Web Workers
Web Workers
从 webpack 5 开始,你可以无需使用 worker-loader 即可使用 Web Workers。
语法
js
new Worker(new URL("./worker.js", import.meta.url));
js
// or customize the chunk name with magic comments
// see https://webpack.js.org/api/module-methods/#magic-comments
new Worker(
/* webpackChunkName: "foo-worker" */ new URL("./worker.js", import.meta.url),
);
选择该语法是为了允许在没有打包器的情况下运行代码,它在浏览器原生 ECMAScript 模块中同样可用。
注意,虽然 Worker API 表明 Worker 构造函数接受表示脚本 URL 的字符串,但在 webpack 5 中你只能使用 URL。
版本要求:5.105.0+
当使用 new Worker() 时,webpack 可以通过包 exports 字段中定义的导出条件名来解析 worker 模块。这允许包自动提供 worker 特定版本的模块。
package.json(位于依赖包中):
json
{
"name": "my-package",
"exports": {
".": {
"worker": "./index.worker.js",
"default": "./index.js"
}
}
}
当你在 worker 上下文中引入这个包时:
js
// Inside a worker file
import { someFunction } from "my-package";
当模块在 worker 上下文中被使用时,webpack 会自动解析到 index.worker.js,无需任何额外配置。
警告: webpack 不支持在
Worker构造函数中使用变量。例如,以下代码将无法工作:const url = new URL('./path/to/worker.ts', import.meta.url); const worker = new Worker(url);。这是因为 webpack 无法静态地分析该语法。在 webpack 中使用Worker语法时,务必了解这一限制。
示例
src/index.js
js
const worker = new Worker(new URL("./deep-thought.js", import.meta.url));
worker.postMessage({
question:
"The Answer to the Ultimate Question of Life, The Universe, and Everything.",
});
worker.onmessage = ({ data: { answer } }) => {
console.log(answer);
};
src/deep-thought.js
js
globalThis.onmessage = ({ data: { question } }) => {
self.postMessage({
answer: 42,
});
};
从变量设置 public path
当你从变量设置 __webpack_public_path__,且 publicPath 等于 auto 时,worker chunk 将获得独立的运行时,webpack 运行时会自动计算并设置 publicPath,但这很可能并非你期望的结果。
要解决此问题,你需要在 worker 代码内设置 __webpack_public_path__。示例如下:
worker.js
js
globalThis.onmessage = ({ data: { publicPath, ...otherData } }) => {
if (publicPath) {
__webpack_public_path__ = publicPath;
}
// rest of the worker code
};
app.js
js
const worker = new Worker(new URL("./worker.js", import.meta.url));
worker.postMessage({ publicPath: globalThis.__MY_GLOBAL_PUBLIC_PATH_VAR__ });
何时使用:
仅当 worker 需要加载额外的 chunk 且资源基础 URL 在运行时确定时(例如,使用 CDN 或多域名部署),才需要使用此模式。
由于 worker 运行在隔离的全局作用域中,自动检测到的 public path 可能与主线程使用的路径不同。在这种情况下,必须显式地将 public path(__webpack_public_path__)传递给 worker,并在 worker 运行时内部进行设置。
注意:这是一个高级用例。如果你的 worker 不加载额外的 chunk,或者你的资源来自静态的同源路径,通常无需手动设置
__webpack_public_path__。
Node.js
本节介绍如何通过 worker_threads 模块在 Node.js 环境中使用 Web Workers。
Node.js(>= 12.17.0)也支持类似的语法:
js
import { Worker } from "node:worker_threads";
new Worker(new URL("./worker.js", import.meta.url));
注意,这仅在 ESM 中可用。webpack 和 Node.js 都不支持 CommonJS 语法中的 Worker。
帮助我们改进文档
发现翻译问题或内容错误?请告诉我们。
