90 lines
3.4 KiB
TypeScript
90 lines
3.4 KiB
TypeScript
import type { Nuxt } from '@nuxt/schema'
|
|
import type { VitePWAOptions } from 'vite-plugin-pwa'
|
|
import { resolve } from 'pathe'
|
|
|
|
export function configurePWAOptions(options: Partial<VitePWAOptions>, nuxt: Nuxt) {
|
|
if (!options.outDir) {
|
|
const publicDir = nuxt.options.nitro?.output?.publicDir
|
|
options.outDir = publicDir ? resolve(publicDir) : resolve(nuxt.options.buildDir, '../.output/public')
|
|
}
|
|
|
|
let config: Partial<
|
|
import('workbox-build').BasePartial
|
|
& import('workbox-build').GlobPartial
|
|
& import('workbox-build').RequiredGlobDirectoryPartial
|
|
>
|
|
|
|
if (options.strategies === 'injectManifest') {
|
|
options.injectManifest = options.injectManifest ?? {}
|
|
config = options.injectManifest
|
|
}
|
|
else {
|
|
options.workbox = options.workbox ?? {}
|
|
if (options.registerType === 'autoUpdate' && (options.injectRegister === 'script' || options.injectRegister === 'inline')) {
|
|
options.workbox.clientsClaim = true
|
|
options.workbox.skipWaiting = true
|
|
}
|
|
if (nuxt.options.dev) {
|
|
// on dev force always to use the root
|
|
|
|
options.workbox.navigateFallback = nuxt.options.app.baseURL ?? '/'
|
|
if (options.devOptions?.enabled && !options.devOptions.navigateFallbackAllowlist)
|
|
options.devOptions.navigateFallbackAllowlist = [new RegExp(nuxt.options.app.baseURL) ?? /\//]
|
|
}
|
|
config = options.workbox
|
|
}
|
|
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 ?? '/', appManifestFolder)]
|
|
}
|
|
|
|
function createManifestTransform(base: string, appManifestFolder?: string): import('workbox-build').ManifestTransform {
|
|
return async (entries) => {
|
|
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') {
|
|
e.url = base
|
|
}
|
|
else {
|
|
const parts = url.split('/')
|
|
parts[parts.length - 1] = parts[parts.length - 1].replace(/\.html$/, '')
|
|
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: [] }
|
|
}
|
|
}
|