From 71e45644257c7a5164da8b69767c1f853c101e97 Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Mon, 19 Aug 2024 15:24:36 +0200 Subject: [PATCH 1/5] feat: runtime logger and debug verbose --- docs/content/docs/3.options/10.misc.md | 4 +- docs/content/docs/5.v9/3.options/10.misc.md | 4 +- pnpm-lock.yaml | 72 --------------------- src/env.d.ts | 2 +- src/runtime/internal.ts | 54 ++++++---------- src/runtime/messages.ts | 27 ++++++-- src/runtime/plugins/i18n.ts | 35 ++++++---- src/runtime/utils.ts | 46 ++++++------- src/types.ts | 2 +- 9 files changed, 93 insertions(+), 153 deletions(-) diff --git a/docs/content/docs/3.options/10.misc.md b/docs/content/docs/3.options/10.misc.md index 0e38a8126..967a79371 100644 --- a/docs/content/docs/3.options/10.misc.md +++ b/docs/content/docs/3.options/10.misc.md @@ -47,10 +47,10 @@ If it can not detect Nuxt configuration changing, you may need to run `nuxi prep ## `debug` -- type: `boolean` +- type: `boolean | 'verbose'` - default: `false` -Whether to use `@nuxtjs/i18n` debug mode. If `true`, logs will be output to the console. +Whether to use `@nuxtjs/i18n` debug mode. If `true` or `'verbose'`, logs will be output to the console, setting this to `'verbose'` will also log loaded messages objects. ::callout{icon="i-heroicons-exclamation-triangle" color="amber"} The purpose of this option is to help identify any problems with `@nuxtjs/i18n`. diff --git a/docs/content/docs/5.v9/3.options/10.misc.md b/docs/content/docs/5.v9/3.options/10.misc.md index bea0fa486..ae80b53bb 100644 --- a/docs/content/docs/5.v9/3.options/10.misc.md +++ b/docs/content/docs/5.v9/3.options/10.misc.md @@ -47,10 +47,10 @@ If it can not detect Nuxt configuration changing, you may need to run `nuxi prep ## `debug` -- type: `boolean` +- type: `boolean | 'verbose'` - default: `false` -Whether to use `@nuxtjs/i18n` debug mode. If `true`, logs will be output to the console. +Whether to use `@nuxtjs/i18n` debug mode. If `true` or `'verbose'`, logs will be output to the console, setting this to `'verbose'` will also log loaded messages objects. ::callout{icon="i-heroicons-exclamation-triangle" color="amber"} The purpose of this option is to help identify any problems with `@nuxtjs/i18n`. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 971e2a591..5c2ac0803 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -274,78 +274,6 @@ importers: specifier: latest version: 3.12.4(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.9)(encoding@0.1.13)(eslint@9.5.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.18.0)(terser@5.31.1)(typescript@5.5.2)(vite@5.3.5(@types/node@20.14.9)(terser@5.31.1))(vue-tsc@2.0.22(typescript@5.5.2)) - specs/fixtures/issues/1888: - devDependencies: - '@nuxtjs/i18n': - specifier: link:../../../.. - version: link:../../../.. - nuxt: - specifier: latest - version: 3.12.4(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.9)(encoding@0.1.13)(eslint@9.5.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.18.0)(terser@5.31.1)(typescript@5.5.2)(vite@5.3.5(@types/node@20.14.9)(terser@5.31.1))(vue-tsc@2.0.22(typescript@5.5.2)) - - specs/fixtures/issues/2151: - devDependencies: - '@nuxtjs/i18n': - specifier: link:../../../.. - version: link:../../../.. - nuxt: - specifier: latest - version: 3.12.4(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.9)(encoding@0.1.13)(eslint@9.5.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.18.0)(terser@5.31.1)(typescript@5.5.2)(vite@5.3.5(@types/node@20.14.9)(terser@5.31.1))(vue-tsc@2.0.22(typescript@5.5.2)) - - specs/fixtures/issues/2220: - devDependencies: - '@nuxtjs/i18n': - specifier: link:../../../.. - version: link:../../../.. - nuxt: - specifier: latest - version: 3.12.4(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.9)(encoding@0.1.13)(eslint@9.5.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.18.0)(terser@5.31.1)(typescript@5.5.2)(vite@5.3.5(@types/node@20.14.9)(terser@5.31.1))(vue-tsc@2.0.22(typescript@5.5.2)) - - specs/fixtures/issues/2226: - devDependencies: - '@nuxtjs/i18n': - specifier: link:../../../.. - version: link:../../../.. - nuxt: - specifier: latest - version: 3.12.4(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.9)(encoding@0.1.13)(eslint@9.5.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.18.0)(terser@5.31.1)(typescript@5.5.2)(vite@5.3.5(@types/node@20.14.9)(terser@5.31.1))(vue-tsc@2.0.22(typescript@5.5.2)) - - specs/fixtures/issues/2247: - devDependencies: - '@nuxtjs/i18n': - specifier: link:../../../.. - version: link:../../../.. - nuxt: - specifier: latest - version: 3.12.4(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.9)(encoding@0.1.13)(eslint@9.5.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.18.0)(terser@5.31.1)(typescript@5.5.2)(vite@5.3.5(@types/node@20.14.9)(terser@5.31.1))(vue-tsc@2.0.22(typescript@5.5.2)) - - specs/fixtures/issues/2288: - devDependencies: - '@nuxtjs/i18n': - specifier: link:../../../.. - version: link:../../../.. - nuxt: - specifier: latest - version: 3.12.4(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.9)(encoding@0.1.13)(eslint@9.5.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.18.0)(terser@5.31.1)(typescript@5.5.2)(vite@5.3.5(@types/node@20.14.9)(terser@5.31.1))(vue-tsc@2.0.22(typescript@5.5.2)) - - specs/fixtures/issues/2315: - devDependencies: - '@nuxtjs/i18n': - specifier: link:../../../.. - version: link:../../../.. - nuxt: - specifier: latest - version: 3.12.4(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.9)(encoding@0.1.13)(eslint@9.5.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.18.0)(terser@5.31.1)(typescript@5.5.2)(vite@5.3.5(@types/node@20.14.9)(terser@5.31.1))(vue-tsc@2.0.22(typescript@5.5.2)) - - specs/fixtures/issues/2590: - devDependencies: - '@nuxtjs/i18n': - specifier: link:../../../.. - version: link:../../../.. - nuxt: - specifier: latest - version: 3.12.4(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.9)(encoding@0.1.13)(eslint@9.5.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.18.0)(terser@5.31.1)(typescript@5.5.2)(vite@5.3.5(@types/node@20.14.9)(terser@5.31.1))(vue-tsc@2.0.22(typescript@5.5.2)) - specs/fixtures/lazy: devDependencies: '@nuxtjs/i18n': diff --git a/src/env.d.ts b/src/env.d.ts index 64eb2139b..b84d7eee7 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -4,4 +4,4 @@ declare namespace NodeJS { } } -declare let __DEBUG__: boolean +declare let __DEBUG__: boolean | 'verbose' diff --git a/src/runtime/internal.ts b/src/runtime/internal.ts index 5eaa7afcc..339cf7f10 100644 --- a/src/runtime/internal.ts +++ b/src/runtime/internal.ts @@ -49,20 +49,21 @@ export function parseAcceptLanguage(input: string): string[] { export function getBrowserLocale(): string | undefined { let ret: string | undefined + const logger = createLogger('getBrowserLocale') if (import.meta.client) { if (navigator.languages) { // get browser language either from navigator if running on client side, or from the headers ret = findBrowserLocale(normalizedLocales, navigator.languages as string[]) - __DEBUG__ && console.log('getBrowserLocale (navigator.languages, ret) -', navigator.languages, ret) + __DEBUG__ && logger.log('(navigator.languages, ret) -', navigator.languages, ret) } } else if (import.meta.server) { const header = useRequestHeaders(['accept-language']) - __DEBUG__ && console.log('getBrowserLocale accept-language', header) + __DEBUG__ && logger.log('accept-language', header) const accept = header['accept-language'] if (accept) { ret = findBrowserLocale(normalizedLocales, parseAcceptLanguage(accept)) - __DEBUG__ && console.log('getBrowserLocale ret', ret) + __DEBUG__ && logger.log('ret', ret) } } @@ -92,8 +93,10 @@ export function getLocaleCookie( detect: false | DetectBrowserLanguageOptions, defaultLocale: string ): string | undefined { + const env = import.meta.client ? 'client' : 'server' + const logger = createLogger(`getLocaleCookie:${env}`) __DEBUG__ && - console.log('getLocaleCookie', { + logger.log({ useCookie: detect && detect.useCookie, cookieKey: detect && detect.cookieKey, localeCodes @@ -104,27 +107,23 @@ export function getLocaleCookie( } const localeCode: string | undefined = cookieRef.value ?? undefined - const env = import.meta.client ? 'client' : 'server' if (localeCode == null) { - __DEBUG__ && console.log(`getLocaleCookie (${env}) - none`) + __DEBUG__ && logger.log(`none`) return } if (localeCodes.includes(localeCode)) { - __DEBUG__ && console.log(`getLocaleCookie (${env}) - locale from cookie: `, localeCode) + __DEBUG__ && logger.log(`locale from cookie: `, localeCode) return localeCode } if (defaultLocale) { - __DEBUG__ && - console.log( - `getLocaleCookie (${env}) - unknown locale cookie (${localeCode}), setting to defaultLocale (${defaultLocale})` - ) + __DEBUG__ && logger.log(`unknown locale cookie (${localeCode}), setting to defaultLocale (${defaultLocale})`) cookieRef.value = defaultLocale return defaultLocale } - __DEBUG__ && console.log(`getLocaleCookie (${env}) - unknown locale cookie (${localeCode}), unsetting cookie`) + __DEBUG__ && logger.log(`unknown locale cookie (${localeCode}), unsetting cookie`) cookieRef.value = undefined return } @@ -271,15 +270,13 @@ export function getLocaleDomain( strategy: string, route: string | RouteLocationNormalized | RouteLocationNormalizedLoaded ): string { + const logger = createLogger(`getLocaleDomain`) let host = getHost() || '' + const routePath = isObject(route) ? route.path : isString(route) ? route : '' + if (host) { - __DEBUG__ && - console.log( - `MultiDomainsMultiLocales: locating domain for host: `, - host, - strategy, - isObject(route) ? route.path : route - ) + __DEBUG__ && logger.log(`locating domain for host`, { host, strategy, path: routePath }) + let matchingLocale: LocaleObject | undefined const matchingLocales = locales.filter(locale => { if (locale && locale.domain) { @@ -296,8 +293,7 @@ export function getLocaleDomain( if (matchingLocales.length === 1) { matchingLocale = matchingLocales[0] - __DEBUG__ && - console.log(`MultiDomainsMultiLocales: found only one matching domain: `, host, matchingLocales[0].code) + __DEBUG__ && logger.log(`found one matching domain`, { host, matchedLocale: matchingLocales[0].code }) } else if (matchingLocales.length > 1) { if (strategy === 'no_prefix') { console.warn( @@ -310,20 +306,13 @@ export function getLocaleDomain( } else { // get prefix from route if (route) { - const routePath = isObject(route) ? route.path : isString(route) ? route : '' - - __DEBUG__ && - console.log(`MultiDomainsMultiLocales: Check in matched domain for locale match in path: `, routePath, host) + __DEBUG__ && logger.log(`check matched domain for locale match`, { path: routePath, host }) if (routePath && routePath !== '') { const matches = routePath.match(getLocalesRegex(matchingLocales.map(l => l.code))) if (matches && matches.length > 1) { matchingLocale = matchingLocales.find(l => l.code === matches[1]) - __DEBUG__ && - console.log( - `MultiDomainsMultiLocales: Found matching locale from path. MatchingLocale is now`, - matchingLocale?.code - ) + __DEBUG__ && logger.log(`matched locale from path`, { matchedLocale: matchingLocale?.code }) } } } @@ -334,10 +323,7 @@ export function getLocaleDomain( Array.isArray(l.defaultForDomains) ? l.defaultForDomains.includes(host) : l.domainDefault ) __DEBUG__ && - console.log( - `MultiDomainsMultiLocales: matching locale not found - trying to get default for this domain. MatchingLocale is now`, - matchingLocale?.code - ) + logger.log(`no locale matched - using default for this domain`, { matchedLocale: matchingLocale?.code }) } } } diff --git a/src/runtime/messages.ts b/src/runtime/messages.ts index c91e448d8..6dfaf2b80 100644 --- a/src/runtime/messages.ts +++ b/src/runtime/messages.ts @@ -14,6 +14,19 @@ export type LocaleLoader> = { load: () => Promise> cache: boolean } + +/** + * Used for runtime debug logs only, cannot be imported due to + * this being a virtual file in both nuxt and nitro contexts + * + * NOTE: We could export the logger from a virtual file instead + */ +function createLogger(label: string) { + return { + log: console.log.bind(console, `[i18n:${label}]`) + } +} + const cacheMessages = new Map>() export async function loadVueI18nOptions( @@ -75,19 +88,20 @@ export async function loadInitialMessages( } async function loadMessage(locale: Locale, { key, load }: LocaleLoader) { + const logger = createLogger('loadMessage') let message: LocaleMessages | null = null try { - __DEBUG__ && console.log('loadMessage: (locale) -', locale) + __DEBUG__ && logger.log({ locale }) const getter = await load().then(r => ('default' in r ? r.default : r)) if (isFunction(getter)) { message = await getter(locale) - __DEBUG__ && console.log('loadMessage: dynamic load', message) + __DEBUG__ && logger.log('dynamic load', __DEBUG__ === 'verbose' ? message : '') } else { message = getter if (message != null && cacheMessages) { cacheMessages.set(key, message) } - __DEBUG__ && console.log('loadMessage: load', message) + __DEBUG__ && logger.log('loaded', __DEBUG__ === 'verbose' ? message : '') } } catch (e: unknown) { console.error('Failed locale loading: ' + (e as Error).message) @@ -100,6 +114,7 @@ export async function loadLocale( localeLoaders: Record, setter: (locale: Locale, message: LocaleMessages) => void ) { + const logger = createLogger('loadLocale') const loaders = localeLoaders[locale] if (loaders == null) { @@ -112,11 +127,11 @@ export async function loadLocale( let message: LocaleMessages | undefined | null = null if (cacheMessages && cacheMessages.has(loader.key) && loader.cache) { - __DEBUG__ && console.log(loader.key + ' is already loaded') + __DEBUG__ && logger.log(loader.key + ' is already loaded') message = cacheMessages.get(loader.key) } else { - __DEBUG__ && !loader.cache && console.log(loader.key + ' bypassing cache!') - __DEBUG__ && console.log(loader.key + ' is loading ...') + __DEBUG__ && !loader.cache && logger.log(loader.key + ' bypassing cache!') + __DEBUG__ && logger.log(loader.key + ' is loading ...') message = await loadMessage(locale, loader) } diff --git a/src/runtime/plugins/i18n.ts b/src/runtime/plugins/i18n.ts index 3e0b7226b..4461cace7 100644 --- a/src/runtime/plugins/i18n.ts +++ b/src/runtime/plugins/i18n.ts @@ -18,7 +18,15 @@ import { type LocaleObject } from '#build/i18n.options.mjs' import { loadVueI18nOptions, loadInitialMessages, loadLocale } from '../messages' -import { loadAndSetLocale, detectLocale, detectRedirect, navigate, injectNuxtHelpers, extendBaseUrl } from '../utils' +import { + loadAndSetLocale, + detectLocale, + detectRedirect, + navigate, + injectNuxtHelpers, + extendBaseUrl, + createLogger +} from '../utils' import { getBrowserLocale, getLocaleCookie, @@ -47,6 +55,7 @@ export default defineNuxtPlugin({ name: 'i18n:plugin', parallel: parallelPlugin, async setup(nuxt) { + const logger = createLogger('plugin:i18n') const route = useRoute() const { vueApp: app } = nuxt const nuxtContext = nuxt as unknown as NuxtApp @@ -92,9 +101,9 @@ export default defineNuxtPlugin({ const _detectBrowserLanguage = runtimeDetectBrowserLanguage() - __DEBUG__ && console.log('isSSG', isSSG) - __DEBUG__ && console.log('useCookie on setup', _detectBrowserLanguage && _detectBrowserLanguage.useCookie) - __DEBUG__ && console.log('defaultLocale on setup', runtimeI18n.defaultLocale) + __DEBUG__ && logger.log('isSSG', isSSG) + __DEBUG__ && logger.log('useCookie on setup', _detectBrowserLanguage && _detectBrowserLanguage.useCookie) + __DEBUG__ && logger.log('defaultLocale on setup', runtimeI18n.defaultLocale) const vueI18nOptions: I18nOptions = await loadVueI18nOptions(vueI18nConfigs, useNuxtApp()) vueI18nOptions.messages = vueI18nOptions.messages || {} @@ -117,7 +126,7 @@ export default defineNuxtPlugin({ }, runtimeI18n ) - __DEBUG__ && console.log('first detect initial locale', initialLocale) + __DEBUG__ && logger.log('first detect initial locale', initialLocale) // load initial vue-i18n locale messages vueI18nOptions.messages = await loadInitialMessages(vueI18nOptions.messages, localeLoaders, { @@ -134,7 +143,7 @@ export default defineNuxtPlugin({ * It means a mode that works only with simple vue-i18n, without nuxtjs/i18n routing, browser detection, SEO, and other features. */ initialLocale = getDefaultLocale(initialLocale) - __DEBUG__ && console.log('final initial locale:', initialLocale) + __DEBUG__ && logger.log('final initial locale:', initialLocale) // create i18n instance const i18n = createI18n({ ...vueI18nOptions, locale: initialLocale }) @@ -151,7 +160,7 @@ export default defineNuxtPlugin({ */ if (isSSGModeInitialSetup() && runtimeI18n.strategy === 'no_prefix' && import.meta.client) { nuxt.hook('app:mounted', async () => { - __DEBUG__ && console.log('hook app:mounted') + __DEBUG__ && logger.log('hook app:mounted') const detected = detectBrowserLanguage( route, { @@ -162,7 +171,7 @@ export default defineNuxtPlugin({ }, initialLocale ) - __DEBUG__ && console.log('app:mounted: detectBrowserLanguage (locale, reason, from) -', Object.values(detected)) + __DEBUG__ && logger.log('app:mounted: detectBrowserLanguage (locale, reason, from) -', Object.values(detected)) await setLocale(i18n, detected.locale) ssgModeInitialSetup = false }) @@ -211,7 +220,7 @@ export default defineNuxtPlugin({ routeLocaleGetter: getLocaleFromRoute }) ) - __DEBUG__ && console.log('redirectPath on setLocale', redirectPath) + __DEBUG__ && logger.log('redirectPath on setLocale', redirectPath) await nuxtContext.runWithContext( async () => @@ -338,7 +347,7 @@ export default defineNuxtPlugin({ 'locale-changing', defineNuxtRouteMiddleware(async (to, from) => { - __DEBUG__ && console.log('locale-changing middleware', to, from) + __DEBUG__ && logger.log('locale-changing middleware', to, from) const locale = detectLocale( to, @@ -354,10 +363,10 @@ export default defineNuxtPlugin({ }, runtimeI18n ) - __DEBUG__ && console.log('detect locale', locale) + __DEBUG__ && logger.log('detect locale', locale) const localeSetup = isInitialLocaleSetup(locale) - __DEBUG__ && console.log('localeSetup', localeSetup) + __DEBUG__ && logger.log('localeSetup', localeSetup) const modified = await loadAndSetLocale(locale, i18n, runtimeI18n, localeSetup) @@ -373,7 +382,7 @@ export default defineNuxtPlugin({ calledWithRouting: true }) ) - __DEBUG__ && console.log('redirectPath on locale-changing middleware', redirectPath) + __DEBUG__ && logger.log('redirectPath on locale-changing middleware', redirectPath) routeChangeCount++ diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index a3a7f35e7..436dff000 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -80,6 +80,7 @@ export async function loadAndSetLocale( runtimeI18n: ModulePublicRuntimeConfig['i18n'], initial: boolean = false ): Promise { + const logger = createLogger('loadAndSetLocale') const { differentDomains, skipSettingLocaleOnNavigate, lazy } = runtimeI18n const opts = runtimeDetectBrowserLanguage(runtimeI18n) const nuxtApp = useNuxtApp() @@ -95,7 +96,7 @@ export async function loadAndSetLocale( setLocaleCookie(i18n, locale) } - __DEBUG__ && console.log('setLocale: new -> ', newLocale, ' old -> ', oldLocale, ' initial -> ', initial) + __DEBUG__ && logger.log({ newLocale, oldLocale, initial }) // `newLocale` is unset or empty if (!newLocale) { @@ -158,9 +159,7 @@ type LocaleLoader = () => Locale */ export function createLogger(label: string) { return { - log: console.log.bind(console, `${label}:`) - // change to this after implementing logger across runtime code - // log: console.log.bind(console, `[i18n:${label}]`) + log: console.log.bind(console, `[i18n:${label}]`) } } @@ -227,10 +226,10 @@ export function detectRedirect({ }): string { const nuxtApp = useNuxtApp() const common = initCommonComposableOptions() + const logger = createLogger('detectRedirect') const { strategy, differentDomains } = common.runtimeConfig.public.i18n - __DEBUG__ && console.log('detectRedirect: targetLocale -> ', targetLocale) - __DEBUG__ && console.log('detectRedirect: route -> ', route) - __DEBUG__ && console.log('detectRedirect: calledWithRouting -> ', calledWithRouting, routeLocaleGetter(route.to)) + __DEBUG__ && logger.log({ route }) + __DEBUG__ && logger.log({ targetLocale, calledWithRouting, routeLocaleGetter: routeLocaleGetter(route.to) }) let redirectPath = '' const { fullPath: toFullPath } = route.to @@ -251,7 +250,7 @@ export function detectRedirect({ ) { // the current route could be 404 in which case attempt to find matching route using the full path const routePath = nuxtApp.$switchLocalePath(targetLocale) || nuxtApp.$localePath(toFullPath, targetLocale) - __DEBUG__ && console.log('detectRedirect: calculate routePath -> ', routePath, toFullPath) + __DEBUG__ && logger.log('calculate routePath', { routePath, toFullPath }) if (isString(routePath) && routePath && !isEqual(routePath, toFullPath) && !routePath.startsWith('//')) { /** * NOTE: for #1889, #2226 @@ -272,7 +271,7 @@ export function detectRedirect({ * let it be processed by the route of the router middleware. */ const routePath = switchLocalePath(common, targetLocale, route.to) - __DEBUG__ && console.log('detectRedirect: calculate domain or ssg routePath -> ', routePath) + __DEBUG__ && logger.log('calculate domain or ssg routePath', { routePath }) if (isString(routePath) && routePath && !isEqual(routePath, toFullPath) && !routePath.startsWith('//')) { redirectPath = routePath } @@ -307,18 +306,18 @@ export async function navigate( const { nuxtApp, i18n, locale, route } = args const { rootRedirect, differentDomains, multiDomainLocales, skipSettingLocaleOnNavigate, configLocales, strategy } = nuxtApp.$config.public.i18n + const logger = createLogger('navigate') let { redirectPath } = args __DEBUG__ && - console.log( - 'navigate options ', + logger.log('options', { status, rootRedirect, differentDomains, skipSettingLocaleOnNavigate, - enableNavigate - ) - __DEBUG__ && console.log('navigate isSSG', isSSG) + enableNavigate, + isSSG + }) if (route.path === '/' && rootRedirect) { if (isString(rootRedirect)) { @@ -328,7 +327,7 @@ export async function navigate( status = rootRedirect.statusCode } redirectPath = nuxtApp.$localePath(redirectPath, locale) - __DEBUG__ && console.log('navigate: rootRedirect mode redirectPath -> ', redirectPath, ' status -> ', status) + __DEBUG__ && logger.log('rootRedirect mode', { redirectPath, status }) return _navigate(redirectPath, status) } @@ -377,13 +376,13 @@ export async function navigate( } } else { const state = useRedirectState() - __DEBUG__ && console.log('redirect state ->', state.value, 'redirectPath -> ', redirectPath) + __DEBUG__ && logger.log('redirect', { state: state.value, redirectPath }) if (state.value && state.value !== redirectPath) { if (import.meta.client) { state.value = '' // reset redirect path window.location.assign(redirectPath) } else if (import.meta.server) { - __DEBUG__ && console.log('differentDomains servermode ', redirectPath) + __DEBUG__ && logger.log('differentDomains servermode', { redirectPath }) state.value = redirectPath // set redirect path } } @@ -409,8 +408,9 @@ export function injectNuxtHelpers(nuxt: NuxtApp, i18n: I18n) { // override prefix for route path, support domain export function extendPrefixable(runtimeConfig = useRuntimeConfig()) { + const logger = createLogger('extendPrefixable') return (opts: PrefixableOptions): boolean => { - __DEBUG__ && console.log('extendPrefixable', DefaultPrefixable(opts)) + __DEBUG__ && logger.log(DefaultPrefixable(opts)) return DefaultPrefixable(opts) && !runtimeConfig.public.i18n.differentDomains } @@ -418,10 +418,11 @@ export function extendPrefixable(runtimeConfig = useRuntimeConfig()) { // override switch locale path intercepter, support domain export function extendSwitchLocalePathIntercepter(runtimeConfig = useRuntimeConfig()): SwitchLocalePathIntercepter { + const logger = createLogger('extendSwitchLocalePathIntercepter') return (path: string, locale: Locale): string => { if (runtimeConfig.public.i18n.differentDomains) { const domain = getDomainFromLocale(locale) - __DEBUG__ && console.log('extendSwitchLocalePathIntercepter: domain -> ', domain, ' path -> ', path) + __DEBUG__ && logger.log({ domain, path }) if (domain) { return joinURL(domain, path) } else { @@ -434,13 +435,14 @@ export function extendSwitchLocalePathIntercepter(runtimeConfig = useRuntimeConf } export function extendBaseUrl(): BaseUrlResolveHandler { + const logger = createLogger('extendBaseUrl') return (): string => { const ctx = useNuxtApp() const { baseUrl, defaultLocale, differentDomains } = ctx.$config.public.i18n if (isFunction(baseUrl)) { const baseUrlResult = baseUrl(ctx) - __DEBUG__ && console.log('baseUrl: using localeLoader function -', baseUrlResult) + __DEBUG__ && logger.log('using localeLoader function -', { baseUrlResult }) return baseUrlResult } @@ -448,13 +450,13 @@ export function extendBaseUrl(): BaseUrlResolveHandler { if (differentDomains && localeCode) { const domain = getDomainFromLocale(localeCode) if (domain) { - __DEBUG__ && console.log('baseUrl: using differentDomains -', domain) + __DEBUG__ && logger.log('using differentDomains -', { domain }) return domain } } if (baseUrl) { - __DEBUG__ && console.log('baseUrl: using runtimeConfig -', baseUrl) + __DEBUG__ && logger.log('using runtimeConfig -', { baseUrl }) return baseUrl } diff --git a/src/types.ts b/src/types.ts index b52b76285..6413d9519 100644 --- a/src/types.ts +++ b/src/types.ts @@ -155,7 +155,7 @@ export type NuxtI18nOptions< rootRedirect?: string | RootRedirectOptions skipSettingLocaleOnNavigate?: boolean types?: 'composition' | 'legacy' - debug?: boolean + debug?: boolean | 'verbose' dynamicRouteParams?: boolean parallelPlugin?: boolean /** From 131f5c653b74810db4a6f2d176f5d919381b280e Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Mon, 19 Aug 2024 16:16:51 +0200 Subject: [PATCH 2/5] fix: add pure comments to function call --- src/bundler.ts | 9 ++++++--- src/env.d.ts | 3 ++- src/nitro.ts | 3 ++- src/runtime/internal.ts | 8 ++++---- src/runtime/messages.ts | 8 ++++---- src/runtime/plugins/i18n.ts | 2 +- src/runtime/utils.ts | 14 +++++++------- 7 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/bundler.ts b/src/bundler.ts index c8b1f779f..446d8d63f 100644 --- a/src/bundler.ts +++ b/src/bundler.ts @@ -84,7 +84,8 @@ export async function extendBundler(nuxt: Nuxt, nuxtOptions: Required { if (config.define) { - config.define['__DEBUG__'] = JSON.stringify(nuxtOptions.debug) + config.define['__DEBUG__'] = JSON.stringify(!!nuxtOptions.debug) + config.define['__DEBUG_VERBOSE__'] = JSON.stringify(nuxtOptions.debug === 'verbose') } else { config.define = { - __DEBUG__: JSON.stringify(nuxtOptions.debug) + __DEBUG__: JSON.stringify(!!nuxtOptions.debug), + __DEBUG_VERBOSE__: JSON.stringify(nuxtOptions.debug === 'verbose') } } debug('vite.config.define', config.define) diff --git a/src/env.d.ts b/src/env.d.ts index b84d7eee7..41695763f 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -4,4 +4,5 @@ declare namespace NodeJS { } } -declare let __DEBUG__: boolean | 'verbose' +declare let __DEBUG__: boolean +declare let __DEBUG_VERBOSE__: boolean diff --git a/src/nitro.ts b/src/nitro.ts index 0fff01581..63f5de2dd 100644 --- a/src/nitro.ts +++ b/src/nitro.ts @@ -120,7 +120,8 @@ export { localeDetector } } // setup debug flag - nitroConfig.replace['__DEBUG__'] = String(nuxtOptions.debug) + nitroConfig.replace['__DEBUG__'] = String(!!nuxtOptions.debug) + nitroConfig.replace['__DEBUG_VERBOSE__'] = String(nuxtOptions.debug === 'verbose') debug('nitro.replace', nitroConfig.replace) }) diff --git a/src/runtime/internal.ts b/src/runtime/internal.ts index 339cf7f10..3dfeaaea2 100644 --- a/src/runtime/internal.ts +++ b/src/runtime/internal.ts @@ -49,7 +49,7 @@ export function parseAcceptLanguage(input: string): string[] { export function getBrowserLocale(): string | undefined { let ret: string | undefined - const logger = createLogger('getBrowserLocale') + const logger = /*#__PURE__*/ createLogger('getBrowserLocale') if (import.meta.client) { if (navigator.languages) { @@ -94,7 +94,7 @@ export function getLocaleCookie( defaultLocale: string ): string | undefined { const env = import.meta.client ? 'client' : 'server' - const logger = createLogger(`getLocaleCookie:${env}`) + const logger = /*#__PURE__*/ createLogger(`getLocaleCookie:${env}`) __DEBUG__ && logger.log({ useCookie: detect && detect.useCookie, @@ -175,7 +175,7 @@ export function detectBrowserLanguage( detectLocaleContext: DetectLocaleContext, locale: Locale = '' ): DetectBrowserLanguageFromResult { - const logger = createLogger('detectBrowserLanguage') + const logger = /*#__PURE__*/ createLogger('detectBrowserLanguage') const _detect = runtimeDetectBrowserLanguage() // feature is disabled @@ -270,7 +270,7 @@ export function getLocaleDomain( strategy: string, route: string | RouteLocationNormalized | RouteLocationNormalizedLoaded ): string { - const logger = createLogger(`getLocaleDomain`) + const logger = /*#__PURE__*/ createLogger(`getLocaleDomain`) let host = getHost() || '' const routePath = isObject(route) ? route.path : isString(route) ? route : '' diff --git a/src/runtime/messages.ts b/src/runtime/messages.ts index 6dfaf2b80..5c55dd9e2 100644 --- a/src/runtime/messages.ts +++ b/src/runtime/messages.ts @@ -88,20 +88,20 @@ export async function loadInitialMessages( } async function loadMessage(locale: Locale, { key, load }: LocaleLoader) { - const logger = createLogger('loadMessage') + const logger = /*#__PURE__*/ createLogger('loadMessage') let message: LocaleMessages | null = null try { __DEBUG__ && logger.log({ locale }) const getter = await load().then(r => ('default' in r ? r.default : r)) if (isFunction(getter)) { message = await getter(locale) - __DEBUG__ && logger.log('dynamic load', __DEBUG__ === 'verbose' ? message : '') + __DEBUG__ && logger.log('dynamic load', __DEBUG_VERBOSE__ ? message : '') } else { message = getter if (message != null && cacheMessages) { cacheMessages.set(key, message) } - __DEBUG__ && logger.log('loaded', __DEBUG__ === 'verbose' ? message : '') + __DEBUG__ && logger.log('loaded', __DEBUG_VERBOSE__ ? message : '') } } catch (e: unknown) { console.error('Failed locale loading: ' + (e as Error).message) @@ -114,7 +114,7 @@ export async function loadLocale( localeLoaders: Record, setter: (locale: Locale, message: LocaleMessages) => void ) { - const logger = createLogger('loadLocale') + const logger = /*#__PURE__*/ createLogger('loadLocale') const loaders = localeLoaders[locale] if (loaders == null) { diff --git a/src/runtime/plugins/i18n.ts b/src/runtime/plugins/i18n.ts index 4461cace7..10eb30c8f 100644 --- a/src/runtime/plugins/i18n.ts +++ b/src/runtime/plugins/i18n.ts @@ -55,7 +55,7 @@ export default defineNuxtPlugin({ name: 'i18n:plugin', parallel: parallelPlugin, async setup(nuxt) { - const logger = createLogger('plugin:i18n') + const logger = /*#__PURE__*/ createLogger('plugin:i18n') const route = useRoute() const { vueApp: app } = nuxt const nuxtContext = nuxt as unknown as NuxtApp diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index 436dff000..3e37d701a 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -80,7 +80,7 @@ export async function loadAndSetLocale( runtimeI18n: ModulePublicRuntimeConfig['i18n'], initial: boolean = false ): Promise { - const logger = createLogger('loadAndSetLocale') + const logger = /*#__PURE__*/ createLogger('loadAndSetLocale') const { differentDomains, skipSettingLocaleOnNavigate, lazy } = runtimeI18n const opts = runtimeDetectBrowserLanguage(runtimeI18n) const nuxtApp = useNuxtApp() @@ -173,7 +173,7 @@ export function detectLocale( const { strategy, defaultLocale, differentDomains, multiDomainLocales } = runtimeI18n const { localeCookie } = detectLocaleContext const _detectBrowserLanguage = runtimeDetectBrowserLanguage(runtimeI18n) - const logger = createLogger('detectLocale') + const logger = /*#__PURE__*/ createLogger('detectLocale') const initialLocale = isFunction(initialLocaleLoader) ? initialLocaleLoader() : initialLocaleLoader __DEBUG__ && logger.log({ initialLocale }) @@ -226,7 +226,7 @@ export function detectRedirect({ }): string { const nuxtApp = useNuxtApp() const common = initCommonComposableOptions() - const logger = createLogger('detectRedirect') + const logger = /*#__PURE__*/ createLogger('detectRedirect') const { strategy, differentDomains } = common.runtimeConfig.public.i18n __DEBUG__ && logger.log({ route }) __DEBUG__ && logger.log({ targetLocale, calledWithRouting, routeLocaleGetter: routeLocaleGetter(route.to) }) @@ -306,7 +306,7 @@ export async function navigate( const { nuxtApp, i18n, locale, route } = args const { rootRedirect, differentDomains, multiDomainLocales, skipSettingLocaleOnNavigate, configLocales, strategy } = nuxtApp.$config.public.i18n - const logger = createLogger('navigate') + const logger = /*#__PURE__*/ createLogger('navigate') let { redirectPath } = args __DEBUG__ && @@ -408,7 +408,7 @@ export function injectNuxtHelpers(nuxt: NuxtApp, i18n: I18n) { // override prefix for route path, support domain export function extendPrefixable(runtimeConfig = useRuntimeConfig()) { - const logger = createLogger('extendPrefixable') + const logger = /*#__PURE__*/ createLogger('extendPrefixable') return (opts: PrefixableOptions): boolean => { __DEBUG__ && logger.log(DefaultPrefixable(opts)) @@ -418,7 +418,7 @@ export function extendPrefixable(runtimeConfig = useRuntimeConfig()) { // override switch locale path intercepter, support domain export function extendSwitchLocalePathIntercepter(runtimeConfig = useRuntimeConfig()): SwitchLocalePathIntercepter { - const logger = createLogger('extendSwitchLocalePathIntercepter') + const logger = /*#__PURE__*/ createLogger('extendSwitchLocalePathIntercepter') return (path: string, locale: Locale): string => { if (runtimeConfig.public.i18n.differentDomains) { const domain = getDomainFromLocale(locale) @@ -435,7 +435,7 @@ export function extendSwitchLocalePathIntercepter(runtimeConfig = useRuntimeConf } export function extendBaseUrl(): BaseUrlResolveHandler { - const logger = createLogger('extendBaseUrl') + const logger = /*#__PURE__*/ createLogger('extendBaseUrl') return (): string => { const ctx = useNuxtApp() const { baseUrl, defaultLocale, differentDomains } = ctx.$config.public.i18n From 216b256f910aa4092c5fd44ef0ad6327a32045d6 Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Tue, 20 Aug 2024 09:22:22 +0200 Subject: [PATCH 3/5] fix: use `consola` for runtime debug logging --- src/runtime/messages.ts | 10 +++++----- src/runtime/utils.ts | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/runtime/messages.ts b/src/runtime/messages.ts index 5c55dd9e2..57a39d93e 100644 --- a/src/runtime/messages.ts +++ b/src/runtime/messages.ts @@ -1,4 +1,5 @@ import { deepCopy, isFunction, isArray, isObject, isString } from '@intlify/shared' +import { createConsola } from 'consola' import type { I18nOptions, Locale, FallbackLocale, LocaleMessages, DefineLocaleMessage } from 'vue-i18n' import type { NuxtApp } from '#app' @@ -21,10 +22,9 @@ export type LocaleLoader> = { * * NOTE: We could export the logger from a virtual file instead */ +const debugLogger = /*#__PURE__*/ createConsola({ level: __DEBUG_VERBOSE__ ? 999 : 4 }).withTag('i18n') function createLogger(label: string) { - return { - log: console.log.bind(console, `[i18n:${label}]`) - } + return /*#__PURE__*/ debugLogger.withTag(label) } const cacheMessages = new Map>() @@ -95,13 +95,13 @@ async function loadMessage(locale: Locale, { key, load }: LocaleLoader) { const getter = await load().then(r => ('default' in r ? r.default : r)) if (isFunction(getter)) { message = await getter(locale) - __DEBUG__ && logger.log('dynamic load', __DEBUG_VERBOSE__ ? message : '') + __DEBUG__ && logger.log('dynamic load', logger.level > 999 ? message : '') } else { message = getter if (message != null && cacheMessages) { cacheMessages.set(key, message) } - __DEBUG__ && logger.log('loaded', __DEBUG_VERBOSE__ ? message : '') + __DEBUG__ && logger.log('loaded', logger.level > 999 ? message : '') } } catch (e: unknown) { console.error('Failed locale loading: ' + (e as Error).message) diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index 3e37d701a..9ea14ff0e 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -34,6 +34,7 @@ import { setLocaleProperty, setLocaleCookie } from './compatibility' +import { createConsola } from 'consola' import type { I18n, Locale } from 'vue-i18n' import type { NuxtApp } from '#app' @@ -154,15 +155,6 @@ export async function loadAndSetLocale( type LocaleLoader = () => Locale -/** - * Used for runtime debug logs only - */ -export function createLogger(label: string) { - return { - log: console.log.bind(console, `[i18n:${label}]`) - } -} - export function detectLocale( route: string | RouteLocationNormalized | RouteLocationNormalizedLoaded, routeLocaleGetter: GetLocaleFromRouteFunction, @@ -477,3 +469,11 @@ export function getNormalizedLocales(locales: string[] | LocaleObject[]): Locale } return normalized } + +/** + * Used for runtime debug logs only + */ +const debugLogger = /*#__PURE__*/ createConsola({ level: __DEBUG_VERBOSE__ ? 999 : 4 }).withTag('i18n') +export function createLogger(label: string) { + return /*#__PURE__*/ debugLogger.withTag(label) +} From a44ce5dbcd40696e2cfd3db47b18464476a5cb45 Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Tue, 20 Aug 2024 19:49:47 +0200 Subject: [PATCH 4/5] fix: use virtual file to set up runtime logger --- src/bundler.ts | 7 ++----- src/env.d.ts | 1 - src/logger.d.ts | 5 +++++ src/module.ts | 12 ++++++++++++ src/nitro.ts | 5 ++++- src/runtime/internal.ts | 3 ++- src/runtime/messages.ts | 17 +++-------------- src/runtime/plugins/i18n.ts | 11 ++--------- src/runtime/utils.ts | 10 +--------- src/virtual-logger.ts | 31 +++++++++++++++++++++++++++++++ 10 files changed, 62 insertions(+), 40 deletions(-) create mode 100644 src/logger.d.ts create mode 100644 src/virtual-logger.ts diff --git a/src/bundler.ts b/src/bundler.ts index 446d8d63f..600d9554d 100644 --- a/src/bundler.ts +++ b/src/bundler.ts @@ -84,8 +84,7 @@ export async function extendBundler(nuxt: Nuxt, nuxtOptions: Required { if (config.define) { config.define['__DEBUG__'] = JSON.stringify(!!nuxtOptions.debug) - config.define['__DEBUG_VERBOSE__'] = JSON.stringify(nuxtOptions.debug === 'verbose') } else { config.define = { - __DEBUG__: JSON.stringify(!!nuxtOptions.debug), - __DEBUG_VERBOSE__: JSON.stringify(nuxtOptions.debug === 'verbose') + __DEBUG__: JSON.stringify(!!nuxtOptions.debug) } } debug('vite.config.define', config.define) diff --git a/src/env.d.ts b/src/env.d.ts index 41695763f..64eb2139b 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -5,4 +5,3 @@ declare namespace NodeJS { } declare let __DEBUG__: boolean -declare let __DEBUG_VERBOSE__: boolean diff --git a/src/logger.d.ts b/src/logger.d.ts new file mode 100644 index 000000000..37ccae036 --- /dev/null +++ b/src/logger.d.ts @@ -0,0 +1,5 @@ +declare module 'virtual:nuxt-i18n-logger' { + import type { ConsolaInstance } from 'consola' + + export function createLogger(label: string): ConsolaInstance +} diff --git a/src/module.ts b/src/module.ts index 38fb2d69a..7cf21c287 100644 --- a/src/module.ts +++ b/src/module.ts @@ -39,6 +39,7 @@ import { import { distDir, 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 type { HookResult } from '@nuxt/schema' import type { LocaleObject, NuxtI18nOptions } from './types' @@ -220,6 +221,7 @@ export default defineNuxtModule({ // for composables nuxt.options.alias['#i18n'] = resolve(distDir, 'runtime/composables/index.mjs') 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) @@ -251,6 +253,16 @@ export default defineNuxtModule({ 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 ||= [] + cfg.plugins.push(i18nVirtualLoggerPlugin(options.debug)) + }) + /** * `PageMeta` augmentation to add `nuxtI18n` property * TODO: Remove in v9, `useSetI18nParams` should be used instead diff --git a/src/nitro.ts b/src/nitro.ts index 63f5de2dd..4f991d2bb 100644 --- a/src/nitro.ts +++ b/src/nitro.ts @@ -21,6 +21,7 @@ import { import type { Nuxt } from '@nuxt/schema' import type { NuxtI18nOptions, LocaleInfo } from './types' import { resolveI18nDir } from './layers' +import { i18nVirtualLoggerPlugin } from './virtual-logger' const debug = createDebug('@nuxtjs/i18n:nitro') @@ -52,6 +53,9 @@ export async function setupNitro( nitroConfig.rollupConfig.plugins = isArray(nitroConfig.rollupConfig.plugins) ? nitroConfig.rollupConfig.plugins : [nitroConfig.rollupConfig.plugins] + + nitroConfig.rollupConfig.plugins.push(i18nVirtualLoggerPlugin(nuxtOptions.debug)) + const yamlPaths = getResourcePaths(additionalParams.localeInfo, /\.ya?ml$/) if (yamlPaths.length > 0) { // @ts-ignore NOTE: A type error occurs due to a mismatch between the version of rollup on the nitro side (v4.x) and the version of rollup that `@rollup/plugin-yaml` depends on (v3.x). We ignore this type error because `@rollup/plugin-yaml` is rollup version compatible. @@ -121,7 +125,6 @@ export { localeDetector } // setup debug flag nitroConfig.replace['__DEBUG__'] = String(!!nuxtOptions.debug) - nitroConfig.replace['__DEBUG_VERBOSE__'] = String(nuxtOptions.debug === 'verbose') debug('nitro.replace', nitroConfig.replace) }) diff --git a/src/runtime/internal.ts b/src/runtime/internal.ts index 3dfeaaea2..adeb2c378 100644 --- a/src/runtime/internal.ts +++ b/src/runtime/internal.ts @@ -6,7 +6,8 @@ import isHTTPS from 'is-https' import { useRequestHeaders, useRequestEvent, useCookie as useNuxtCookie, useRuntimeConfig, useNuxtApp } from '#imports' import { NUXT_I18N_MODULE_ID, DEFAULT_COOKIE_KEY, isSSG, localeCodes, normalizedLocales } from '#build/i18n.options.mjs' import { findBrowserLocale, getLocalesRegex } from './routing/utils' -import { createLogger, initCommonComposableOptions, type CommonComposableOptions } from './utils' +import { initCommonComposableOptions, type CommonComposableOptions } from './utils' +import { createLogger } from 'virtual:nuxt-i18n-logger' import type { Locale } from 'vue-i18n' import type { DetectBrowserLanguageOptions, LocaleObject } from '#build/i18n.options.mjs' diff --git a/src/runtime/messages.ts b/src/runtime/messages.ts index 57a39d93e..e5c1cb0ca 100644 --- a/src/runtime/messages.ts +++ b/src/runtime/messages.ts @@ -1,5 +1,5 @@ import { deepCopy, isFunction, isArray, isObject, isString } from '@intlify/shared' -import { createConsola } from 'consola' +import { createLogger } from 'virtual:nuxt-i18n-logger' import type { I18nOptions, Locale, FallbackLocale, LocaleMessages, DefineLocaleMessage } from 'vue-i18n' import type { NuxtApp } from '#app' @@ -16,17 +16,6 @@ export type LocaleLoader> = { cache: boolean } -/** - * Used for runtime debug logs only, cannot be imported due to - * this being a virtual file in both nuxt and nitro contexts - * - * NOTE: We could export the logger from a virtual file instead - */ -const debugLogger = /*#__PURE__*/ createConsola({ level: __DEBUG_VERBOSE__ ? 999 : 4 }).withTag('i18n') -function createLogger(label: string) { - return /*#__PURE__*/ debugLogger.withTag(label) -} - const cacheMessages = new Map>() export async function loadVueI18nOptions( @@ -95,13 +84,13 @@ async function loadMessage(locale: Locale, { key, load }: LocaleLoader) { const getter = await load().then(r => ('default' in r ? r.default : r)) if (isFunction(getter)) { message = await getter(locale) - __DEBUG__ && logger.log('dynamic load', logger.level > 999 ? message : '') + __DEBUG__ && logger.log('dynamic load', logger.level >= 999 ? message : '') } else { message = getter if (message != null && cacheMessages) { cacheMessages.set(key, message) } - __DEBUG__ && logger.log('loaded', logger.level > 999 ? message : '') + __DEBUG__ && logger.log('loaded', logger.level >= 999 ? message : '') } } catch (e: unknown) { console.error('Failed locale loading: ' + (e as Error).message) diff --git a/src/runtime/plugins/i18n.ts b/src/runtime/plugins/i18n.ts index 10eb30c8f..57ca1867f 100644 --- a/src/runtime/plugins/i18n.ts +++ b/src/runtime/plugins/i18n.ts @@ -18,15 +18,7 @@ import { type LocaleObject } from '#build/i18n.options.mjs' import { loadVueI18nOptions, loadInitialMessages, loadLocale } from '../messages' -import { - loadAndSetLocale, - detectLocale, - detectRedirect, - navigate, - injectNuxtHelpers, - extendBaseUrl, - createLogger -} from '../utils' +import { loadAndSetLocale, detectLocale, detectRedirect, navigate, injectNuxtHelpers, extendBaseUrl } from '../utils' import { getBrowserLocale, getLocaleCookie, @@ -39,6 +31,7 @@ import { import { inBrowser, resolveBaseUrl } from '../routing/utils' import { extendI18n, createLocaleFromRouteGetter } from '../routing/extends' import { setLocale, getLocale, mergeLocaleMessage, setLocaleProperty } from '../compatibility' +import { createLogger } from 'virtual:nuxt-i18n-logger' import type { Locale, I18nOptions } from 'vue-i18n' import type { NuxtApp } from '#app' diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index 9ea14ff0e..e1359231d 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -34,7 +34,7 @@ import { setLocaleProperty, setLocaleCookie } from './compatibility' -import { createConsola } from 'consola' +import { createLogger } from 'virtual:nuxt-i18n-logger' import type { I18n, Locale } from 'vue-i18n' import type { NuxtApp } from '#app' @@ -469,11 +469,3 @@ export function getNormalizedLocales(locales: string[] | LocaleObject[]): Locale } return normalized } - -/** - * Used for runtime debug logs only - */ -const debugLogger = /*#__PURE__*/ createConsola({ level: __DEBUG_VERBOSE__ ? 999 : 4 }).withTag('i18n') -export function createLogger(label: string) { - return /*#__PURE__*/ debugLogger.withTag(label) -} diff --git a/src/virtual-logger.ts b/src/virtual-logger.ts new file mode 100644 index 000000000..aa5d2c520 --- /dev/null +++ b/src/virtual-logger.ts @@ -0,0 +1,31 @@ +import type { Plugin } from 'vite' + +export const VIRTUAL_NUXT_I18N_LOGGER = 'virtual:nuxt-i18n-logger' +export const RESOLVED_VIRTUAL_NUXT_I18N_LOGGER = `\0${VIRTUAL_NUXT_I18N_LOGGER}` + +export function i18nVirtualLoggerPlugin(debug: boolean | 'verbose') { + return { + name: 'nuxtjs:i18n-logger', + enforce: 'pre', + resolveId(id) { + if (id === VIRTUAL_NUXT_I18N_LOGGER) return RESOLVED_VIRTUAL_NUXT_I18N_LOGGER + }, + load(id) { + if (id !== RESOLVED_VIRTUAL_NUXT_I18N_LOGGER) return + + // return stub if debug logging is disabled + if (!debug) { + return `export function createLogger() {}` + } + + return ` +import { createConsola } from 'consola' + +const debugLogger = createConsola({ level: ${debug === 'verbose' ? 999 : 4} }).withTag('i18n') + +export function createLogger(label) { + return debugLogger.withTag(label) +}` + } + } +} From 8fe1a336fb69a5185b28b70ba12c5a64f8e8f570 Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Wed, 21 Aug 2024 11:03:29 +0200 Subject: [PATCH 5/5] docs: remove debug option changes from v8 docs --- docs/content/docs/3.options/10.misc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/docs/3.options/10.misc.md b/docs/content/docs/3.options/10.misc.md index 967a79371..0e38a8126 100644 --- a/docs/content/docs/3.options/10.misc.md +++ b/docs/content/docs/3.options/10.misc.md @@ -47,10 +47,10 @@ If it can not detect Nuxt configuration changing, you may need to run `nuxi prep ## `debug` -- type: `boolean | 'verbose'` +- type: `boolean` - default: `false` -Whether to use `@nuxtjs/i18n` debug mode. If `true` or `'verbose'`, logs will be output to the console, setting this to `'verbose'` will also log loaded messages objects. +Whether to use `@nuxtjs/i18n` debug mode. If `true`, logs will be output to the console. ::callout{icon="i-heroicons-exclamation-triangle" color="amber"} The purpose of this option is to help identify any problems with `@nuxtjs/i18n`.