Skip to content

Commit

Permalink
feat: runtime logger formatting and debug verbose option (#3067)
Browse files Browse the repository at this point in the history
* feat: runtime logger and debug verbose

* fix: add pure comments to function call

* fix: use `consola` for runtime debug logging

* fix: use virtual file to set up runtime logger

* docs: remove debug option changes from v8 docs
  • Loading branch information
BobbieGoede authored Aug 21, 2024
1 parent f513ee7 commit 80d9e60
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 164 deletions.
4 changes: 2 additions & 2 deletions docs/content/docs/5.v9/3.options/10.misc.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
72 changes: 0 additions & 72 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export async function extendBundler(nuxt: Nuxt, nuxtOptions: Required<NuxtI18nOp
dropMessageCompiler: nuxtOptions.bundle.dropMessageCompiler
}),
{
__DEBUG__: String(nuxtOptions.debug)
__DEBUG__: String(!!nuxtOptions.debug)
}
)
)
Expand Down Expand Up @@ -125,10 +125,10 @@ export async function extendBundler(nuxt: Nuxt, nuxtOptions: Required<NuxtI18nOp

extendViteConfig(config => {
if (config.define) {
config.define['__DEBUG__'] = JSON.stringify(nuxtOptions.debug)
config.define['__DEBUG__'] = JSON.stringify(!!nuxtOptions.debug)
} else {
config.define = {
__DEBUG__: JSON.stringify(nuxtOptions.debug)
__DEBUG__: JSON.stringify(!!nuxtOptions.debug)
}
}
debug('vite.config.define', config.define)
Expand Down
5 changes: 5 additions & 0 deletions src/logger.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare module 'virtual:nuxt-i18n-logger' {
import type { ConsolaInstance } from 'consola'

export function createLogger(label: string): ConsolaInstance
}
12 changes: 12 additions & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -220,6 +221,7 @@ export default defineNuxtModule<NuxtI18nOptions>({
// 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)
Expand Down Expand Up @@ -251,6 +253,16 @@ export default defineNuxtModule<NuxtI18nOptions>({
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
Expand Down
6 changes: 5 additions & 1 deletion src/nitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -120,7 +124,7 @@ export { localeDetector }
}

// setup debug flag
nitroConfig.replace['__DEBUG__'] = String(nuxtOptions.debug)
nitroConfig.replace['__DEBUG__'] = String(!!nuxtOptions.debug)
debug('nitro.replace', nitroConfig.replace)
})

Expand Down
59 changes: 23 additions & 36 deletions src/runtime/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -49,20 +50,21 @@ export function parseAcceptLanguage(input: string): string[] {

export function getBrowserLocale(): string | undefined {
let ret: string | undefined
const logger = /*#__PURE__*/ 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)
}
}

Expand Down Expand Up @@ -92,8 +94,10 @@ export function getLocaleCookie(
detect: false | DetectBrowserLanguageOptions,
defaultLocale: string
): string | undefined {
const env = import.meta.client ? 'client' : 'server'
const logger = /*#__PURE__*/ createLogger(`getLocaleCookie:${env}`)
__DEBUG__ &&
console.log('getLocaleCookie', {
logger.log({
useCookie: detect && detect.useCookie,
cookieKey: detect && detect.cookieKey,
localeCodes
Expand All @@ -104,27 +108,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
}
Expand Down Expand Up @@ -176,7 +176,7 @@ export function detectBrowserLanguage(
detectLocaleContext: DetectLocaleContext,
locale: Locale = ''
): DetectBrowserLanguageFromResult {
const logger = createLogger('detectBrowserLanguage')
const logger = /*#__PURE__*/ createLogger('detectBrowserLanguage')
const _detect = runtimeDetectBrowserLanguage()

// feature is disabled
Expand Down Expand Up @@ -271,15 +271,13 @@ export function getLocaleDomain(
strategy: string,
route: string | RouteLocationNormalized | RouteLocationNormalizedLoaded
): string {
const logger = /*#__PURE__*/ 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) {
Expand All @@ -296,8 +294,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(
Expand All @@ -310,20 +307,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 })
}
}
}
Expand All @@ -334,10 +324,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 })
}
}
}
Expand Down
16 changes: 10 additions & 6 deletions src/runtime/messages.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { deepCopy, isFunction, isArray, isObject, isString } from '@intlify/shared'
import { createLogger } from 'virtual:nuxt-i18n-logger'

import type { I18nOptions, Locale, FallbackLocale, LocaleMessages, DefineLocaleMessage } from 'vue-i18n'
import type { NuxtApp } from '#app'
Expand All @@ -14,6 +15,7 @@ export type LocaleLoader<T = LocaleMessages<DefineLocaleMessage>> = {
load: () => Promise<MessageLoaderResult<T>>
cache: boolean
}

const cacheMessages = new Map<string, LocaleMessages<DefineLocaleMessage>>()

export async function loadVueI18nOptions(
Expand Down Expand Up @@ -75,19 +77,20 @@ export async function loadInitialMessages<Context extends NuxtApp = NuxtApp>(
}

async function loadMessage(locale: Locale, { key, load }: LocaleLoader) {
const logger = /*#__PURE__*/ createLogger('loadMessage')
let message: LocaleMessages<DefineLocaleMessage> | 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', logger.level >= 999 ? message : '')
} else {
message = getter
if (message != null && cacheMessages) {
cacheMessages.set(key, message)
}
__DEBUG__ && console.log('loadMessage: load', message)
__DEBUG__ && logger.log('loaded', logger.level >= 999 ? message : '')
}
} catch (e: unknown) {
console.error('Failed locale loading: ' + (e as Error).message)
Expand All @@ -100,6 +103,7 @@ export async function loadLocale(
localeLoaders: Record<Locale, LocaleLoader[]>,
setter: (locale: Locale, message: LocaleMessages<DefineLocaleMessage>) => void
) {
const logger = /*#__PURE__*/ createLogger('loadLocale')
const loaders = localeLoaders[locale]

if (loaders == null) {
Expand All @@ -112,11 +116,11 @@ export async function loadLocale(
let message: LocaleMessages<DefineLocaleMessage> | 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)
}

Expand Down
Loading

0 comments on commit 80d9e60

Please sign in to comment.