Web Worker启动失败主因是路径解析错误:浏览器以HTML页面URL为基准拼接Worker路径,而非JS文件位置;需通过worker-loader的publicPath配置或new URL('./x.js', import.meta.url)动态获取正确路径。

Web Worker 启动失败,八成不是代码写错了,而是脚本路径在打包后“找不着家”——根本原因在于构建工具对 new Worker() 中路径的解析逻辑,和你想象的完全不一样。
路径解析规则:它不看文件位置,只看页面 URL
很多人以为 new Worker('./workers/processor.js') 是相对于当前 JS 文件所在目录,其实不是。浏览器会以当前 HTML 页面的完整 URL 为基准来拼接路径。
- 如果页面地址是
https://site.com/app/dashboard.html,那它实际请求的是https://site.com/app/workers/processor.js - 哪怕 Worker 文件物理上在
src/workers/,打包后被挪到/assets/workers/,只要没配对加载路径,就 404 - 用
../或./猜路径,在开发环境可能碰巧能跑,上线必崩
Webpack 下 worker-loader 的 publicPath 是关键开关
worker-loader 不读你 import 的路径,也不读文件结构,它只认自己配置的 publicPath —— 这个值决定了最终发起网络请求的 URL 前缀。
- 显式写死(适合静态部署):
publicPath: '/assets/workers/'→ 所有 Worker 都从该前缀下加载 - 动态返回(推荐多环境):
publicPath: () => process.env.NODE_ENV === 'production' ? 'https://cdn.example.com/workers/' : '/dev-workers/' - 不配?它会 fallback 到 Webpack 的
output.publicPath,而这个值若设为'./'或空字符串,极易导致相对页面路径出错
绕过路径问题的实用方案:内联模式
如果 Worker 逻辑简单(比如数据压缩、格式校验),且不依赖外部模块,直接打包进主 bundle 最省心。
-
inline: 'no-fallback':Worker 代码转成 Blob URL,零额外请求,彻底摆脱路径困扰 -
inline: 'fallback':同时生成独立文件 + 内联代码,老浏览器自动降级 - 配置示例:
{ test: /\.worker\.js$/, use: { loader: 'worker-loader', options: { inline: 'no-fallback' } } }
Vue/Vite 等现代框架中的安全引用法
借助构建时注入的元信息,让路径随打包结果自动适配:
- Vue CLI / Vite 中可写:
new Worker(new URL('./my.worker.js', import.meta.url)) - Webpack 5+ 支持
import.meta.webpackHot,配合__webpack_public_path__动态修正 - 避免硬编码路径,也别依赖
process.env.BASE_URL,它不参与 Worker 加载路径计算











