I've been trying to implement web workers with Typescript and Webpack's worker-loader smoothly. The documentation shows an example of achieving this using a custom module declaration, but it requires the webpack syntax worker-loader!./myWorker
.
My goal is to load workers through a custom webpack *.worker.js
rule without explicitly specifying the loader in the import string. However, TypeScript seems to have issues defining or modifying a module declaration with plain relative imports, as it struggles to recognize the worker file as a module even with a proper declaration.
The worker code looks like this:
// test.worker.ts
/// <reference lib="webworker" />
const worker: DedicatedWorkerGlobalScope = self as any;
worker.onmessage = ({ data }) => {
if (data instanceof Array) {
worker.postMessage(data.join(' ') + '!');
}
};
The declaration I created is:
// custom.d.ts
declare module '*.worker' {
class TestWorker extends Worker {
constructor();
}
export default TestWorker
}
And I use it in my main app like this:
import TestWorker from './test.worker';
const testWorker = new TestWorker();
testWorker.onmessage = ({ data }: { data: string }) => {
console.log(data);
};
testWorker.postMessage([
'hello',
'I',
'am',
'a',
'web',
'worker',
]);
However, I get the following error:
TypeScript error in /worker-test/src/index.tsx(9,24):File '/worker-test/src/test.worker.ts' is not a module. TS2306
Using worker-loader!./test.worker
in the import statement solves the issue and helps TypeScript understand the custom declaration. But my aim is to avoid using custom loader strings, especially since I plan to integrate this into create-react-app where they are not allowed.
So, I'm wondering if there is a way to make regular relative imports work with a custom module declaration?