Angular集成Workbox遇Service Worker注册404错误求助
Hey,你这明显是踩了Angular构建流程和Workbox集成的常见坑——核心问题要么是生成的sw.js没在正确的部署目录,要么是注册路径不对,还有可能是构建顺序搞反了。我帮你一步步排查:
1. 先把Workbox配置和Angular的构建目录对齐
Angular默认把构建产物打包到dist/[你的项目名](比如dist/my-app),你之前把swDest指向src/肯定不行——src/是源码目录,Angular部署时只会用dist里的文件,根本不会管src里的sw.js。
给你个正确的workbox-cli-config.js示例:
module.exports = { globDirectory: 'dist/my-app/', // 必须指向Angular构建好的产物目录 globPatterns: [ '**/*.{html,css,js,png,jpg,svg}' // 按需调整要缓存的文件类型 ], swDest: 'dist/my-app/sw.js', // 把sw.js直接生成到dist产物目录里 // 其他默认配置保留即可 };
2. 调整构建脚本的执行顺序
你得确保先跑Angular构建,再执行Workbox生成sw.js——不然Workbox扫描的是旧文件或者空目录,生成的sw.js还可能被Angular的构建命令清空掉。
修改package.json里的脚本:
{ "scripts": { "build": "ng build && npm run generate-sw", "generate-sw": "workbox generateSW workbox-cli-config.js" } }
之后别单独跑ng build或者generate-sw,直接执行npm run build,让它按顺序完成。
3. 修正Service Worker的注册路径
你之前注册的是'src/sw.js',这完全错误——部署时src/目录根本不存在,浏览器只会去dist目录找资源。注册路径要相对于应用的根URL:
如果你的应用部署在域名根路径(比如https://your-app.com/),修改index.html里的注册脚本:
<script> if ('serviceWorker' in navigator && 'PushManager' in window) { navigator.serviceWorker.register('/sw.js') // 改成根路径的sw.js .then(function(swReg) { console.log('Service Worker is registered', swReg); }) .catch(function(error) { console.error('Service Worker Error', error); }); } else { console.warn('Push messaging is not supported'); } </script>
如果部署在子路径(比如https://your-app.com/my-app/),就改成'/my-app/sw.js',或者用相对路径'./sw.js'(注意当前页面的URL层级要匹配)。
4. 确保Angular不会漏掉sw.js
只要sw.js生成在dist目录里,Angular默认会把它当成部署资产,但如果你的angular.json里自定义了assets规则,要确保sw.js被包含:
// angular.json -> projects -> [你的项目名] -> architect -> build -> options "assets": [ "src/favicon.ico", "src/assets", "sw.js" // 直接加这个,因为它在dist根目录 ]
一般来说这一步不需要,但如果你的配置比较严格,就得加上。
5. 排查Angular自带SW的冲突
如果你之前装过@angular/service-worker,它会自动生成ngsw-worker.js,这时候两个SW会冲突,甚至Angular的构建会覆盖你的sw.js。如果不需要Angular自带的SW,直接卸载:
npm uninstall @angular/service-worker
然后在app.module.ts里删掉ServiceWorkerModule的导入,angular.json里把serviceWorker: true的配置去掉。
最后测试一下
- 执行
npm run build,去dist/my-app目录下看看有没有sw.js文件。 - 用
npx serve dist/my-app启动本地服务器(别直接打开index.html,file://协议不支持SW)。 - 打开浏览器控制台,看Network标签里sw.js的请求路径对不对,有没有返回200。
如果还是有问题,看看Workbox生成时的日志,有没有报错说找不到要扫描的文件——那就是globDirectory配置错了。
内容的提问来源于stack exchange,提问作者StudentRik

