Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add require/exports to worker scope #23

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

lmexo
Copy link

@lmexo lmexo commented Mar 9, 2023

About the context

Vite provides a very convinient way to import workers. But I cannot use it, since jest does not support it. The beauty of Vite's workers is, it basically bundles the worker to its own file, which allows me to split my worker into multiple files and can happily do imports :)

Okay. After doing some configuration, I was able to emulate vites behavior in Jest, except the "multi-file"-thing. But since this lib does not run a real worker but just emulates it in the jsdom environment, we can make of jests imports. In order to get everything running, I required the following config:

// jest.config.json
module.exports = {
  transform: {
    '^.+\\.worker\\.(js|jsx|mjs|cjs|ts|tsx)$': '<rootDir>/jest/viteWorkerTransform.js',
    '^.+\\.(js|jsx|mjs|cjs|ts|tsx)$': '<rootDir>/jest/swcTransform.js',
  }
}
// jest/viteWorkerTransform.js
const { resolve, dirname } = require('path');

// this is the transformer for all source files using SWC
const swcTransform = require('./swcTransform');

module.exports = {
  process(sourceText, sourcePath, options) {
    let { code: bundle } = swcTransform.process(sourceText, sourcePath, options);
    bundle = bundle.replaceAll(/(?<![_\w])require\("[^"]+"\)/g, (str) => {
      const m = str.match(/require\("([^"]+)"\)/);
      return `require("${resolve(dirname(sourcePath), m[1])}")`;
    });
    const workerB64 = Buffer.from(bundle).toString('base64');
    const code = `
      var url = URL.createObjectURL(new Blob([Buffer.from('${workerB64}', 'base64')], { type: 'text/javascript' }));
      module.exports = function() {
        var worker = new Worker(url);
        worker.addEventListener('error', function(e) {
          console.log(e);
        });
        return worker;
      }
    `;

    return { code };
  },
};

Now I am able to import my worker within my spec's as import Worker from 'background.worker.ts?worker'. Alrighty, so far so good, as long I do not import/require anything (in my configuration all imports became requires after swcTransform.process).

Solution

Everything I needed was the require/exports members in my worker scope. Having this allows me to emulate vite worker imports using jest working perfectly fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant