web worker 中使用 es modules 需显式指定 { type: 'module' },路径须为同源 url,脚本需符合 esm 规范,支持顶层 await;构建工具需适配模块路径,通信仍依赖 postmessage()。

在 Web Worker 中使用 ES Modules 是现代浏览器和 Node.js 环境支持的标准能力,但需满足特定条件并正确配置。核心在于显式声明 type: 'module',且路径、加载方式和通信逻辑要匹配模块语义。
必须指定 type: 'module' 选项
创建 Worker 时不能依赖默认行为,classic 类型不支持 import 语法。必须传入 { type: 'module' } 配置:
-
new Worker('./worker.js', { type: 'module' })—— 浏览器中直接加载本地模块文件 - 路径必须是同源的绝对或相对 URL(如
new URL('./worker.js', import.meta.url)),不能是内联字符串或非模块化脚本 - Node.js 12.8+ 同样支持该选项,配合
web-worker库可实现跨平台一致行为
Worker 脚本内部用标准 import/export
worker.js 文件本身要符合 ES Module 规范:
- 可直接
import { helper } from './utils.js'或import _ from 'lodash-es'(需打包工具支持裸模块解析) - 不能使用
require()或global;self仍是全局对象,但window、document不可用 - 顶层 await 可用(Chrome 89+、Firefox 86+、Safari 16.4+),适合动态导入或初始化异步资源
注意模块路径与构建工具适配
在工程化项目中(如 Vite、Webpack、Next.js),直接写 new Worker('./xxx.js') 可能失败:
- Vite 开发模式下支持原生 ESM,
new Worker(new URL('./worker.js', import.meta.url), { type: 'module' })可直接工作 - Vue CLI 或 Webpack 需引入
worker-loader并配置.worker.js后缀,同时确保 loader 输出为模块类型 - 打包后路径可能被重写,建议用
new URL()构造动态 URL,避免硬编码路径失效
主线程与 Worker 的模块通信不变
ES Modules 不改变消息机制,仍靠 postMessage() 和事件监听:
- 主线程发送:
worker.postMessage({ cmd: 'process', data: arrayBuffer }) - Worker 接收:
self.addEventListener('message', e => { ... }) - 返回结果:
self.postMessage(result),数据自动序列化,大对象可配合transfer参数零拷贝传递











