diff --git a/src/frontend/apps/impress/next.config.js b/src/frontend/apps/impress/next.config.js index a093d3e9..41dbb881 100644 --- a/src/frontend/apps/impress/next.config.js +++ b/src/frontend/apps/impress/next.config.js @@ -1,5 +1,9 @@ +const crypto = require('crypto'); + const { InjectManifest } = require('workbox-webpack-plugin'); +const buildId = crypto.randomBytes(256).toString('hex').slice(0, 8); + /** @type {import('next').NextConfig} */ const nextConfig = { output: 'export', @@ -11,6 +15,10 @@ const nextConfig = { // Enables the styled-components SWC transform styledComponents: true, }, + generateBuildId: () => buildId, + env: { + NEXT_PUBLIC_BUILD_ID: buildId, + }, webpack(config, { isServer }) { // Grab the existing rule that handles SVG imports const fileLoaderRule = config.module.rules.find((rule) => diff --git a/src/frontend/apps/impress/src/core/service-worker/__tests__/_app.test.tsx b/src/frontend/apps/impress/src/core/service-worker/__tests__/_app.test.tsx index 3e83e24e..91017b3d 100644 --- a/src/frontend/apps/impress/src/core/service-worker/__tests__/_app.test.tsx +++ b/src/frontend/apps/impress/src/core/service-worker/__tests__/_app.test.tsx @@ -22,6 +22,7 @@ jest.mock('@/core/', () => ({ describe('App', () => { it('checks service-worker is register', () => { + process.env.NEXT_PUBLIC_BUILD_ID = '123456'; jest.spyOn(console, 'error').mockImplementation(() => {}); const registerSpy = jest.fn(); @@ -42,11 +43,12 @@ describe('App', () => { wrapper: AppWrapper, }); - expect(registerSpy).toHaveBeenCalledWith('/service-worker.js'); + expect(registerSpy).toHaveBeenCalledWith('/service-worker.js?v=123456'); }); it('checks service-worker is not register', () => { process.env.NEXT_PUBLIC_SW_DEACTIVATED = 'true'; + process.env.NEXT_PUBLIC_BUILD_ID = '123456'; const registerSpy = jest.fn(); registerSpy.mockImplementation( @@ -66,6 +68,6 @@ describe('App', () => { wrapper: AppWrapper, }); - expect(registerSpy).not.toHaveBeenCalledWith('/service-worker.js'); + expect(registerSpy).not.toHaveBeenCalledWith('/service-worker.js?v=123456'); }); }); diff --git a/src/frontend/apps/impress/src/core/service-worker/service-worker.ts b/src/frontend/apps/impress/src/core/service-worker/service-worker.ts index 0dd051ad..b661d776 100644 --- a/src/frontend/apps/impress/src/core/service-worker/service-worker.ts +++ b/src/frontend/apps/impress/src/core/service-worker/service-worker.ts @@ -30,13 +30,15 @@ declare const self: ServiceWorkerGlobalScope & { self.__WB_DISABLE_DEV_LOGS = true; +const version = `v-${process.env.NEXT_PUBLIC_BUILD_ID}`; + setCacheNameDetails({ prefix: pkg.name, - suffix: `v${pkg.version}`, + suffix: version, }); const getCacheNameVersion = (cacheName: string) => - `${pkg.name}-${cacheName}-v${pkg.version}`; + `${pkg.name}-${cacheName}-${version}`; /** * In development, use NetworkFirst strategy, in production use CacheFirst strategy @@ -69,7 +71,7 @@ self.addEventListener('install', function (event) { }); self.addEventListener('activate', function (event) { - const cacheAllow = `v${pkg.version}`; + const cacheAllow = `${version}`; event.waitUntil( // Delete old caches diff --git a/src/frontend/apps/impress/src/pages/_app.tsx b/src/frontend/apps/impress/src/pages/_app.tsx index 85e87ee0..c78ded8b 100644 --- a/src/frontend/apps/impress/src/pages/_app.tsx +++ b/src/frontend/apps/impress/src/pages/_app.tsx @@ -21,9 +21,11 @@ export default function App({ Component, pageProps }: AppPropsWithLayout) { 'serviceWorker' in navigator && process.env.NEXT_PUBLIC_SW_DEACTIVATED !== 'true' ) { - navigator.serviceWorker.register('/service-worker.js').catch((err) => { - console.error('Service worker registration failed:', err); - }); + navigator.serviceWorker + .register(`/service-worker.js?v=${process.env.NEXT_PUBLIC_BUILD_ID}`) + .catch((err) => { + console.error('Service worker registration failed:', err); + }); } }, []);