Skip to content

Commit

Permalink
feat(i18n): add splitServiceWorker which splits service worker by loc…
Browse files Browse the repository at this point in the history
…ale if set
  • Loading branch information
Antoine Monnet committed Jan 18, 2025
1 parent 272c836 commit 68db259
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export interface I18nOptions {
* Split manifest per locale : defaults to false.
*/
splitManifest?: boolean
/**
* Split service worker per locale : defaults to false.
*/
splitServiceWorker?: boolean
}

export interface PwaModuleOptions extends Partial<VitePWAOptions> {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function configurePWAOptions(
config.dontCacheBustURLsMatching = new RegExp(buildAssetsDir)

// handle payload extraction
if (nuxt.options.experimental.payloadExtraction) {
if (nuxt.options.experimental.payloadExtraction && !options.i18n?.splitServiceWorker) {
const enableGlobPatterns = nuxt.options._generate
|| (
!!nitroConfig.prerender?.routes?.length
Expand Down
26 changes: 23 additions & 3 deletions src/utils/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

import { useNuxt, loadNuxtModuleInstance } from '@nuxt/kit'
import { resolve } from 'pathe'
import { resolve, join, basename } from 'pathe'
import type { PwaModuleOptions } from 'vite-plugin-pwa'
import type { NuxtI18nOptions } from '@nuxtjs/i18n'
import type { NuxtModule } from 'nuxt/schema'

export async function webManifests(manifestDir) {

const i18nOptions = await getNuxtModuleOptions('@nuxtjs/i18n') as NuxtI18nOptions

return i18nOptions.locales.map(({code})=>{
Expand All @@ -21,6 +21,26 @@ export async function webManifests(manifestDir) {
})
}

export async function swOptions(options: PwaModuleOptions) {
const i18nOptions = await getNuxtModuleOptions('@nuxtjs/i18n') as NuxtI18nOptions
const ignorePrefix = i18nOptions.locales.map(({code})=>code).join(',')
return i18nOptions.locales.map(({code})=>{
const prefix = getLocalePath(i18nOptions, code)
const swDest = join(options.outDir, prefix, basename(options.swDest) || "sw.js")
const ret:Partial<PwaModuleOptions> = {
outDir: join(options.outDir, prefix),
swDest: swDest,
}
ret.injectManifest = ret.workbox = ({
swDest: swDest,
globPatterns: [join(prefix, '**', '_payload.json')],
globIgnores: prefix ? [] : [join(`{${ignorePrefix}}`, '**', '_payload.json')],
modifyURLPrefix: {"": "/"},
})
return ret
})
}

//from https://github.com/nuxt-modules/sitemap/blob/main/src/util/kit.ts
async function getNuxtModuleOptions(module: string | NuxtModule, nuxt: Nuxt = useNuxt()) {
const moduleMeta = (typeof module === 'string' ? { name: module } : await module.getMeta?.()) || {}
Expand All @@ -46,7 +66,7 @@ async function getNuxtModuleOptions(module: string | NuxtModule, nuxt: Nuxt = us
return inlineOptions
}

function getLocalePath(options, localeCode) {
function getLocalePath(options: NuxtI18nOptions, localeCode: string) {
switch (options.strategy) {
case 'prefix_except_default':
case 'prefix_and_default':
Expand Down
6 changes: 3 additions & 3 deletions src/utils/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ export const periodicSyncForUpdates = ${typeof client.periodicSyncForUpdates ===
if (nuxt3_8) {
nuxt.hook('nitro:build:public-assets', async () => {
await regeneratePWA(
options.outDir!,
options,
pwaAssets,
resolveVitePluginPWAAPI(),
)
Expand All @@ -325,7 +325,7 @@ export const periodicSyncForUpdates = ${typeof client.periodicSyncForUpdates ===
nuxt.hook('nitro:init', (nitro) => {
nitro.hooks.hook('rollup:before', async () => {
await regeneratePWA(
options.outDir!,
options,
pwaAssets,
resolveVitePluginPWAAPI(),
)
Expand All @@ -334,7 +334,7 @@ export const periodicSyncForUpdates = ${typeof client.periodicSyncForUpdates ===
if (nuxt.options._generate) {
nuxt.hook('close', async () => {
await regeneratePWA(
options.outDir!,
options,
pwaAssets,
resolveVitePluginPWAAPI(),
)
Expand Down
9 changes: 7 additions & 2 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { mkdir, writeFile } from 'node:fs/promises'
import type { VitePluginPWAAPI, PwaModuleOptions } from 'vite-plugin-pwa'
import { resolve } from 'pathe'

export async function regeneratePWA(_dir: string, pwaAssets: boolean, api?: VitePluginPWAAPI) {
export async function regeneratePWA(options: PwaModuleOptions, pwaAssets: boolean, api?: VitePluginPWAAPI) {
if (pwaAssets) {
const pwaAssetsGenerator = await api?.pwaAssetsGenerator()
if (pwaAssetsGenerator)
Expand All @@ -12,7 +12,12 @@ export async function regeneratePWA(_dir: string, pwaAssets: boolean, api?: Vite
if (!api || api.disabled)
return

await api.generateSW()
if (options.i18n?.splitServiceWorker == true) {
const i18n = await import('./i18n')
await Promise.all((await i18n.swOptions(options)).map(api.generateSW))
} else {
await api.generateSW()
}
}

export async function writeWebManifest(dir: string, options: PwaModuleOptions, api: VitePluginPWAAPI, pwaAssets: boolean) {
Expand Down

0 comments on commit 68db259

Please sign in to comment.