From 2a7a47d57d8ba3139958c68f3c16d47abe0e12eb Mon Sep 17 00:00:00 2001 From: Danilo Hoffmann Date: Tue, 8 Mar 2022 00:12:19 +0100 Subject: [PATCH] fix: repair service worker (#1045) --- Dockerfile | 3 --- nginx/templates/multi-channel.conf.tmpl | 2 +- scripts/build-pwa.js | 31 +++++++++++++++++++++++-- server.ts | 14 ++++++++++- src/ssr/server-scripts/server.js | 2 +- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index c331279fed..b9bcd7dcda 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,9 +24,6 @@ RUN if [ ! -z "${activeThemes}" ]; then npm config set intershop-pwa:active-them RUN npm run build:multi client -- --deploy-url=DEPLOY_URL_PLACEHOLDER COPY tsconfig.server.json server.ts /workspace/ RUN npm run build:multi server -# remove cache check for resources (especially index.html) -# https://github.com/angular/angular/issues/23613#issuecomment-415886919 -RUN test "${serviceWorker}" = "true" && sed -i 's/canonicalHash !== cacheBustedHash/false/g' /workspace/dist/browser/ngsw-worker.js || true RUN node scripts/compile-docker-scripts COPY dist/* /workspace/dist/ diff --git a/nginx/templates/multi-channel.conf.tmpl b/nginx/templates/multi-channel.conf.tmpl index 9b1ef081f8..c252d9b521 100644 --- a/nginx/templates/multi-channel.conf.tmpl +++ b/nginx/templates/multi-channel.conf.tmpl @@ -144,7 +144,7 @@ server { } # respect cache entries of static assets - location ~* ^/(ngx_pagespeed_beacon|metrics|assets|.*\.(js|css|ico|json|txt|webmanifest|woff|woff2))(.*)$ { + location ~* ^/(?!ngsw\.json)(ngx_pagespeed_beacon|metrics|assets|.*\.(js|css|ico|json|txt|webmanifest|woff|woff2))(.*)$ { allow all; auth_basic off; diff --git a/scripts/build-pwa.js b/scripts/build-pwa.js index 9a9a68f780..0889c0860e 100644 --- a/scripts/build-pwa.js +++ b/scripts/build-pwa.js @@ -1,7 +1,33 @@ -// https://stackoverflow.com/questions/51388921/pass-command-line-args-to-npm-scripts-in-package-json/51401577 - +const fs = require('fs'); +const path = require('path'); const execSync = require('child_process').execSync; +/** + * remove service worker cache check for resources (especially index.html) + * https://github.com/angular/angular/issues/23613#issuecomment-415886919 + */ +function removeServiceWorkerCacheCheck(args) { + const outputPathArg = args.find(arg => arg.startsWith('--output-path')); + + let outputPath = ''; + if (outputPathArg) { + // get outputPath from build args (in case of build:multi) + outputPath = outputPathArg.split('=')[1]; + } else { + // get default outputPath from angular.json + const angularJson = JSON.parse(fs.readFileSync('./angular.json', { encoding: 'utf-8' })); + outputPath = angularJson.projects[angularJson.defaultProject].architect.build.options.outputPath; + } + + const serviceWorkerScript = path.join(outputPath, 'ngsw-worker.js'); + if (fs.existsSync(serviceWorkerScript)) { + console.warn('replacing cache check for service worker in', serviceWorkerScript); + const script = fs.readFileSync(serviceWorkerScript, { encoding: 'utf-8' }); + fs.writeFileSync(serviceWorkerScript, script.replace('canonicalHash !== cacheBustedHash', 'false')); + } +} + +// https://stackoverflow.com/questions/51388921/pass-command-line-args-to-npm-scripts-in-package-json/64694166#64694166 let configuration = process.env.npm_config_configuration; if (configuration === 'true') { @@ -24,6 +50,7 @@ if (client) { execSync(`npm run ng -- build ${configString} ${remainingArgs.join(' ')}`, { stdio: 'inherit', }); + removeServiceWorkerCacheCheck(remainingArgs); } if (server) { diff --git a/server.ts b/server.ts index 8fa5ef2103..ec70ccd87d 100644 --- a/server.ts +++ b/server.ts @@ -188,7 +188,9 @@ export function app() { // Serve static files from browser folder server.get(/\/.*\.(js|css)$/, (req, res) => { - const path = req.originalUrl.substring(1); + // remove all parameters + const path = req.originalUrl.substring(1).replace(/[;?&].*$/, ''); + fs.readFile(join(BROWSER_FOLDER, path), { encoding: 'utf-8' }, (err, data) => { if (err) { res.sendStatus(404); @@ -198,6 +200,16 @@ export function app() { } }); }); + server.get(/\/ngsw\.json/, (_, res) => { + fs.readFile(join(BROWSER_FOLDER, 'ngsw.json'), { encoding: 'utf-8' }, (err, data) => { + if (err) { + res.sendStatus(404); + } else { + res.set('Content-Type', 'application/json; charset=UTF-8'); + res.send(data); + } + }); + }); server.get( '*.*', express.static(BROWSER_FOLDER, { diff --git a/src/ssr/server-scripts/server.js b/src/ssr/server-scripts/server.js index 12191a8be4..e72a7ecbc5 100644 --- a/src/ssr/server-scripts/server.js +++ b/src/ssr/server-scripts/server.js @@ -12,7 +12,7 @@ app.use((req, res, next) => { if (!match) { match = Object.keys(ports).find(config => { - const p = path.join(process.cwd(), 'dist', config, 'browser', req.path); + const p = path.join(process.cwd(), 'dist', config, 'browser', req.path.substring(1).replace(/[;?&].*$/, '')); return fs.existsSync(p); }); }