Angular +Workbox = build ChunkLoadError: Loading chunk # and Refused to execute script because its MIME
Angular +Workbox = build ChunkLoadError: Loading chunk # and Refused to execute script because its MIME
我在第一次生产部署中将 Workbox 添加到 Angular 一切正常,但是在更新模块并重建 angular 并注入 Workbox 然后访问站点后,我看到服务工作者更新了新版本并刷新页面,但现在尝试使用更新的模块时出现错误
Refused to execute script from 'https://example.com/8-es2015.203674bf0547eff7ff27.js'
because its MIME type ('text/html') is not executable,
并且启用了严格的 MIME 类型检查。
main-es2015.45ba4a512f87eefb1b3a.js:1 ERROR Error: Uncaught (in promise): ChunkLoadError:
Loading chunk 8 failed.(error: https://example.com/8-es2015.203674bf0547eff7ff27.js)
ChunkLoadError: Loading chunk 8 failed......
我查看了 chrome 中的网络,发现文件 8-es2015.203674bf0547eff7ff27.js 正在从(磁盘缓存)提供服务与 (ServiceWorker) 提供的其他文件不同,它的内容是 index.html 文件我不知道它来自哪里,它甚至不是新构建的一部分? chrome 将其放在脚本下的顶部框架部分
这个错误的原因是什么,在 angular.json 我有 "outputHashing": "all",我删除了所有内容并重建但仍然存在此错误,直到我清除浏览器现金删除 ServiceWorker 并硬刷新错误停止发生,直到我重新加载页面并且它 returns。我是否需要在每次更新后删除所有缓存,我认为 Workbox 会这样做 automatically.Do 我在 sw.js
中添加了类似的内容
self.addEventListener('activate', event => event.waitUntil(
caches.keys().then(cacheNames => cacheNames.forEach(name => caches.delete(name)))
)
);
我正在使用 express,所以我将 sw.js 上的 maxAge 设置为 0,甚至将 public 到静态文件的路由更改为深层路由,但什么都没有
app.use('/sw.js', express.static(path.resolve('./public/dist/static/sw.js'), {maxAge: 0}));
app.use('/', express.static(path.resolve('./public/dist/static/'), {maxAge: 86400000}));
工具:angular 8.2.4 - 工作箱 4.3.1
更新
删除了工作箱并且该应用程序运行正常,我猜测其原因是他们的新包 workbox-window 或我尝试使用它的方式。我将它放在从 app.module 加载的模块服务中,然后从 AppComponent ngOnInit 调用该服务。这可能是错误的初始化方式。
代码设置:
import {Workbox} from 'workbox-window';
@Injectable()
export class WorkerService {
supportWorker: boolean;
supportPush: boolean;
constructor(@Inject(WINDOW) private window: any, private loggerService: LoggerService) {
this.supportWorker = ('serviceWorker' in navigator);
this.supportPush = (this.supportWorker && 'PushManager' in window);
}
initWorker() {
if (this.supportWorker && environment.production) {
const wb = new Workbox('sw.js');
if (wb) {
wb.addEventListener('installed', event => {
if (event.isUpdate) {
// output a toast translated message to users
this.loggerService.info('App.webWorkerUpdate', 10000);
setTimeout(() => this.window.location.reload(), 10000);
}
});
wb.addEventListener('activated', event => {
if (!event.isUpdate) {
this.loggerService.success('App.webWorkerInit', 10000);
}
});
wb.register();
}
}
}
}
这是应用程序组件,我认为最好在 bootstrapModule.then() 之后将其添加到 main.ts,但我不知道如何在此方法中注入服务
@Component({
selector: 'app-root',
template: '<route-handler></route-handler>'
})
export class AppComponent implements OnInit {
constructor(private ws: WorkerService) {
}
ngOnInit(): void {
this.ws.initWorker();
}
}
在以不同的方式设置 Workbox 后,问题甚至影响 chrome,在测试时每次构建后未能清除所有缓存,不得不使用隐身模式以确保一切正常。
这里是解决方案,感谢 Ralph Schaer 一篇必读的文章。他的方法不是缓存-Bust angular 构建生成的块,他还将应用程序使用的工作箱的所有生产脚本放入构建文件夹中,最后在 index.html 他调用工作箱- window 注册 service-worker。
我在第一次生产部署中将 Workbox 添加到 Angular 一切正常,但是在更新模块并重建 angular 并注入 Workbox 然后访问站点后,我看到服务工作者更新了新版本并刷新页面,但现在尝试使用更新的模块时出现错误
Refused to execute script from 'https://example.com/8-es2015.203674bf0547eff7ff27.js'
because its MIME type ('text/html') is not executable,
并且启用了严格的 MIME 类型检查。
main-es2015.45ba4a512f87eefb1b3a.js:1 ERROR Error: Uncaught (in promise): ChunkLoadError:
Loading chunk 8 failed.(error: https://example.com/8-es2015.203674bf0547eff7ff27.js)
ChunkLoadError: Loading chunk 8 failed......
我查看了 chrome 中的网络,发现文件 8-es2015.203674bf0547eff7ff27.js 正在从(磁盘缓存)提供服务与 (ServiceWorker) 提供的其他文件不同,它的内容是 index.html 文件我不知道它来自哪里,它甚至不是新构建的一部分? chrome 将其放在脚本下的顶部框架部分
这个错误的原因是什么,在 angular.json 我有 "outputHashing": "all",我删除了所有内容并重建但仍然存在此错误,直到我清除浏览器现金删除 ServiceWorker 并硬刷新错误停止发生,直到我重新加载页面并且它 returns。我是否需要在每次更新后删除所有缓存,我认为 Workbox 会这样做 automatically.Do 我在 sw.js
中添加了类似的内容self.addEventListener('activate', event => event.waitUntil(
caches.keys().then(cacheNames => cacheNames.forEach(name => caches.delete(name)))
)
);
我正在使用 express,所以我将 sw.js 上的 maxAge 设置为 0,甚至将 public 到静态文件的路由更改为深层路由,但什么都没有
app.use('/sw.js', express.static(path.resolve('./public/dist/static/sw.js'), {maxAge: 0}));
app.use('/', express.static(path.resolve('./public/dist/static/'), {maxAge: 86400000}));
工具:angular 8.2.4 - 工作箱 4.3.1
更新 删除了工作箱并且该应用程序运行正常,我猜测其原因是他们的新包 workbox-window 或我尝试使用它的方式。我将它放在从 app.module 加载的模块服务中,然后从 AppComponent ngOnInit 调用该服务。这可能是错误的初始化方式。
代码设置:
import {Workbox} from 'workbox-window';
@Injectable()
export class WorkerService {
supportWorker: boolean;
supportPush: boolean;
constructor(@Inject(WINDOW) private window: any, private loggerService: LoggerService) {
this.supportWorker = ('serviceWorker' in navigator);
this.supportPush = (this.supportWorker && 'PushManager' in window);
}
initWorker() {
if (this.supportWorker && environment.production) {
const wb = new Workbox('sw.js');
if (wb) {
wb.addEventListener('installed', event => {
if (event.isUpdate) {
// output a toast translated message to users
this.loggerService.info('App.webWorkerUpdate', 10000);
setTimeout(() => this.window.location.reload(), 10000);
}
});
wb.addEventListener('activated', event => {
if (!event.isUpdate) {
this.loggerService.success('App.webWorkerInit', 10000);
}
});
wb.register();
}
}
}
}
这是应用程序组件,我认为最好在 bootstrapModule.then() 之后将其添加到 main.ts,但我不知道如何在此方法中注入服务
@Component({
selector: 'app-root',
template: '<route-handler></route-handler>'
})
export class AppComponent implements OnInit {
constructor(private ws: WorkerService) {
}
ngOnInit(): void {
this.ws.initWorker();
}
}
在以不同的方式设置 Workbox 后,问题甚至影响 chrome,在测试时每次构建后未能清除所有缓存,不得不使用隐身模式以确保一切正常。
这里是解决方案,感谢 Ralph Schaer 一篇必读的文章。他的方法不是缓存-Bust angular 构建生成的块,他还将应用程序使用的工作箱的所有生产脚本放入构建文件夹中,最后在 index.html 他调用工作箱- window 注册 service-worker。