Web Worker 文件路径失效源于构建工具未识别 new Worker() 中的字符串路径为依赖。Webpack 5 用 new URL('./x.js', import.meta.url) 自动打包;Vite 要求文件带 .js/.ts 后缀且显式 type: 'module';通用方案是 Blob URL 内联。

打包时 Web Worker 文件路径失效,本质是构建工具无法自动识别 new Worker('./xxx.js') 这类字符串路径为资源依赖。直接写相对路径在开发时能跑,但一打包就 404,核心问题不在代码写法,而在构建阶段没把 Worker 脚本纳入产物和路径映射体系。
Webpack 5:用 new URL() 自动识别并打包
Webpack 5 原生支持动态 Worker 路径解析,只需改写创建方式:
- 主线程中不用
new Worker('./worker.js'),而是写成:const worker = new Worker(new URL('./worker.js', import.meta.url)); - Webpack 会自动将该文件作为独立 chunk 打包,并注入正确的运行时路径
- 支持 TypeScript,Worker 内可正常 import 其他模块(需配置
type: 'module') - 无需安装
worker-loader,零额外配置
Vite:默认支持,但要注意后缀和类型
Vite 对模块化 Worker 开箱即用,但有两个硬性要求:
- Worker 文件名必须带
.js或.ts后缀(如calc.worker.ts) - 创建时显式声明
type: 'module':const worker = new Worker(new URL('./calc.worker.ts', import.meta.url), { type: 'module' }); - Worker 脚本内可直接使用
import,Vite 会自动解析、转译、打包依赖 - 若用传统非模块 Worker(含
importScripts),也需确保路径为new URL(...)形式,否则 HMR 和打包均可能失败
通用兜底方案:Blob URL 内联 Worker
当构建工具不兼容或需最大兼容性(如发布为 UMD 库),推荐将 Worker 逻辑转为字符串,通过 Blob 创建:
- 把 Worker 代码写成导出字符串的模块:
export const workerCode = `self.onmessage = () => { self.postMessage('done'); };`; - 主线程中:
const blob = new Blob([workerCode], { type: 'application/javascript' });<br>const url = URL.createObjectURL(blob);<br>const worker = new Worker(url); - 完全脱离文件路径,无拷贝遗漏、无跨域、无 loader 依赖
- 适合轻量逻辑;若含大量第三方库,需手动拼接或预构建为字符串
避免踩坑的关键细节
无论选哪种方式,都要注意:
- Worker 脚本里不能访问
window、document,所有 API 必须是 Worker 环境支持的(如fetch、setTimeout、self) - 路径必须是同源,或跨域脚本响应头带
Access-Control-Allow-Origin - 使用
importScripts时,脚本必须是传统 IIFE/UMD 格式,不能含export/import - 打包后务必检查 dist 目录下是否存在 Worker 文件(或对应 chunk),并验证浏览器 Network 面板中加载是否 200


















