From 6dcd6cb429cc10ed086aabdbedffafee9796da7d Mon Sep 17 00:00:00 2001 From: userquin Date: Fri, 20 Sep 2024 16:11:11 +0200 Subject: [PATCH 1/4] chore: refactor module --- src/alias.ts | 6 +- src/context.ts | 51 ++++++++ src/module.ts | 213 +++++----------------------------- src/nitro.ts | 10 +- src/pages.ts | 5 +- src/prepare-auto-imports.ts | 48 ++++++++ src/prepare-options.ts | 34 ++++++ src/prepare-runtime-config.ts | 26 +++++ src/prepare-runtime.ts | 51 ++++++++ src/resolve-locale-info.ts | 28 +++++ 10 files changed, 277 insertions(+), 195 deletions(-) create mode 100644 src/context.ts create mode 100644 src/prepare-auto-imports.ts create mode 100644 src/prepare-options.ts create mode 100644 src/prepare-runtime-config.ts create mode 100644 src/prepare-runtime.ts create mode 100644 src/resolve-locale-info.ts diff --git a/src/alias.ts b/src/alias.ts index 405b4f95d..c4b87e9ef 100644 --- a/src/alias.ts +++ b/src/alias.ts @@ -14,16 +14,16 @@ import { } from './constants' import type { Nuxt } from '@nuxt/schema' -import type { NuxtI18nOptions } from './types' +import type { I18nNuxtContext } from './context' const debug = createDebug('@nuxtjs/i18n:alias') -export async function setupAlias(nuxt: Nuxt, options: NuxtI18nOptions) { +export async function setupAlias({ userOptions: options, isDev, isPrepare }: I18nNuxtContext, nuxt: Nuxt) { const runtimeOnly = options.bundle?.runtimeOnly const modules: Record = {} modules[VUE_I18N_PKG] = - nuxt.options.dev || nuxt.options._prepare + isDev || isPrepare ? `${VUE_I18N_PKG}/dist/vue-i18n.mjs` : `${VUE_I18N_PKG}/dist/vue-i18n${runtimeOnly ? '.runtime' : ''}.mjs` modules[SHARED_PKG] = `${SHARED_PKG}/dist/shared.mjs` diff --git a/src/context.ts b/src/context.ts new file mode 100644 index 000000000..0b9603adf --- /dev/null +++ b/src/context.ts @@ -0,0 +1,51 @@ +import type { Resolver } from '@nuxt/kit' +import type { LocaleInfo, LocaleObject, NuxtI18nOptions, VueI18nConfigPathInfo } from './types' +import type { Nuxt } from '@nuxt/schema' +import { createResolver, useLogger } from '@nuxt/kit' +import { NUXT_I18N_MODULE_ID } from './constants' +import createDebug from 'debug' + +export interface I18nNuxtContext { + resolver: Resolver + logger: ReturnType<(typeof import('@nuxt/kit'))['useLogger']> + debug: ReturnType + userOptions: NuxtI18nOptions + options: Required + isDev: boolean + isSSR: boolean + isPrepare: boolean + isSSG: boolean + isBuild: boolean + isTest: boolean + genTemplate: (isServer: boolean, lazy?: boolean) => string + normalizedLocales: LocaleObject[] + localeCodes: string[] + localeInfo: LocaleInfo[] + vueI18nConfigPaths: Required[] +} + +const debug = createDebug('@nuxtjs/i18n:context') +const resolver = createResolver(import.meta.url) + +export function createContext(userOptions: NuxtI18nOptions, nuxt: Nuxt): I18nNuxtContext { + const options = userOptions as Required + + return { + resolver, + logger: useLogger(NUXT_I18N_MODULE_ID), + debug, + userOptions, + options, + isDev: nuxt.options.dev, + isSSR: nuxt.options.ssr, + isPrepare: nuxt.options._prepare, + isSSG: nuxt.options._generate, + isBuild: nuxt.options._build, + isTest: nuxt.options.test, + genTemplate: undefined!, + normalizedLocales: undefined!, + localeCodes: undefined!, + localeInfo: undefined!, + vueI18nConfigPaths: undefined! + } +} diff --git a/src/module.ts b/src/module.ts index 9f03e3f66..8d0b4dea6 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,52 +1,26 @@ -import createDebug from 'debug' -import { - defineNuxtModule, - addComponent, - addPlugin, - addTemplate, - addTypeTemplate, - addImports, - useLogger, - createResolver -} from '@nuxt/kit' -import { resolve, relative } from 'pathe' -import { defu } from 'defu' +import { defineNuxtModule, addTypeTemplate } from '@nuxt/kit' +import { relative } from 'pathe' import { setupAlias } from './alias' import { setupPages } from './pages' import { setupNitro } from './nitro' import { extendBundler } from './bundler' -import { generateI18nTypes, generateLoaderOptions, simplifyLocaleOptions } from './gen' -import { - NUXT_I18N_MODULE_ID, - DEFAULT_OPTIONS, - NUXT_I18N_TEMPLATE_OPTIONS_KEY, - NUXT_I18N_COMPOSABLE_DEFINE_ROUTE, - NUXT_I18N_COMPOSABLE_DEFINE_LOCALE, - NUXT_I18N_COMPOSABLE_DEFINE_CONFIG, - VUE_I18N_PKG -} from './constants' -import { - formatMessage, - getNormalizedLocales, - resolveLocales, - mergeI18nModules, - applyOptionOverrides, - getLocaleFiles, - filterLocales -} from './utils' -import { runtimeDir } from './dirs' -import { applyLayerOptions, checkLayerOptions, resolveLayerVueI18nConfigInfo } from './layers' -import { generateTemplateNuxtI18nOptions } from './template' -import { i18nVirtualLoggerPlugin, RESOLVED_VIRTUAL_NUXT_I18N_LOGGER, VIRTUAL_NUXT_I18N_LOGGER } from './virtual-logger' - +import { generateI18nTypes } from './gen' +import { NUXT_I18N_MODULE_ID, DEFAULT_OPTIONS } from './constants' +import { mergeI18nModules, getLocaleFiles, filterLocales } from './utils' +import { applyLayerOptions } from './layers' +import { i18nVirtualLoggerPlugin, RESOLVED_VIRTUAL_NUXT_I18N_LOGGER } from './virtual-logger' import type { HookResult } from '@nuxt/schema' import type { LocaleObject, NuxtI18nOptions } from './types' import type { Locale } from 'vue-i18n' +import { createContext } from './context' +import { prepareOptions } from './prepare-options' +import { resolveLocaleInfo } from './resolve-locale-info' +import { prepareRuntime } from './prepare-runtime' +import { prepareRuntimeConfig } from './prepare-runtime-config' +import { prepareAutoImports } from './prepare-auto-imports' export * from './types' -const debug = createDebug('@nuxtjs/i18n:module') - export default defineNuxtModule({ meta: { name: NUXT_I18N_MODULE_ID, @@ -58,47 +32,18 @@ export default defineNuxtModule({ }, defaults: DEFAULT_OPTIONS, async setup(i18nOptions, nuxt) { - const logger = useLogger(NUXT_I18N_MODULE_ID) - - nuxt.hook('prepare:types', ({ references }) => { - references.push({ types: `${NUXT_I18N_MODULE_ID}/internals` }) - }) - - const options = i18nOptions as Required - applyOptionOverrides(options, nuxt) - debug('options', options) + const ctx = createContext(i18nOptions, nuxt) - checkLayerOptions(options, nuxt) + const { isSSG, options } = ctx /** - * Check conflicting options + * Prepare options */ - - if (options.bundle.compositionOnly && options.types === 'legacy') { - throw new Error( - formatMessage( - '`bundle.compositionOnly` option and `types` option is conflicting: ' + - `bundle.compositionOnly: ${options.bundle.compositionOnly}, types: ${JSON.stringify(options.types)}` - ) - ) - } - - if (options.experimental.autoImportTranslationFunctions && nuxt.options.imports.autoImport === false) { - logger.warn( - 'Disabling `autoImports` in Nuxt is not compatible with `experimental.autoImportTranslationFunctions`, either enable `autoImports` or disable `experimental.autoImportTranslationFunctions`.' - ) - } - - if (nuxt.options.experimental.scanPageMeta === false) { - logger.warn( - "Route localization features (e.g. custom name, prefixed aliases) require Nuxt's `experimental.scanPageMeta` to be enabled.\nThis feature will be enabled in future Nuxt versions (https://github.com/nuxt/nuxt/pull/27134), check out the docs for more details: https://nuxt.com/docs/guide/going-further/experimental-features#scanpagemeta" - ) - } + prepareOptions(ctx, nuxt) /** * nuxt layers handling ... */ - applyLayerOptions(options, nuxt) await mergeI18nModules(options, nuxt) filterLocales(options, nuxt) @@ -106,57 +51,27 @@ export default defineNuxtModule({ /** * setup runtime config */ - // for public - // @ts-expect-error generated type - nuxt.options.runtimeConfig.public.i18n = defu(nuxt.options.runtimeConfig.public.i18n, { - baseUrl: options.baseUrl, - defaultLocale: options.defaultLocale, - defaultDirection: options.defaultDirection, - strategy: options.strategy, - lazy: options.lazy, - rootRedirect: options.rootRedirect, - routesNameSeparator: options.routesNameSeparator, - defaultLocaleRouteNameSuffix: options.defaultLocaleRouteNameSuffix, - skipSettingLocaleOnNavigate: options.skipSettingLocaleOnNavigate, - differentDomains: options.differentDomains, - trailingSlash: options.trailingSlash, - locales: options.locales, - detectBrowserLanguage: options.detectBrowserLanguage ?? DEFAULT_OPTIONS.detectBrowserLanguage, - experimental: options.experimental, - multiDomainLocales: options.multiDomainLocales - // TODO: we should support more i18n module options. welcome PRs :-) - }) - - /** - * resolve locale info - */ - - const normalizedLocales = getNormalizedLocales(options.locales) - const localeCodes = normalizedLocales.map(locale => locale.code) - const localeInfo = await resolveLocales(nuxt.options.srcDir, normalizedLocales, nuxt.options.buildDir) - debug('localeInfo', localeInfo) + prepareRuntimeConfig(ctx, nuxt) /** - * resolve vue-i18n config path + * resolve locale info and vue-i18n config path */ + await resolveLocaleInfo(ctx, nuxt) - const vueI18nConfigPaths = await resolveLayerVueI18nConfigInfo(options) - debug('VueI18nConfigPaths', vueI18nConfigPaths) + const { normalizedLocales, localeInfo, localeCodes } = ctx /** * setup nuxt/pages */ - if (localeCodes.length) { - setupPages(options, nuxt) + setupPages(ctx, nuxt) } /** * ignore `/` during prerender when using prefixed routing */ - - if (options.strategy === 'prefix' && nuxt.options._generate) { + if (options.strategy === 'prefix' && isSSG) { const localizedEntryPages = normalizedLocales.map(x => ['/', x.code].join('')) nuxt.hook('nitro:config', config => { config.prerender ??= {} @@ -174,51 +89,12 @@ export default defineNuxtModule({ /** * setup module alias */ - - await setupAlias(nuxt, options) + await setupAlias(ctx, nuxt) /** * add plugin and templates */ - - // for core plugin - addPlugin(resolve(runtimeDir, 'plugins/i18n')) - addPlugin(resolve(runtimeDir, 'plugins/switch-locale-path-ssr')) - - const resolver = createResolver(import.meta.url) - // for composables - nuxt.options.alias['#i18n'] = resolver.resolve('./runtime/composables/index') - nuxt.options.build.transpile.push('#i18n') - nuxt.options.build.transpile.push(VIRTUAL_NUXT_I18N_LOGGER) - - const genTemplate = (isServer: boolean, lazy?: boolean) => { - const nuxtI18nOptions = defu({}, options) - // override `lazy` options - if (lazy != null) { - nuxtI18nOptions.lazy = lazy - } - return generateTemplateNuxtI18nOptions({ - ...generateLoaderOptions(nuxt, { - vueI18nConfigPaths, - localeInfo, - nuxtI18nOptions, - isServer - }), - localeCodes, - normalizedLocales, - dev: nuxt.options.dev, - isSSG: nuxt.options._generate, - parallelPlugin: options.parallelPlugin - }) - } - - nuxt.options.runtimeConfig.public.i18n.locales = simplifyLocaleOptions(nuxt, defu({}, options)) - - addTemplate({ - filename: NUXT_I18N_TEMPLATE_OPTIONS_KEY, - write: true, - getContents: () => genTemplate(false) - }) + prepareRuntime(ctx, nuxt) nuxt.options.imports.transform ??= {} nuxt.options.imports.transform.include ??= [] @@ -269,48 +145,15 @@ export default defineNuxtModule({ * setup nitro */ - await setupNitro(nuxt, options, { - optionsCode: genTemplate(true, true), + await setupNitro(ctx, nuxt, { + optionsCode: ctx.genTemplate(true, true), localeInfo }) /** * auto imports */ - - const vueI18nPath = nuxt.options.alias[VUE_I18N_PKG] - debug('vueI18nPath for auto-import', vueI18nPath) - - await addComponent({ - name: 'NuxtLinkLocale', - filePath: resolve(runtimeDir, 'components/NuxtLinkLocale') - }) - - await addComponent({ - name: 'SwitchLocalePathLink', - filePath: resolve(runtimeDir, 'components/SwitchLocalePathLink') - }) - - addImports([ - { name: 'useI18n', from: vueI18nPath }, - ...[ - 'useRouteBaseName', - 'useLocalePath', - 'useLocaleRoute', - 'useSwitchLocalePath', - 'useLocaleHead', - 'useBrowserLocale', - 'useCookieLocale', - 'useSetI18nParams', - NUXT_I18N_COMPOSABLE_DEFINE_ROUTE, - NUXT_I18N_COMPOSABLE_DEFINE_LOCALE, - NUXT_I18N_COMPOSABLE_DEFINE_CONFIG - ].map(key => ({ - name: key, - as: key, - from: resolve(runtimeDir, 'composables/index') - })) - ]) + await prepareAutoImports(ctx, nuxt) /** * transpile @nuxtjs/i18n diff --git a/src/nitro.ts b/src/nitro.ts index 5b956b90e..398ee59df 100644 --- a/src/nitro.ts +++ b/src/nitro.ts @@ -2,7 +2,7 @@ import createDebug from 'debug' import { resolveModuleExportNames } from 'mlly' import { defu } from 'defu' import { resolve } from 'pathe' -import { addServerPlugin, createResolver, resolvePath, useLogger } from '@nuxt/kit' +import { addServerPlugin, resolvePath, useLogger } from '@nuxt/kit' import yamlPlugin from '@rollup/plugin-yaml' import json5Plugin from '@miyaneee/rollup-plugin-json5' import { getFeatureFlags } from './bundler' @@ -18,9 +18,10 @@ import { } from './constants' import type { Nuxt } from '@nuxt/schema' -import type { NuxtI18nOptions, LocaleInfo } from './types' +import type { LocaleInfo } from './types' import { resolveI18nDir } from './layers' import { i18nVirtualLoggerPlugin } from './virtual-logger' +import type { I18nNuxtContext } from '~/src/context' const debug = createDebug('@nuxtjs/i18n:nitro') @@ -30,11 +31,10 @@ type AdditionalSetupNitroParams = { } export async function setupNitro( + { isSSR, resolver, options: nuxtOptions }: I18nNuxtContext, nuxt: Nuxt, - nuxtOptions: Required, additionalParams: AdditionalSetupNitroParams ) { - const resolver = createResolver(import.meta.url) const [enableServerIntegration, localeDetectionPath] = await resolveLocaleDetectorPath(nuxt) nuxt.hook('nitro:config', async nitroConfig => { @@ -111,7 +111,7 @@ export { localeDetector } nitroConfig.replace = nitroConfig.replace || {} - if (nuxt.options.ssr) { + if (isSSR) { // vue-i18n feature flags configuration for server-side (server api, server middleware, etc...) nitroConfig.replace = { ...nitroConfig.replace, diff --git a/src/pages.ts b/src/pages.ts index a7bbe9f1b..fd4ac12ba 100644 --- a/src/pages.ts +++ b/src/pages.ts @@ -13,6 +13,7 @@ import { NUXT_I18N_COMPOSABLE_DEFINE_ROUTE } from './constants' import type { Nuxt, NuxtPage } from '@nuxt/schema' import type { NuxtI18nOptions, CustomRoutePages, ComputedRouteOptions, RouteOptionsResolver } from './types' import type { Node, ObjectExpression, ArrayExpression } from '@babel/types' +import type { I18nNuxtContext } from '~/src/context' const debug = createDebug('@nuxtjs/i18n:pages') @@ -34,8 +35,8 @@ export type NuxtPageAnalyzeContext = { pages: Map } -export function setupPages(options: Required, nuxt: Nuxt) { - let includeUnprefixedFallback = nuxt.options.ssr === false +export function setupPages({ options, isSSR }: I18nNuxtContext, nuxt: Nuxt) { + let includeUnprefixedFallback = !isSSR nuxt.hook('nitro:init', () => { debug('enable includeUprefixedFallback') includeUnprefixedFallback = options.strategy !== 'prefix' diff --git a/src/prepare-auto-imports.ts b/src/prepare-auto-imports.ts new file mode 100644 index 000000000..04b89711c --- /dev/null +++ b/src/prepare-auto-imports.ts @@ -0,0 +1,48 @@ +import type { Nuxt } from '@nuxt/schema' +import { + NUXT_I18N_COMPOSABLE_DEFINE_CONFIG, + NUXT_I18N_COMPOSABLE_DEFINE_LOCALE, + NUXT_I18N_COMPOSABLE_DEFINE_ROUTE, + VUE_I18N_PKG +} from './constants' +import { addComponent, addImports } from '@nuxt/kit' +import { resolve } from 'pathe' +import { runtimeDir } from './dirs' +import type { I18nNuxtContext } from './context' + +export async function prepareAutoImports({ debug }: I18nNuxtContext, nuxt: Nuxt) { + const vueI18nPath = nuxt.options.alias[VUE_I18N_PKG] + debug('vueI18nPath for auto-import', vueI18nPath) + + await Promise.all([ + addComponent({ + name: 'NuxtLinkLocale', + filePath: resolve(runtimeDir, 'components/NuxtLinkLocale') + }), + addComponent({ + name: 'SwitchLocalePathLink', + filePath: resolve(runtimeDir, 'components/SwitchLocalePathLink') + }) + ]) + + addImports([ + { name: 'useI18n', from: vueI18nPath }, + ...[ + 'useRouteBaseName', + 'useLocalePath', + 'useLocaleRoute', + 'useSwitchLocalePath', + 'useLocaleHead', + 'useBrowserLocale', + 'useCookieLocale', + 'useSetI18nParams', + NUXT_I18N_COMPOSABLE_DEFINE_ROUTE, + NUXT_I18N_COMPOSABLE_DEFINE_LOCALE, + NUXT_I18N_COMPOSABLE_DEFINE_CONFIG + ].map(key => ({ + name: key, + as: key, + from: resolve(runtimeDir, 'composables/index') + })) + ]) +} diff --git a/src/prepare-options.ts b/src/prepare-options.ts new file mode 100644 index 000000000..0129ceb7e --- /dev/null +++ b/src/prepare-options.ts @@ -0,0 +1,34 @@ +import type { I18nNuxtContext } from './context' +import type { Nuxt } from '@nuxt/schema' +import { applyOptionOverrides, formatMessage } from './utils' +import { checkLayerOptions } from './layers' + +export function prepareOptions({ debug, logger, options }: I18nNuxtContext, nuxt: Nuxt) { + applyOptionOverrides(options, nuxt) + debug('options', options) + checkLayerOptions(options, nuxt) + + /** + * Check conflicting options + */ + if (options.bundle.compositionOnly && options.types === 'legacy') { + throw new Error( + formatMessage( + '`bundle.compositionOnly` option and `types` option is conflicting: ' + + `bundle.compositionOnly: ${options.bundle.compositionOnly}, types: ${JSON.stringify(options.types)}` + ) + ) + } + + if (options.experimental.autoImportTranslationFunctions && nuxt.options.imports.autoImport === false) { + logger.warn( + 'Disabling `autoImports` in Nuxt is not compatible with `experimental.autoImportTranslationFunctions`, either enable `autoImports` or disable `experimental.autoImportTranslationFunctions`.' + ) + } + + if (nuxt.options.experimental.scanPageMeta === false) { + logger.warn( + "Route localization features (e.g. custom name, prefixed aliases) require Nuxt's `experimental.scanPageMeta` to be enabled.\nThis feature will be enabled in future Nuxt versions (https://github.com/nuxt/nuxt/pull/27134), check out the docs for more details: https://nuxt.com/docs/guide/going-further/experimental-features#scanpagemeta" + ) + } +} diff --git a/src/prepare-runtime-config.ts b/src/prepare-runtime-config.ts new file mode 100644 index 000000000..5bc8440c9 --- /dev/null +++ b/src/prepare-runtime-config.ts @@ -0,0 +1,26 @@ +import type { I18nNuxtContext } from './context' +import type { Nuxt } from '@nuxt/schema' +import { DEFAULT_OPTIONS } from './constants' +import { defu } from 'defu' + +export function prepareRuntimeConfig({ options }: I18nNuxtContext, nuxt: Nuxt) { + // @ts-expect-error generated type + nuxt.options.runtimeConfig.public.i18n = defu(nuxt.options.runtimeConfig.public.i18n, { + baseUrl: options.baseUrl, + defaultLocale: options.defaultLocale, + defaultDirection: options.defaultDirection, + strategy: options.strategy, + lazy: options.lazy, + rootRedirect: options.rootRedirect, + routesNameSeparator: options.routesNameSeparator, + defaultLocaleRouteNameSuffix: options.defaultLocaleRouteNameSuffix, + skipSettingLocaleOnNavigate: options.skipSettingLocaleOnNavigate, + differentDomains: options.differentDomains, + trailingSlash: options.trailingSlash, + locales: options.locales, + detectBrowserLanguage: options.detectBrowserLanguage ?? DEFAULT_OPTIONS.detectBrowserLanguage, + experimental: options.experimental, + multiDomainLocales: options.multiDomainLocales + // TODO: we should support more i18n module options. welcome PRs :-) + }) +} diff --git a/src/prepare-runtime.ts b/src/prepare-runtime.ts new file mode 100644 index 000000000..48be30160 --- /dev/null +++ b/src/prepare-runtime.ts @@ -0,0 +1,51 @@ +import type { Nuxt } from '@nuxt/schema' +import type { I18nNuxtContext } from './context' +import { VIRTUAL_NUXT_I18N_LOGGER } from './virtual-logger' +import { defu } from 'defu' +import { addPlugin, addTemplate } from '@nuxt/kit' +import { generateTemplateNuxtI18nOptions } from './template' +import { generateLoaderOptions, simplifyLocaleOptions } from './gen' +import { NUXT_I18N_TEMPLATE_OPTIONS_KEY } from './constants' + +export function prepareRuntime(ctx: I18nNuxtContext, nuxt: Nuxt) { + const { isDev: dev, isSSG, localeCodes, localeInfo, normalizedLocales, options, resolver, vueI18nConfigPaths } = ctx + // for core plugin + addPlugin(resolver.resolve('./runtime/plugins/i18n')) + addPlugin(resolver.resolve('./runtime/plugins/switch-locale-path-ssr')) + + // for composables + nuxt.options.alias['#i18n'] = resolver.resolve('./runtime/composables/index') + nuxt.options.build.transpile.push('#i18n') + nuxt.options.build.transpile.push(VIRTUAL_NUXT_I18N_LOGGER) + + const genTemplate = (isServer: boolean, lazy?: boolean) => { + const nuxtI18nOptions = defu({}, options) + // override `lazy` options + if (lazy != null) { + nuxtI18nOptions.lazy = lazy + } + return generateTemplateNuxtI18nOptions({ + ...generateLoaderOptions(nuxt, { + vueI18nConfigPaths, + localeInfo, + nuxtI18nOptions, + isServer + }), + localeCodes, + normalizedLocales, + dev, + isSSG, + parallelPlugin: options.parallelPlugin + }) + } + + ctx.genTemplate = genTemplate + + nuxt.options.runtimeConfig.public.i18n.locales = simplifyLocaleOptions(nuxt, defu({}, options)) + + addTemplate({ + filename: NUXT_I18N_TEMPLATE_OPTIONS_KEY, + write: true, + getContents: () => genTemplate(false) + }) +} diff --git a/src/resolve-locale-info.ts b/src/resolve-locale-info.ts new file mode 100644 index 000000000..ad718a150 --- /dev/null +++ b/src/resolve-locale-info.ts @@ -0,0 +1,28 @@ +import type { I18nNuxtContext } from './context' +import type { Nuxt } from '@nuxt/schema' +import { getNormalizedLocales, resolveLocales } from './utils' +import { resolveLayerVueI18nConfigInfo } from './layers' + +export async function resolveLocaleInfo(ctx: I18nNuxtContext, nuxt: Nuxt) { + const { options, debug } = ctx + + /** + * resolve locale info + */ + const normalizedLocales = getNormalizedLocales(options.locales) + const localeCodes = normalizedLocales.map(locale => locale.code) + const localeInfo = await resolveLocales(nuxt.options.srcDir, normalizedLocales, nuxt.options.buildDir) + debug('localeInfo', localeInfo) + + /** + * resolve vue-i18n config path + */ + + const vueI18nConfigPaths = await resolveLayerVueI18nConfigInfo(options) + debug('VueI18nConfigPaths', vueI18nConfigPaths) + + ctx.normalizedLocales = normalizedLocales + ctx.localeCodes = localeCodes + ctx.localeInfo = localeInfo + ctx.vueI18nConfigPaths = vueI18nConfigPaths +} From a50a1b12cca9920ac523f6058728daa26756df7e Mon Sep 17 00:00:00 2001 From: userquin Date: Fri, 20 Sep 2024 16:50:24 +0200 Subject: [PATCH 2/4] chore: module only with context reference --- src/bundler.ts | 4 +- src/module.ts | 80 +++++------------------------------ src/nitro.ts | 9 ++-- src/pages.ts | 4 +- src/prepare-build-manifest.ts | 22 ++++++++++ src/prepare-layers.ts | 10 +++++ src/prepare-runtime.ts | 26 ++++++++++-- src/prepare-strategy.ts | 19 +++++++++ 8 files changed, 95 insertions(+), 79 deletions(-) create mode 100644 src/prepare-build-manifest.ts create mode 100644 src/prepare-layers.ts create mode 100644 src/prepare-strategy.ts diff --git a/src/bundler.ts b/src/bundler.ts index 5840cf6d4..8fd42eade 100644 --- a/src/bundler.ts +++ b/src/bundler.ts @@ -10,12 +10,12 @@ import { getLayerLangPaths } from './layers' import type { Nuxt } from '@nuxt/schema' import type { PluginOptions } from '@intlify/unplugin-vue-i18n' -import type { NuxtI18nOptions } from './types' import type { BundlerPluginOptions } from './transform/utils' +import type { I18nNuxtContext } from './context' const debug = createDebug('@nuxtjs/i18n:bundler') -export async function extendBundler(nuxt: Nuxt, nuxtOptions: Required) { +export async function extendBundler({ options: nuxtOptions }: I18nNuxtContext, nuxt: Nuxt) { const langPaths = getLayerLangPaths(nuxt) debug('langPaths -', langPaths) const i18nModulePaths = diff --git a/src/module.ts b/src/module.ts index 8d0b4dea6..d8bc1f072 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,14 +1,9 @@ -import { defineNuxtModule, addTypeTemplate } from '@nuxt/kit' -import { relative } from 'pathe' +import { defineNuxtModule } from '@nuxt/kit' import { setupAlias } from './alias' import { setupPages } from './pages' import { setupNitro } from './nitro' import { extendBundler } from './bundler' -import { generateI18nTypes } from './gen' import { NUXT_I18N_MODULE_ID, DEFAULT_OPTIONS } from './constants' -import { mergeI18nModules, getLocaleFiles, filterLocales } from './utils' -import { applyLayerOptions } from './layers' -import { i18nVirtualLoggerPlugin, RESOLVED_VIRTUAL_NUXT_I18N_LOGGER } from './virtual-logger' import type { HookResult } from '@nuxt/schema' import type { LocaleObject, NuxtI18nOptions } from './types' import type { Locale } from 'vue-i18n' @@ -18,6 +13,9 @@ import { resolveLocaleInfo } from './resolve-locale-info' import { prepareRuntime } from './prepare-runtime' import { prepareRuntimeConfig } from './prepare-runtime-config' import { prepareAutoImports } from './prepare-auto-imports' +import { prepareBuildManifest } from './prepare-build-manifest' +import { prepareStrategy } from './prepare-strategy' +import { prepareLayers } from './prepare-layers' export * from './types' @@ -34,8 +32,6 @@ export default defineNuxtModule({ async setup(i18nOptions, nuxt) { const ctx = createContext(i18nOptions, nuxt) - const { isSSG, options } = ctx - /** * Prepare options */ @@ -44,9 +40,7 @@ export default defineNuxtModule({ /** * nuxt layers handling ... */ - applyLayerOptions(options, nuxt) - await mergeI18nModules(options, nuxt) - filterLocales(options, nuxt) + await prepareLayers(ctx, nuxt) /** * setup runtime config @@ -59,32 +53,15 @@ export default defineNuxtModule({ */ await resolveLocaleInfo(ctx, nuxt) - const { normalizedLocales, localeInfo, localeCodes } = ctx - /** * setup nuxt/pages */ - if (localeCodes.length) { - setupPages(ctx, nuxt) - } + setupPages(ctx, nuxt) /** * ignore `/` during prerender when using prefixed routing */ - if (options.strategy === 'prefix' && isSSG) { - const localizedEntryPages = normalizedLocales.map(x => ['/', x.code].join('')) - nuxt.hook('nitro:config', config => { - config.prerender ??= {} - - // ignore `/` which is added by nitro by default - config.prerender.ignore ??= [] - config.prerender.ignore.push(/^\/$/) - - // add localized routes as entry pages for prerendering - config.prerender.routes ??= [] - config.prerender.routes.push(...localizedEntryPages) - }) - } + prepareStrategy(ctx, nuxt) /** * setup module alias @@ -96,59 +73,22 @@ export default defineNuxtModule({ */ prepareRuntime(ctx, nuxt) - nuxt.options.imports.transform ??= {} - nuxt.options.imports.transform.include ??= [] - nuxt.options.imports.transform.include.push(new RegExp(`${RESOLVED_VIRTUAL_NUXT_I18N_LOGGER}$`)) - - nuxt.hook('vite:extendConfig', cfg => { - // eslint-disable-next-line @typescript-eslint/no-floating-promises - cfg.plugins ||= [] - // @ts-ignore NOTE: A type error occurs due to a mismatch between Vite plugins and those of Rollup - cfg.plugins.push(i18nVirtualLoggerPlugin(options.debug)) - }) - - /** - * `$i18n` type narrowing based on 'legacy' or 'composition' - * `locales` type narrowing based on generated configuration - */ - addTypeTemplate({ - filename: 'types/i18n-plugin.d.ts', - getContents: () => generateI18nTypes(nuxt, i18nOptions) - }) - /** * disable preloading/prefetching lazy loaded locales */ - nuxt.hook('build:manifest', manifest => { - if (options.lazy) { - const langFiles = localeInfo - .flatMap(locale => getLocaleFiles(locale)) - .map(x => relative(nuxt.options.srcDir, x.path)) - const langPaths = [...new Set(langFiles)] - - for (const key in manifest) { - if (langPaths.some(x => key.startsWith(x))) { - manifest[key].prefetch = false - manifest[key].preload = false - } - } - } - }) + prepareBuildManifest(ctx, nuxt) /** * extend bundler */ - await extendBundler(nuxt, options) + await extendBundler(ctx, nuxt) /** * setup nitro */ - await setupNitro(ctx, nuxt, { - optionsCode: ctx.genTemplate(true, true), - localeInfo - }) + await setupNitro(ctx, nuxt) /** * auto imports diff --git a/src/nitro.ts b/src/nitro.ts index 398ee59df..f64cab386 100644 --- a/src/nitro.ts +++ b/src/nitro.ts @@ -31,14 +31,17 @@ type AdditionalSetupNitroParams = { } export async function setupNitro( - { isSSR, resolver, options: nuxtOptions }: I18nNuxtContext, - nuxt: Nuxt, - additionalParams: AdditionalSetupNitroParams + { genTemplate, isSSR, localeInfo, resolver, options: nuxtOptions }: I18nNuxtContext, + nuxt: Nuxt ) { const [enableServerIntegration, localeDetectionPath] = await resolveLocaleDetectorPath(nuxt) nuxt.hook('nitro:config', async nitroConfig => { if (enableServerIntegration) { + const additionalParams: AdditionalSetupNitroParams = { + optionsCode: genTemplate(true, true), + localeInfo + } // inline module runtime in Nitro bundle nitroConfig.externals = defu(typeof nitroConfig.externals === 'object' ? nitroConfig.externals : {}, { inline: [resolver.resolve('./runtime')] diff --git a/src/pages.ts b/src/pages.ts index fd4ac12ba..0b6a2cfc3 100644 --- a/src/pages.ts +++ b/src/pages.ts @@ -35,7 +35,9 @@ export type NuxtPageAnalyzeContext = { pages: Map } -export function setupPages({ options, isSSR }: I18nNuxtContext, nuxt: Nuxt) { +export function setupPages({ localeCodes, options, isSSR }: I18nNuxtContext, nuxt: Nuxt) { + if (!localeCodes.length) return + let includeUnprefixedFallback = !isSSR nuxt.hook('nitro:init', () => { debug('enable includeUprefixedFallback') diff --git a/src/prepare-build-manifest.ts b/src/prepare-build-manifest.ts new file mode 100644 index 000000000..d629295ca --- /dev/null +++ b/src/prepare-build-manifest.ts @@ -0,0 +1,22 @@ +import type { I18nNuxtContext } from './context' +import type { Nuxt } from '@nuxt/schema' +import { getLocaleFiles } from './utils' +import { relative } from 'pathe' + +export function prepareBuildManifest({ options, localeInfo }: I18nNuxtContext, nuxt: Nuxt) { + nuxt.hook('build:manifest', manifest => { + if (options.lazy) { + const langFiles = localeInfo + .flatMap(locale => getLocaleFiles(locale)) + .map(x => relative(nuxt.options.srcDir, x.path)) + const langPaths = [...new Set(langFiles)] + + for (const key in manifest) { + if (langPaths.some(x => key.startsWith(x))) { + manifest[key].prefetch = false + manifest[key].preload = false + } + } + } + }) +} diff --git a/src/prepare-layers.ts b/src/prepare-layers.ts new file mode 100644 index 000000000..e5e61dcdc --- /dev/null +++ b/src/prepare-layers.ts @@ -0,0 +1,10 @@ +import type { I18nNuxtContext } from '~/src/context' +import type { Nuxt } from '@nuxt/schema' +import { applyLayerOptions } from '~/src/layers' +import { filterLocales, mergeI18nModules } from '~/src/utils' + +export async function prepareLayers({ options }: I18nNuxtContext, nuxt: Nuxt) { + applyLayerOptions(options, nuxt) + await mergeI18nModules(options, nuxt) + filterLocales(options, nuxt) +} diff --git a/src/prepare-runtime.ts b/src/prepare-runtime.ts index 48be30160..f4a455cfa 100644 --- a/src/prepare-runtime.ts +++ b/src/prepare-runtime.ts @@ -1,10 +1,10 @@ import type { Nuxt } from '@nuxt/schema' import type { I18nNuxtContext } from './context' -import { VIRTUAL_NUXT_I18N_LOGGER } from './virtual-logger' +import { i18nVirtualLoggerPlugin, RESOLVED_VIRTUAL_NUXT_I18N_LOGGER, VIRTUAL_NUXT_I18N_LOGGER } from './virtual-logger' import { defu } from 'defu' -import { addPlugin, addTemplate } from '@nuxt/kit' +import { addPlugin, addTemplate, addTypeTemplate } from '@nuxt/kit' import { generateTemplateNuxtI18nOptions } from './template' -import { generateLoaderOptions, simplifyLocaleOptions } from './gen' +import { generateI18nTypes, generateLoaderOptions, simplifyLocaleOptions } from './gen' import { NUXT_I18N_TEMPLATE_OPTIONS_KEY } from './constants' export function prepareRuntime(ctx: I18nNuxtContext, nuxt: Nuxt) { @@ -48,4 +48,24 @@ export function prepareRuntime(ctx: I18nNuxtContext, nuxt: Nuxt) { write: true, getContents: () => genTemplate(false) }) + + nuxt.options.imports.transform ??= {} + nuxt.options.imports.transform.include ??= [] + nuxt.options.imports.transform.include.push(new RegExp(`${RESOLVED_VIRTUAL_NUXT_I18N_LOGGER}$`)) + + nuxt.hook('vite:extendConfig', cfg => { + // eslint-disable-next-line @typescript-eslint/no-floating-promises + cfg.plugins ||= [] + // @ts-ignore NOTE: A type error occurs due to a mismatch between Vite plugins and those of Rollup + cfg.plugins.push(i18nVirtualLoggerPlugin(options.debug)) + }) + + /** + * `$i18n` type narrowing based on 'legacy' or 'composition' + * `locales` type narrowing based on generated configuration + */ + addTypeTemplate({ + filename: 'types/i18n-plugin.d.ts', + getContents: () => generateI18nTypes(nuxt, ctx.userOptions) + }) } diff --git a/src/prepare-strategy.ts b/src/prepare-strategy.ts new file mode 100644 index 000000000..aa593643e --- /dev/null +++ b/src/prepare-strategy.ts @@ -0,0 +1,19 @@ +import type { I18nNuxtContext } from './context' +import type { Nuxt } from '@nuxt/schema' + +export function prepareStrategy({ options, isSSG, normalizedLocales }: I18nNuxtContext, nuxt: Nuxt) { + if (options.strategy === 'prefix' && isSSG) { + const localizedEntryPages = normalizedLocales.map(x => ['/', x.code].join('')) + nuxt.hook('nitro:config', config => { + config.prerender ??= {} + + // ignore `/` which is added by nitro by default + config.prerender.ignore ??= [] + config.prerender.ignore.push(/^\/$/) + + // add localized routes as entry pages for prerendering + config.prerender.routes ??= [] + config.prerender.routes.push(...localizedEntryPages) + }) + } +} From ead3d4d3aede1b18c45da075f2e58c9f2bb0456e Mon Sep 17 00:00:00 2001 From: userquin Date: Fri, 20 Sep 2024 17:01:06 +0200 Subject: [PATCH 3/4] chore: fix build --- src/prepare-layers.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/prepare-layers.ts b/src/prepare-layers.ts index e5e61dcdc..8c016eee0 100644 --- a/src/prepare-layers.ts +++ b/src/prepare-layers.ts @@ -1,7 +1,7 @@ -import type { I18nNuxtContext } from '~/src/context' +import type { I18nNuxtContext } from './context' import type { Nuxt } from '@nuxt/schema' -import { applyLayerOptions } from '~/src/layers' -import { filterLocales, mergeI18nModules } from '~/src/utils' +import { applyLayerOptions } from './layers' +import { filterLocales, mergeI18nModules } from './utils' export async function prepareLayers({ options }: I18nNuxtContext, nuxt: Nuxt) { applyLayerOptions(options, nuxt) From 184159e1f263a821e3eb15d5a6524d01cea48ccb Mon Sep 17 00:00:00 2001 From: userquin Date: Fri, 20 Sep 2024 17:16:12 +0200 Subject: [PATCH 4/4] chore: move all prepare modules to prepare folder --- src/module.ts | 29 ++++++++----------- .../auto-imports.ts} | 6 ++-- .../build-manifest.ts} | 4 +-- src/{prepare-layers.ts => prepare/layers.ts} | 6 ++-- .../locale-info.ts} | 6 ++-- .../options.ts} | 6 ++-- .../runtime-config.ts} | 4 +-- .../runtime.ts} | 10 +++---- .../strategy.ts} | 2 +- src/prepare/transpile.ts | 7 +++++ src/prepare/vite.ts | 8 +++++ 11 files changed, 49 insertions(+), 39 deletions(-) rename src/{prepare-auto-imports.ts => prepare/auto-imports.ts} (91%) rename src/{prepare-build-manifest.ts => prepare/build-manifest.ts} (87%) rename src/{prepare-layers.ts => prepare/layers.ts} (59%) rename src/{resolve-locale-info.ts => prepare/locale-info.ts} (82%) rename src/{prepare-options.ts => prepare/options.ts} (89%) rename src/{prepare-runtime-config.ts => prepare/runtime-config.ts} (91%) rename src/{prepare-runtime.ts => prepare/runtime.ts} (90%) rename src/{prepare-strategy.ts => prepare/strategy.ts} (92%) create mode 100644 src/prepare/transpile.ts create mode 100644 src/prepare/vite.ts diff --git a/src/module.ts b/src/module.ts index d8bc1f072..8a5ffe557 100644 --- a/src/module.ts +++ b/src/module.ts @@ -8,14 +8,16 @@ import type { HookResult } from '@nuxt/schema' import type { LocaleObject, NuxtI18nOptions } from './types' import type { Locale } from 'vue-i18n' import { createContext } from './context' -import { prepareOptions } from './prepare-options' -import { resolveLocaleInfo } from './resolve-locale-info' -import { prepareRuntime } from './prepare-runtime' -import { prepareRuntimeConfig } from './prepare-runtime-config' -import { prepareAutoImports } from './prepare-auto-imports' -import { prepareBuildManifest } from './prepare-build-manifest' -import { prepareStrategy } from './prepare-strategy' -import { prepareLayers } from './prepare-layers' +import { prepareOptions } from './prepare/options' +import { resolveLocaleInfo } from './prepare/locale-info' +import { prepareRuntime } from './prepare/runtime' +import { prepareRuntimeConfig } from './prepare/runtime-config' +import { prepareAutoImports } from './prepare/auto-imports' +import { prepareBuildManifest } from './prepare/build-manifest' +import { prepareStrategy } from './prepare/strategy' +import { prepareLayers } from './prepare/layers' +import { prepareTranspile } from './prepare/transpile' +import { prepareVite } from './prepare/vite' export * from './types' @@ -98,19 +100,12 @@ export default defineNuxtModule({ /** * transpile @nuxtjs/i18n */ - - // https://github.com/nuxt/framework/issues/5257 - nuxt.options.build.transpile.push('@nuxtjs/i18n') - nuxt.options.build.transpile.push('@nuxtjs/i18n-edge') + prepareTranspile(nuxt) /** * Optimize deps */ - - // Optimize vue-i18n to ensure we share the same symbol - nuxt.options.vite.optimizeDeps = nuxt.options.vite.optimizeDeps || {} - nuxt.options.vite.optimizeDeps.exclude = nuxt.options.vite.optimizeDeps.exclude || [] - nuxt.options.vite.optimizeDeps.exclude.push('vue-i18n') + prepareVite(nuxt) } }) diff --git a/src/prepare-auto-imports.ts b/src/prepare/auto-imports.ts similarity index 91% rename from src/prepare-auto-imports.ts rename to src/prepare/auto-imports.ts index 04b89711c..594a32d7a 100644 --- a/src/prepare-auto-imports.ts +++ b/src/prepare/auto-imports.ts @@ -4,11 +4,11 @@ import { NUXT_I18N_COMPOSABLE_DEFINE_LOCALE, NUXT_I18N_COMPOSABLE_DEFINE_ROUTE, VUE_I18N_PKG -} from './constants' +} from '../constants' import { addComponent, addImports } from '@nuxt/kit' import { resolve } from 'pathe' -import { runtimeDir } from './dirs' -import type { I18nNuxtContext } from './context' +import { runtimeDir } from '../dirs' +import type { I18nNuxtContext } from '../context' export async function prepareAutoImports({ debug }: I18nNuxtContext, nuxt: Nuxt) { const vueI18nPath = nuxt.options.alias[VUE_I18N_PKG] diff --git a/src/prepare-build-manifest.ts b/src/prepare/build-manifest.ts similarity index 87% rename from src/prepare-build-manifest.ts rename to src/prepare/build-manifest.ts index d629295ca..17b8c293c 100644 --- a/src/prepare-build-manifest.ts +++ b/src/prepare/build-manifest.ts @@ -1,6 +1,6 @@ -import type { I18nNuxtContext } from './context' +import type { I18nNuxtContext } from '../context' import type { Nuxt } from '@nuxt/schema' -import { getLocaleFiles } from './utils' +import { getLocaleFiles } from '../utils' import { relative } from 'pathe' export function prepareBuildManifest({ options, localeInfo }: I18nNuxtContext, nuxt: Nuxt) { diff --git a/src/prepare-layers.ts b/src/prepare/layers.ts similarity index 59% rename from src/prepare-layers.ts rename to src/prepare/layers.ts index 8c016eee0..98fabb0fe 100644 --- a/src/prepare-layers.ts +++ b/src/prepare/layers.ts @@ -1,7 +1,7 @@ -import type { I18nNuxtContext } from './context' +import type { I18nNuxtContext } from '../context' import type { Nuxt } from '@nuxt/schema' -import { applyLayerOptions } from './layers' -import { filterLocales, mergeI18nModules } from './utils' +import { applyLayerOptions } from '../layers' +import { filterLocales, mergeI18nModules } from '../utils' export async function prepareLayers({ options }: I18nNuxtContext, nuxt: Nuxt) { applyLayerOptions(options, nuxt) diff --git a/src/resolve-locale-info.ts b/src/prepare/locale-info.ts similarity index 82% rename from src/resolve-locale-info.ts rename to src/prepare/locale-info.ts index ad718a150..b43fe8584 100644 --- a/src/resolve-locale-info.ts +++ b/src/prepare/locale-info.ts @@ -1,7 +1,7 @@ -import type { I18nNuxtContext } from './context' +import type { I18nNuxtContext } from '../context' import type { Nuxt } from '@nuxt/schema' -import { getNormalizedLocales, resolveLocales } from './utils' -import { resolveLayerVueI18nConfigInfo } from './layers' +import { getNormalizedLocales, resolveLocales } from '../utils' +import { resolveLayerVueI18nConfigInfo } from '../layers' export async function resolveLocaleInfo(ctx: I18nNuxtContext, nuxt: Nuxt) { const { options, debug } = ctx diff --git a/src/prepare-options.ts b/src/prepare/options.ts similarity index 89% rename from src/prepare-options.ts rename to src/prepare/options.ts index 0129ceb7e..bdc9d30ef 100644 --- a/src/prepare-options.ts +++ b/src/prepare/options.ts @@ -1,7 +1,7 @@ -import type { I18nNuxtContext } from './context' +import type { I18nNuxtContext } from '../context' import type { Nuxt } from '@nuxt/schema' -import { applyOptionOverrides, formatMessage } from './utils' -import { checkLayerOptions } from './layers' +import { applyOptionOverrides, formatMessage } from '../utils' +import { checkLayerOptions } from '../layers' export function prepareOptions({ debug, logger, options }: I18nNuxtContext, nuxt: Nuxt) { applyOptionOverrides(options, nuxt) diff --git a/src/prepare-runtime-config.ts b/src/prepare/runtime-config.ts similarity index 91% rename from src/prepare-runtime-config.ts rename to src/prepare/runtime-config.ts index 5bc8440c9..f200cd89d 100644 --- a/src/prepare-runtime-config.ts +++ b/src/prepare/runtime-config.ts @@ -1,6 +1,6 @@ -import type { I18nNuxtContext } from './context' +import type { I18nNuxtContext } from '../context' import type { Nuxt } from '@nuxt/schema' -import { DEFAULT_OPTIONS } from './constants' +import { DEFAULT_OPTIONS } from '../constants' import { defu } from 'defu' export function prepareRuntimeConfig({ options }: I18nNuxtContext, nuxt: Nuxt) { diff --git a/src/prepare-runtime.ts b/src/prepare/runtime.ts similarity index 90% rename from src/prepare-runtime.ts rename to src/prepare/runtime.ts index f4a455cfa..497dfd990 100644 --- a/src/prepare-runtime.ts +++ b/src/prepare/runtime.ts @@ -1,11 +1,11 @@ import type { Nuxt } from '@nuxt/schema' -import type { I18nNuxtContext } from './context' -import { i18nVirtualLoggerPlugin, RESOLVED_VIRTUAL_NUXT_I18N_LOGGER, VIRTUAL_NUXT_I18N_LOGGER } from './virtual-logger' +import type { I18nNuxtContext } from '../context' +import { i18nVirtualLoggerPlugin, RESOLVED_VIRTUAL_NUXT_I18N_LOGGER, VIRTUAL_NUXT_I18N_LOGGER } from '../virtual-logger' import { defu } from 'defu' import { addPlugin, addTemplate, addTypeTemplate } from '@nuxt/kit' -import { generateTemplateNuxtI18nOptions } from './template' -import { generateI18nTypes, generateLoaderOptions, simplifyLocaleOptions } from './gen' -import { NUXT_I18N_TEMPLATE_OPTIONS_KEY } from './constants' +import { generateTemplateNuxtI18nOptions } from '../template' +import { generateI18nTypes, generateLoaderOptions, simplifyLocaleOptions } from '../gen' +import { NUXT_I18N_TEMPLATE_OPTIONS_KEY } from '../constants' export function prepareRuntime(ctx: I18nNuxtContext, nuxt: Nuxt) { const { isDev: dev, isSSG, localeCodes, localeInfo, normalizedLocales, options, resolver, vueI18nConfigPaths } = ctx diff --git a/src/prepare-strategy.ts b/src/prepare/strategy.ts similarity index 92% rename from src/prepare-strategy.ts rename to src/prepare/strategy.ts index aa593643e..487e93878 100644 --- a/src/prepare-strategy.ts +++ b/src/prepare/strategy.ts @@ -1,4 +1,4 @@ -import type { I18nNuxtContext } from './context' +import type { I18nNuxtContext } from '../context' import type { Nuxt } from '@nuxt/schema' export function prepareStrategy({ options, isSSG, normalizedLocales }: I18nNuxtContext, nuxt: Nuxt) { diff --git a/src/prepare/transpile.ts b/src/prepare/transpile.ts new file mode 100644 index 000000000..1e927f7f6 --- /dev/null +++ b/src/prepare/transpile.ts @@ -0,0 +1,7 @@ +import type { Nuxt } from '@nuxt/schema' + +export function prepareTranspile(nuxt: Nuxt) { + // https://github.com/nuxt/framework/issues/5257 + nuxt.options.build.transpile.push('@nuxtjs/i18n') + nuxt.options.build.transpile.push('@nuxtjs/i18n-edge') +} diff --git a/src/prepare/vite.ts b/src/prepare/vite.ts new file mode 100644 index 000000000..c7b3196ca --- /dev/null +++ b/src/prepare/vite.ts @@ -0,0 +1,8 @@ +import type { Nuxt } from '@nuxt/schema' + +export function prepareVite(nuxt: Nuxt) { + // Optimize vue-i18n to ensure we share the same symbol + nuxt.options.vite.optimizeDeps = nuxt.options.vite.optimizeDeps || {} + nuxt.options.vite.optimizeDeps.exclude = nuxt.options.vite.optimizeDeps.exclude || [] + nuxt.options.vite.optimizeDeps.exclude.push('vue-i18n') +}