Add require/exports to worker scope
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.