I'm using a TypeScript project based on SystemJS, following this example whose code is at https://github.com/tekmi/blogging-typescript-with-bundlers/blob/master/systemjs/app.ts
I'm able to implement a simple Worker in TypeScript, e.g. from this example,
// src/worker/simulator.ts
const scope = (self as unknown) as Worker
scope.addEventListener('message', event => {
console.log(event.data)
scope.postMessage('pong')
})
It runs fine in the SystemJS environment - I make sure that its code is transpiled outside of SystemJS, with a separate tsconfig.json
, following the advice at this blog.
But as soon as I try something more complex in the Worker code, i.e., a class that imports/exports something, I hit snags with the code that runs. Depending on the transpiled format ("module"
in the tsconfig), I get the following problems:
"module": "ESNext"
-> SyntaxError: Cannot use import statement outside a module
"module": "CommonJS"
-> ReferenceError: exports is not defined
The transpiled code is loaded properly when invoked (I see it fine in the log for lite-server
).
I invoke the worker inside the event code for a button on a web page:
export function start(this: GlobalEventHandlers, ev: MouseEvent) {
let worker = new Worker("../worker/simulator.js");
//...
My conclusion is there's some context missing in the transpiled worker code, but I can't figure out what it is. It's the first time I'm trying Workers in TypeScript.
Here's my tsconfig.json
for the src/worker
sub-project (this one is configured for CommonJS module transpilation):
{
"extends": "../generic-tsconfig.json",
"compilerOptions": {
"strict": true,
"target": "ES6",
"module": "CommonJS",
// store the webworker transpiled files separately
"outDir": "../../dist",
"lib": [
"ES6",
"WebWorker"
],
},
"include": [
"../worker/*",
"../shared/*"
]
}
What is needed to allow a (complex) Worker to run in this configuration?
I want avoid Webpack if possible, mostly because I'm trying to understand what's happening.
As mentioned in the comments, if you want to be able to use module syntax like import
and export
in a web worker, you need to define the worker with the type: module
option, like this:
new Worker("worker.js", { type: "module" });
This is discussed further in the question Web Workers - How To Import Modules