diff --git a/config/pwa.ts b/config/pwa.ts index 19c82b7f..c6ce1016 100644 --- a/config/pwa.ts +++ b/config/pwa.ts @@ -15,16 +15,6 @@ export const pwa: VitePWANuxtOptions = { injectManifest: { globPatterns: ['**/*.{js,json,css,html,txt,svg,png,ico,webp,woff,woff2,ttf,eot,otf,wasm}'], globIgnores: ['emojis/**', 'shiki/**', 'manifest**.webmanifest'], - manifestTransforms: [(entries) => { - const manifest = entries.map((entry) => { - if (entry.url.length > 1 && entry.url[0] !== '/') - entry.url = `/${entry.url}` - - return entry - }) - - return { manifest, warnings: [] } - }], }, devOptions: { enabled: process.env.VITE_DEV_PWA === 'true', diff --git a/modules/pwa/config.ts b/modules/pwa/config.ts index 262f00ab..fecec2e8 100644 --- a/modules/pwa/config.ts +++ b/modules/pwa/config.ts @@ -32,25 +32,37 @@ export function configurePWAOptions(options: Partial, nuxt: Nuxt options.devOptions.navigateFallbackAllowlist = [new RegExp(nuxt.options.app.baseURL) ?? /\//] } config = options.workbox - // todo: change navigateFallback based on the command: use 404 only when using generate - /* else if (nuxt.options.build) { - if (!options.workbox.navigateFallback) - options.workbox.navigateFallback = '/200.html' - } */ } + let buildAssetsDir = nuxt.options.app.buildAssetsDir ?? '_nuxt/' + if (buildAssetsDir[0] === '/') + buildAssetsDir = buildAssetsDir.slice(1) + if (buildAssetsDir[buildAssetsDir.length - 1] !== '/') + buildAssetsDir += '/' + + // Vite 5 support: allow override dontCacheBustURLsMatching + if (!('dontCacheBustURLsMatching' in config)) + config.dontCacheBustURLsMatching = new RegExp(buildAssetsDir) + + // handle payload extraction + if (nuxt.options.experimental.payloadExtraction) { + config.globPatterns = config.globPatterns ?? [] + config.globPatterns.push('**/_payload.json') + } + + // handle Nuxt App Manifest + let appManifestFolder: string | undefined + if (nuxt.options.experimental.appManifest) { + config.globPatterns = config.globPatterns ?? [] + appManifestFolder = `${buildAssetsDir}builds/` + config.globPatterns.push(`${appManifestFolder}**/*.json`) + } + if (!nuxt.options.dev) - config.manifestTransforms = [createManifestTransform(nuxt.options.app.baseURL ?? '/')] + config.manifestTransforms = [createManifestTransform(nuxt.options.app.baseURL ?? '/', appManifestFolder)] } -function createManifestTransform(base: string): import('workbox-build').ManifestTransform { +function createManifestTransform(base: string, appManifestFolder?: string): import('workbox-build').ManifestTransform { return async (entries) => { - // prefix non html assets with base - /* - entries.filter(e => e && !e.url.endsWith('.html')).forEach((e) => { - if (!e.url.startsWith(base)) - e.url = `${base}${e.url}` - }) -*/ entries.filter(e => e && e.url.endsWith('.html')).forEach((e) => { const url = e.url.startsWith('/') ? e.url.slice(1) : e.url if (url === 'index.html') { @@ -59,11 +71,19 @@ function createManifestTransform(base: string): import('workbox-build').Manifest else { const parts = url.split('/') parts[parts.length - 1] = parts[parts.length - 1].replace(/\.html$/, '') - // e.url = `${base}${parts.length > 1 ? parts.slice(0, parts.length - 1).join('/') : parts[0]}` e.url = parts.length > 1 ? parts.slice(0, parts.length - 1).join('/') : parts[0] } }) + if (appManifestFolder) { + const regExp = /(\/)?[0-9a-f]{8}\b-[0-9a-f]{4}\b-[0-9a-f]{4}\b-[0-9a-f]{4}\b-[0-9a-f]{12}\.json$/i + // we need to remove the revision from the sw prechaing manifest, UUID is enough: + // we don't use dontCacheBustURLsMatching, single regex + entries.filter(e => e && e.url.startsWith(appManifestFolder) && regExp.test(e.url)).forEach((e) => { + e.revision = null + }) + } + return { manifest: entries, warnings: [] } } } diff --git a/modules/pwa/index.ts b/modules/pwa/index.ts index 72a348c1..210b56a9 100644 --- a/modules/pwa/index.ts +++ b/modules/pwa/index.ts @@ -217,10 +217,8 @@ export default defineNuxtModule({ } } }) - nuxt.hook('nitro:init', (nitro) => { - nitro.hooks.hook('rollup:before', async () => { - await resolveVitePluginPWAAPI()?.generateSW() - }) + nuxt.hook('nitro:build:public-assets', async () => { + await resolveVitePluginPWAAPI()?.generateSW() }) } },