I'm trying to get web workers playing nice with Typescript and Webpack's worker-loader. There's an example in their documentation of achieving this through a custom module declaration, however this relies on using the webpack worker-loader!./myWorker syntax.
I want to be able to load workers through a custom *.worker.js webpack use rule rather than explicitly listing the loader in the import string. Something about typescript doesn't seem to like defining or modifying a modules declaration if it's a plain relative import, and gets stuck on the fact that the worker file is not a module, even with a module declaration for it.
I have a worker that looks like
// test.worker.ts
/// <reference lib="webworker" />
const worker: DedicatedWorkerGlobalScope = self as any;
worker.onmessage = ({ data }) => {
if (data instanceof Array) {
worker.postMessage(data.join(' ') + '!');
}
};
A declaration that looks like
// custom.d.ts
declare module '*.worker' {
class TestWorker extends Worker {
constructor();
}
export default TestWorker
}
And is used in my main app as
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',
]);
The error output is
TypeScript error in /worker-test/src/index.tsx(9,24):File '/worker-test/src/test.worker.ts' is not a module. TS2306
Changing the import to worker-loader!./test.worker seems to work and gets typescript to understand the custom declaration, however I'm really trying to avoid using custom loader strings as the intention is to integrate this into create-react-app which doesn't allow these.
Is there a way to get regular relative imports to recognise a custom module declaration?