Skip to content

Commit

Permalink
fix: not work SPA (ssr: false) mode (#2099)
Browse files Browse the repository at this point in the history
resolve #2029
  • Loading branch information
kazupon authored May 23, 2023
1 parent a314697 commit 3c5eda5
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export async function extendBundler(

const dynamicOptions: ResourceDynamicPluginOptions = {
prerenderTargs: options.prerenderTargets,
ssr: nuxt.options.ssr,
dev: nuxt.options.dev,
sourcemap: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client
}
Expand Down
3 changes: 2 additions & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ export default defineNuxtModule<NuxtI18nOptions>({

// for privates
nuxt.options.runtimeConfig.i18n = defu(nuxt.options.runtimeConfig.i18n, {
precompile: options.precompile
precompile: options.precompile,
ssr: nuxt.options.ssr
})

/**
Expand Down
40 changes: 32 additions & 8 deletions src/runtime/server/dynamic.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineEventHandler, setResponseHeader, createError } from 'h3'
// @ts-expect-error
import { useStorage } from '#imports'
import { useStorage, useRuntimeConfig } from '#imports'
import { relative, join } from 'pathe'
import { isObject, isFunction } from '@intlify/shared'

Expand All @@ -10,18 +10,32 @@ import type { PrerenderTarget } from '../../utils'
type ResourceMapValue = Pick<PrerenderTarget, 'type' | 'path'> & { locale?: string }

export default defineEventHandler(async event => {
const config = useRuntimeConfig()

const hash = event.context.params?.hash
if (hash == null) {
throw createError({ statusMessage: `require the 'hash'`, statusCode: 400 })
}

const i18nMeta = await getI18nMeta()
const [filename] = hash.split('.') // request from `xxx.js`
/**
* resolve pre-comilable config or locales
*/

const i18nMeta = await getI18nMeta(config.i18n.ssr)
const filename = getFilename(hash)
const target = i18nMeta[filename]

const loadPath = await resolveModule(target.path)
/**
* import a module that can pre-compile config or locales.
*/

const loadPath = await resolveModule(target.path, config.i18n.ssr)
const loader = await import(loadPath).then(m => m.default || m)

/**
* pre-compile
*/

if (target.type === 'locale') {
if (target.locale == null) {
throw createError({ statusMessage: `not found locale`, statusCode: 500 })
Expand All @@ -41,16 +55,26 @@ export default defineEventHandler(async event => {
}
})

async function getI18nMeta() {
return (await useStorage().getItem('build:dist:server:i18n-meta.json')) as Record<string, ResourceMapValue>
function getFilename(hash: string) {
const [filename] = hash.split('.') // request from `xxx.js`
return filename
}

const resourcePlace = (ssr = true) => (ssr ? 'server' : 'client')

async function getI18nMeta(ssr = true) {
return (await useStorage().getItem(`build:dist:${resourcePlace(ssr)}:i18n-meta.json`)) as Record<
string,
ResourceMapValue
>
}

async function resolveModule(path: string) {
async function resolveModule(path: string, ssr = true) {
const storage = await useStorage()
const rootMount = await storage.getMount('root')
const root = rootMount.driver.options.base
const rootRelative = relative(new URL(import.meta.url).pathname, root)
return join(rootRelative, 'dist/server', path)
return join(rootRelative, `dist/${resourcePlace(ssr)}`, path)
}

async function precompileLocale(locale: string, filename: string, messages: LocaleMessages<DefineLocaleMessage>) {
Expand Down
25 changes: 18 additions & 7 deletions src/transform/dynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import type { PrerenderTargets, PrerenderTarget } from '../utils'

export interface ResourceDynamicPluginOptions {
prerenderTargs: PrerenderTargets
ssr: boolean
dev?: boolean
sourcemap?: boolean
}

type ResourceMapValue = Pick<PrerenderTarget, 'type'> & { ref: string; locale?: string }
type ResourceMapValue = Pick<PrerenderTarget, 'type'> & { ref: string; hash: string; locale?: string }

const debug = createDebug('@nuxtjs/i18n:transform:dynamic')

Expand Down Expand Up @@ -73,10 +74,12 @@ export const ResourceDynamicPlugin = createUnplugin((options: ResourceDynamicPlu
const ref = this.emitFile({
// @ts-expect-error
type: 'chunk',
id
id,
preserveSignature: 'strict'
}) as unknown as string

resoucesMap.set(hash, {
resoucesMap.set(id, {
hash,
type: query.locale ? 'locale' : 'config',
locale: query.locale as string,
ref
Expand All @@ -87,10 +90,18 @@ export const ResourceDynamicPlugin = createUnplugin((options: ResourceDynamicPlu
},

vite: {
generateBundle() {
// console.log('generateBundle: outputOptions', outputOptions)
const resources = [...resoucesMap].reduce((obj, [hash, { type, locale, ref }]) => {
obj[hash] = { type, locale, path: this.getFileName(ref) }
generateBundle(outputOptions) {
/**
* NOTE:
* avoid generating i18n-meta.json for SPA mode,
* because some i18n resources doesn't bundle on server-side
*/
if (!options.ssr && outputOptions.dir?.endsWith('server')) {
return
}

const resources = [...resoucesMap].reduce((obj, [_, { hash, type, locale, ref }]) => {
obj[hash] = { hash, type, locale, path: this.getFileName(ref) }
return obj
}, {} as Record<string, Omit<ResourceMapValue, 'ref'> & { path: string }>)
debug('generateBundle: resources', resources)
Expand Down

0 comments on commit 3c5eda5

Please sign in to comment.