I have a project written on Typescript and bundeled using webpack5. I try to use web-workers to off-load some of the code from the min thread.
main.worker.ts:
import { expose } from 'comlink';
import {TimeConsumingFunction} from "./TimeConsumingFunction"
const exports = {
TimeConsumingFunction
};
export type WorkerInterfaceTimeConsumingFunction = typeof exports;
export default null as any;
expose(exports);
main.ts:
import { wrap } from 'comlink';
import {WorkerInterfaceTimeConsumingFunction, default as DataPixelsWorker} from './main.worker';
const worker = new Worker(new URL("./main.worker", import.meta.url));
const workerApi = wrap(worker);
let result = await workerApi.TimeConsumingFunction();
tsconfig:
{
"compilerOptions": {
"target": "es3",
"module": "esnext",
"lib": ["webworker", "es2018", "dom"],
"allowJs": true,
"checkJs": false,
"sourceMap": true,
"removeComments": false,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"esModuleInterop": true
},
"include": [
"./**/*"
],
"exclude": [
"./plugins/**/*",
"./typings/**/*",
"./dev/**/*",
"./dist/**/*"
]
}
webpack.js:
const path = require('path');
module.exports = [
{
entry: './main.ts',
mode: 'production',
target: ['web', 'es5'],
module:
{
rules:
[
{
test: /\.worker\.(js|ts)$/,
use: { loader: 'worker-loader' }
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve:
{
extensions: [ '.tsx', '.ts', '.js' ]
},
output:
{
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
optimization:
{
minimize: true,
},
stats:
{
colors: true
}
}
];
Package.json:
{
"name": "Project",
"sideEffects": false,
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --progress --config=./webpack.js --mode production --output-path ./dist/."
},
"devDependencies": {
"@babel/core": "^7.14.6",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-decorators": "^7.14.5",
"@babel/plugin-transform-runtime": "^7.14.5",
"@babel/preset-env": "^7.14.5",
"@babel/preset-typescript": "^7.14.5",
"babel-loader": "^8.2.2",
"ts-loader": "^4.5.0",
"typescript": "^4.2.4",
"webpack": "^5.36.0",
"webpack-cli": "^4.6.0",
"webpack-version-file-plugin": "^0.4.0",
"worker-loader": "^3.0.8"
},
"dependencies": {
"@babel/runtime": "^7.14.6",
"comlink": "^4.3.1",
"core-js": "^3.11.2"
},
"keywords": [],
"author": "",
"license": "ISC"
}
When the project is transpiled using the command npm run build the output contains 2 files:
- main.js
- main.worker.js
The output files are uploaded to a CDN. The files will be loaded from the URL https://www.example.com/main.js.
The content is loaded from the URL https://www.example-content.com
The content contains the following script tag <script src='https://www.example.com/main.js'></script>
When the content is loaded, the following error appears on the browser's console:
main.js?x=1111:1 Uncaught (in promise) DOMException: Failed to construct 'Worker': Script at 'https://www.example.com/main.worker.js'
cannot be accessed from origin 'https://www.example-content.com'.
at e.<anonymous> (https://www.example.com/main.js?x=1111:1:313839)
Because the script is loaded from a CDN that is accessible through a different domain than the content that loads the script I think the best way is to bundle the files main.worker.js into main.js. Is there a way doing that with webpack 5? Is there another way to overcome this problem?