Cache problem during deployment to production with service workers
See original GitHub issueš bug report
Description
We have 2 problems:
We have an angular app with service workers. We deployed it months ago without any problem running ng build --configuration=production. We have IIS 10 (below I added itās configuration). Now, every time we need to do an update, we delete all deployed files and we copy new ones in site root. After this operation we start getting problems. Site doesnāt load, we get black page with some errors (errors are described below) This happens only in production environment. We have another server where we deploy app for testing before deploy to production, and here we have no problem. The difference between two environments is only the presence of a CDN in production one. After every deploy in production we also invalidate entire CDN cache.
This problem occurs in production but also on developer server where we donāt have CDN. When we deploy an update (deleting all files in site root and then copying there new ones, we expect new version is loaded when user open site. Service workers should understand a new version has been deployed comparing its version with the new one through ngsw.json file, and finally āinstallā the correct version. This happens only if a user delete browser cache or if user do a ctrl + f5. This doesnāt happens with a simple page refresh. And this happens on every browser.
š„ Exception or Error
Error for problem 1:
Refused to execute script from https://mysite/1.5960f4f...js/ because its MIME type (text/html/ is not executable, and strict MIME type checking is enabled
and same error on other js files that are other modules files.
Error screenshot
š Your Environment
Angular Version:
Angular CLI: 7.3.9
Node: 10.16.0
OS: win32 x64
Angular: 7.2.15
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
... service-worker
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.13.9
@angular-devkit/build-angular 0.13.9
@angular-devkit/build-optimizer 0.13.9
@angular-devkit/build-webpack 0.13.9
@angular-devkit/core 7.3.9
@angular-devkit/schematics 7.3.9
@angular/cdk 7.3.7
@angular/cli 7.3.9
@angular/material 7.3.7
@angular/pwa 0.8.7
@ngtools/webpack 7.3.9
@schematics/angular 0.8.7
@schematics/update 0.13.9
rxjs 6.3.3
typescript 3.1.6
webpack 4.29.0
Anything else relevant?
The site is under AWS CDN (CloudFront) CDN rules cache every image, js and css
Our ngsw-config.json:
{
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/*.css",
"/*.js",
"/*.(woff2)"
]
}
}, {
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**",
"/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|ani)"
]
}
}
]
}
Our index.html:
<!doctype html>
<html lang="it">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<style>
.async-hide {
opacity: 0 !important
}
</style>
<script>(function (a, s, y, n, c, h, i, d, e) {
s.className += ' ' + y; h.start = 1 * new Date;
h.end = i = function () { s.className = s.className.replace(RegExp(' ?' + y), '') };
(a[n] = a[n] || []).hide = h; setTimeout(function () { i(); h.end = null }, c); h.timeout = c;
})(window, document.documentElement, 'async-hide', 'dataLayer', 4000,
{ 'XXXXXXX': true });</script>
<meta charset="utf-8">
<title>Title</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<link rel="icon" type="image/x-icon" href="favicon.ico">
<meta name="theme-color" content="#1976d2">
</head>
<body class="body">
<app-root></app-root>
</body>
</html>
<script>
if (global === undefined) {
var global = window;
}
if (System === undefined) {
var System = window;
}
</script>
We deploy app under IIS
These are some relevant parts of web.config:
<httpProtocol>
<customHeaders>
<remove name="X-Content-Type-Options" />
<add name="X-Content-Type-Options" value="nosniff" />
<remove name="X-Powered-By" />
<remove name="Vary" />
<add name="Vary" value="Accept-Encoding,User-Agent" />
</customHeaders>
</httpProtocol>
...
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
<scheme dll="%Windir%\system32\inetsrv\gzip.dll" name="gzip" staticCompressionLevel="9" />
<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/javascript" enabled="true" />
<add mimeType="application/json" enabled="true" />
<add mimeType="*/*" enabled="false" />
</dynamicTypes>
<staticTypes>
<add enabled="true" mimeType="text/*" />
<add enabled="true" mimeType="message/*" />
<add enabled="true" mimeType="application/javascript" />
<add enabled="true" mimeType="application/json" />
<add enabled="false" mimeType="*/*" />
</staticTypes>
</httpCompression>
...
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
...
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" cacheControlCustom="public" />
<remove fileExtension=".html" />
<mimeMap fileExtension=".html" mimeType="text/html; charset=UTF-8" />
<remove fileExtension=".css" />
<mimeMap fileExtension=".css" mimeType="text/css" />
<remove fileExtension=".js" />
<mimeMap fileExtension=".js" mimeType="text/javascript" />
<remove fileExtension=".png" />
<mimeMap fileExtension=".png" mimeType="image/png" />
<remove fileExtension=".jpg" />
<mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
<remove fileExtension=".json" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<remove fileExtension=".rss" />
<mimeMap fileExtension=".rss" mimeType="application/rss+xml; charset=UTF-8" />
<remove fileExtension=".xml" />
<mimeMap fileExtension=".xml" mimeType="application/xml; charset=UTF-8" />
<!-- HTML5 Audio/Video mime types-->
<remove fileExtension=".mp3" />
<mimeMap fileExtension=".mp3" mimeType="audio/mpeg" />
<remove fileExtension=".mp4" />
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
<remove fileExtension=".ogg" />
<mimeMap fileExtension=".ogg" mimeType="audio/ogg" />
<remove fileExtension=".ogv" />
<mimeMap fileExtension=".ogv" mimeType="video/ogg" />
<remove fileExtension=".webm" />
<mimeMap fileExtension=".webm" mimeType="video/webm" />
<!-- Proper svg serving. Required for svg webfonts on iPad -->
<remove fileExtension=".svg" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<remove fileExtension=".svgz" />
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml" />
<!-- HTML4 Web font mime types -->
<!-- Remove default IIS mime type for .eot which is application/octet-stream -->
<remove fileExtension=".eot" />
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
<remove fileExtension=".ttf" />
<mimeMap fileExtension=".ttf" mimeType="application/x-font-ttf" />
<remove fileExtension=".ttc" />
<mimeMap fileExtension=".ttc" mimeType="application/x-font-ttf" />
<remove fileExtension=".otf" />
<mimeMap fileExtension=".otf" mimeType="font/opentype" />
<remove fileExtension=".woff" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".woff2" mimeType="font/woff2" />
<remove fileExtension=".crx" />
<mimeMap fileExtension=".crx" mimeType="application/x-chrome-extension" />
<remove fileExtension=".xpi" />
<mimeMap fileExtension=".xpi" mimeType="application/x-xpinstall" />
<remove fileExtension=".safariextz" />
<mimeMap fileExtension=".safariextz" mimeType="application/octet-stream" />
<!-- Flash Video mime types-->
<remove fileExtension=".flv" />
<mimeMap fileExtension=".flv" mimeType="video/x-flv" />
<remove fileExtension=".f4v" />
<mimeMap fileExtension=".f4v" mimeType="video/mp4" />
<!-- Assorted types -->
<remove fileExtension=".ico" />
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
<remove fileExtension=".webp" />
<mimeMap fileExtension=".webp" mimeType="image/webp" />
<remove fileExtension=".htc" />
<mimeMap fileExtension=".htc" mimeType="text/x-component" />
<remove fileExtension=".vcf" />
<mimeMap fileExtension=".vcf" mimeType="text/x-vcard" />
<remove fileExtension=".torrent" />
<mimeMap fileExtension=".torrent" mimeType="application/x-bittorrent" />
<remove fileExtension=".cur" />
<mimeMap fileExtension=".cur" mimeType="image/x-icon" />
<remove fileExtension=".webapp" />
<mimeMap fileExtension=".webapp" mimeType="application/x-web-app-manifest+json; charset=UTF-8" />
</staticContent>
...
<location path="index.html">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" cacheControlMaxAge="0.00:00:00" />
</staticContent>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache, no-store, must-revalidate" />
<add name="Pragma" value="no-cache" />
<add name="Expires" value="-1" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
Our package.json:
{
"name": "xxx",
"version": "0.0.0",
"scripts": {
"ng": "node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng",
"start": "npm run ng -- serve",
"build": "npm run ng -- build",
"test": "npm run ng -- test",
"lint": "npm run ng -- lint",
"e2e": "npm run ng -- e2e",
"analyze": "webpack-bundle-analyzer dist/stats.json",
"compodoc": "npx compodoc -p src/tsconfig.app.json",
"build:stats": "ng build --stats-json"
},
"private": true,
"dependencies": {
"@agm/core": "1.0.0-beta.7",
"@agm/js-marker-clusterer": "1.0.0-beta.3",
"@angular/animations": "7.2.15",
"@angular/cdk": "7.3.7",
"@angular/common": "7.2.15",
"@angular/compiler": "7.2.15",
"@angular/core": "7.2.15",
"@angular/forms": "7.2.15",
"@angular/http": "7.2.15",
"@angular/material": "7.3.7",
"@angular/platform-browser": "7.2.15",
"@angular/platform-browser-dynamic": "7.2.15",
"@angular/platform-server": "7.2.15",
"@angular/pwa": "0.8.7",
"@angular/router": "7.2.15",
"@angular/service-worker": "7.2.15",
"@satispay/web-button-factory": "1.4.3",
"angular4-social-login": "1.1.1",
"braintree-web": "3.52.1",
"braintree-web-drop-in": "1.20.1",
"classlist.js": "1.1.20150312",
"codice-fiscale-js": "2.1.0",
"core-js": "2.5.4",
"domino": "2.1.3",
"express": "4.17.1",
"font-awesome": "4.7.0",
"hammerjs": "2.0.8",
"js-marker-clusterer": "1.0.0",
"lory.js": "2.3.3",
"md5": "2.2.1",
"moment-mini-ts": "2.20.1",
"ng-lazyload-image": "5.1.2",
"ng2-cookies": "1.0.12",
"ngx-gallery": "4.1.2",
"ngx-json-ld": "0.3.1",
"ngx-loadable": "1.0.10",
"ngx-responsive": "6.0.0",
"ngx-swiper-wrapper": "4.9.0",
"paypal-checkout": "4.0.285",
"rxjs": "~6.3.3",
"tslib": "1.9.0",
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "0.13.9",
"@angular/cli": "7.3.9",
"@angular/compiler-cli": "7.2.15",
"@angular/language-service": "7.2.15",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.1.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "0.2.2",
"node-ts": "5.0.1",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "3.1.6",
"webpack-bundle-analyzer": "3.3.2"
}
}
I suppose problem 1 is related to CDN, but I donāt understand why. It seems that somewhere (I think on userās browsers, in service workers) something continue to have reference to old files (the ones we delete before copying there new app version). And this problem seems to be related to problem number 2, where it seems new version is not loaded the first time user access it.
Maybe we are doing something wrong, or we have an incorrect configuration, but we canāt find it.
Thanks for help
Issue Analytics
- State:
- Created 4 years ago
- Comments:11 (1 by maintainers)

Top Related StackOverflow Question
Firebase hosting has a 1 hour default caching policy. If you donāt specifically specify that you do not want caching on the service worker files, youāll get this 1 hour cache.
What you do is that in your firebase.json you insert the following in the
headerssection:This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.