Skip to content

Commit 9116dff

Browse files
authored
fix: memory leak (nuxt-modules#2616)
* fix: `nuxtI18nOptions` being set and not cleaned up * fix: use local `useNuxtApp` instead of passing nuxt context as argument * fix: remove `nuxtI18nOptions` copy
1 parent b8684bc commit 9116dff

File tree

3 files changed

+50
-56
lines changed

3 files changed

+50
-56
lines changed

src/runtime/internal.ts

+16-19
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
} from 'vue-i18n-routing'
1212
import { hasProtocol } from 'ufo'
1313
import isHTTPS from 'is-https'
14-
import { useRequestHeaders, useRequestEvent, useCookie as useNuxtCookie } from '#imports'
14+
import { useRequestHeaders, useRequestEvent, useCookie as useNuxtCookie, useRuntimeConfig, useNuxtApp } from '#imports'
1515
import { nuxtI18nOptionsDefault, NUXT_I18N_MODULE_ID, isSSG } from '#build/i18n.options.mjs'
1616

1717
import type { NuxtApp } from '#app'
@@ -86,7 +86,7 @@ export function parseAcceptLanguage(input: string): string[] {
8686
}
8787

8888
// eslint-disable-next-line @typescript-eslint/no-unused-vars
89-
export function getBrowserLocale(options: Required<NuxtI18nInternalOptions>, context?: any): string | undefined {
89+
export function getBrowserLocale(options: Required<NuxtI18nInternalOptions>): string | undefined {
9090
let ret: string | undefined
9191

9292
if (process.client) {
@@ -108,16 +108,13 @@ export function getBrowserLocale(options: Required<NuxtI18nInternalOptions>, con
108108
return ret
109109
}
110110

111-
export function getLocaleCookie(
112-
context: any,
113-
{
114-
useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie,
115-
cookieKey = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey,
116-
localeCodes = []
117-
}: Pick<DetectBrowserLanguageOptions, 'useCookie' | 'cookieKey'> & {
118-
localeCodes?: readonly string[]
119-
} = {}
120-
): string | undefined {
111+
export function getLocaleCookie({
112+
useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie,
113+
cookieKey = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey,
114+
localeCodes = []
115+
}: Pick<DetectBrowserLanguageOptions, 'useCookie' | 'cookieKey'> & {
116+
localeCodes?: readonly string[]
117+
} = {}): string | undefined {
121118
__DEBUG__ && console.log('getLocaleCookie', { useCookie, cookieKey, localeCodes })
122119
if (!useCookie) {
123120
return
@@ -134,7 +131,6 @@ export function getLocaleCookie(
134131

135132
export function setLocaleCookie(
136133
locale: string,
137-
context: any,
138134
{
139135
useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie,
140136
cookieKey = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey,
@@ -197,7 +193,6 @@ export const DefaultDetectBrowserLanguageFromResult: DetectBrowserLanguageFromRe
197193

198194
export function detectBrowserLanguage<Context extends NuxtApp = NuxtApp>(
199195
route: string | Route | RouteLocationNormalized | RouteLocationNormalizedLoaded,
200-
context: any,
201196
nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>>,
202197
nuxtI18nInternalOptions: DeepRequired<NuxtI18nInternalOptions>,
203198
vueI18nOptions: I18nOptions,
@@ -253,13 +248,13 @@ export function detectBrowserLanguage<Context extends NuxtApp = NuxtApp>(
253248

254249
// get preferred language from cookie if present and enabled
255250
if (useCookie) {
256-
matchedLocale = cookieLocale = getLocaleCookie(context, { ...nuxtI18nOptions.detectBrowserLanguage, localeCodes })
251+
matchedLocale = cookieLocale = getLocaleCookie({ ...nuxtI18nOptions.detectBrowserLanguage, localeCodes })
257252
localeFrom = 'cookie'
258253
__DEBUG__ && console.log('detectBrowserLanguage: cookieLocale', cookieLocale)
259254
}
260255
// try to get locale from either navigator or header detection
261256
if (!matchedLocale) {
262-
matchedLocale = getBrowserLocale(nuxtI18nInternalOptions, context)
257+
matchedLocale = getBrowserLocale(nuxtI18nInternalOptions)
263258
localeFrom = 'navigator_or_header'
264259
__DEBUG__ && console.log('detectBrowserLanguage: browserLocale', matchedLocale)
265260
}
@@ -369,9 +364,11 @@ export function getLocaleDomain(locales: LocaleObject[]): string {
369364
return host
370365
}
371366

372-
export function getDomainFromLocale(localeCode: Locale, locales: LocaleObject[], nuxt?: NuxtApp): string | undefined {
367+
export function getDomainFromLocale(localeCode: Locale, locales: LocaleObject[]): string | undefined {
368+
const runtimeConfig = useRuntimeConfig()
369+
const nuxtApp = useNuxtApp()
373370
// lookup the `differentDomain` origin associated with given locale.
374-
const config = nuxt?.$config.public.i18n as { locales?: Record<Locale, { domain?: string }> }
371+
const config = runtimeConfig.public.i18n as { locales?: Record<Locale, { domain?: string }> }
375372
const lang = locales.find(locale => locale.code === localeCode)
376373
const domain = config?.locales?.[localeCode]?.domain ?? lang?.domain
377374

@@ -383,7 +380,7 @@ export function getDomainFromLocale(localeCode: Locale, locales: LocaleObject[],
383380
if (process.server) {
384381
const {
385382
node: { req }
386-
} = useRequestEvent(nuxt)
383+
} = useRequestEvent(nuxtApp)
387384
protocol = req && isHTTPS(req) ? 'https:' : 'http:'
388385
} else {
389386
protocol = new URL(window.location.origin).protocol

src/runtime/plugins/i18n.ts

+15-15
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ import {
1313
getLocale,
1414
getComposer
1515
} from 'vue-i18n-routing'
16-
import { defineNuxtPlugin, useRouter, useRoute, addRouteMiddleware, defineNuxtRouteMiddleware } from '#imports'
16+
import {
17+
defineNuxtPlugin,
18+
useRouter,
19+
useRoute,
20+
addRouteMiddleware,
21+
defineNuxtRouteMiddleware,
22+
useNuxtApp
23+
} from '#imports'
1724
import {
1825
localeCodes,
1926
vueI18nConfigs,
@@ -65,7 +72,7 @@ export default defineNuxtPlugin({
6572
const { vueApp: app } = nuxt
6673
const nuxtContext = nuxt as unknown as NuxtApp
6774

68-
const vueI18nOptions: I18nOptions = await loadVueI18nOptions(vueI18nConfigs, nuxtContext)
75+
const vueI18nOptions: I18nOptions = await loadVueI18nOptions(vueI18nConfigs, useNuxtApp())
6976

7077
const useCookie = nuxtI18nOptions.detectBrowserLanguage && nuxtI18nOptions.detectBrowserLanguage.useCookie
7178
const { __normalizedLocales: normalizedLocales } = nuxtI18nInternalOptions
@@ -85,7 +92,6 @@ export default defineNuxtPlugin({
8592

8693
nuxtI18nOptions.baseUrl = extendBaseUrl(nuxtI18nOptions.baseUrl, {
8794
differentDomains,
88-
nuxt: nuxtContext,
8995
localeCodeLoader: defaultLocale,
9096
normalizedLocales
9197
})
@@ -103,7 +109,7 @@ export default defineNuxtPlugin({
103109
registerGlobalOptions(router, {
104110
...nuxtI18nOptions,
105111
dynamicRouteParamsKey: 'nuxtI18n',
106-
switchLocalePathIntercepter: extendSwitchLocalePathIntercepter(differentDomains, normalizedLocales, nuxtContext),
112+
switchLocalePathIntercepter: extendSwitchLocalePathIntercepter(differentDomains, normalizedLocales),
107113
prefixable: extendPrefixable(differentDomains)
108114
})
109115

@@ -112,7 +118,6 @@ export default defineNuxtPlugin({
112118
// detect initial locale
113119
let initialLocale = detectLocale(
114120
route,
115-
nuxt.ssrContext,
116121
getLocaleFromRoute,
117122
nuxtI18nOptions,
118123
vueI18nOptions,
@@ -167,7 +172,6 @@ export default defineNuxtPlugin({
167172
} = nuxtI18nOptions.detectBrowserLanguage
168173
? detectBrowserLanguage(
169174
route,
170-
nuxtContext,
171175
nuxtI18nOptions,
172176
nuxtI18nInternalOptions,
173177
vueI18nOptions,
@@ -207,7 +211,7 @@ export default defineNuxtPlugin({
207211
})
208212
composer.setLocale = async (locale: string) => {
209213
const localeSetup = isInitialLocaleSetup(locale)
210-
const [modified] = await loadAndSetLocale(locale, nuxtContext, localeMessages, i18n, {
214+
const [modified] = await loadAndSetLocale(locale, localeMessages, i18n, {
211215
useCookie,
212216
differentDomains,
213217
initial: localeSetup,
@@ -222,7 +226,6 @@ export default defineNuxtPlugin({
222226

223227
const redirectPath = detectRedirect({
224228
route: { to: route },
225-
context: nuxtContext,
226229
targetLocale: locale,
227230
routeLocaleGetter: getLocaleFromRoute,
228231
nuxtI18nOptions
@@ -246,11 +249,10 @@ export default defineNuxtPlugin({
246249
}
247250
composer.differentDomains = differentDomains
248251
composer.defaultLocale = defaultLocale
249-
composer.getBrowserLocale = () => _getBrowserLocale(nuxtI18nInternalOptions, nuxt.ssrContext)
250-
composer.getLocaleCookie = () =>
251-
_getLocaleCookie(nuxt.ssrContext, { ...nuxtI18nOptions.detectBrowserLanguage, localeCodes })
252+
composer.getBrowserLocale = () => _getBrowserLocale(nuxtI18nInternalOptions)
253+
composer.getLocaleCookie = () => _getLocaleCookie({ ...nuxtI18nOptions.detectBrowserLanguage, localeCodes })
252254
composer.setLocaleCookie = (locale: string) =>
253-
_setLocaleCookie(locale, nuxt.ssrContext, nuxtI18nOptions.detectBrowserLanguage || undefined)
255+
_setLocaleCookie(locale, nuxtI18nOptions.detectBrowserLanguage || undefined)
254256

255257
composer.onBeforeLanguageSwitch = (oldLocale, newLocale, initialSetup, context) =>
256258
nuxt.callHook('i18n:beforeLocaleSwitch', { oldLocale, newLocale, initialSetup, context })
@@ -448,7 +450,6 @@ export default defineNuxtPlugin({
448450

449451
const locale = detectLocale(
450452
to,
451-
nuxt.ssrContext,
452453
getLocaleFromRoute,
453454
nuxtI18nOptions,
454455
vueI18nOptions,
@@ -468,7 +469,7 @@ export default defineNuxtPlugin({
468469
const localeSetup = isInitialLocaleSetup(locale)
469470
__DEBUG__ && console.log('localeSetup', localeSetup)
470471

471-
const [modified] = await loadAndSetLocale(locale, nuxtContext, localeMessages, i18n, {
472+
const [modified] = await loadAndSetLocale(locale, localeMessages, i18n, {
472473
useCookie,
473474
differentDomains,
474475
initial: localeSetup,
@@ -483,7 +484,6 @@ export default defineNuxtPlugin({
483484

484485
const redirectPath = detectRedirect({
485486
route: { to, from },
486-
context: nuxtContext,
487487
targetLocale: locale,
488488
routeLocaleGetter: nuxtI18nOptions.strategy === 'no_prefix' ? () => locale : getLocaleFromRoute,
489489
nuxtI18nOptions,

src/runtime/utils.ts

+19-22
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
} from 'vue-i18n-routing'
2121
import { joinURL, isEqual } from 'ufo'
2222
import { isString, isFunction, isArray, isObject } from '@intlify/shared'
23-
import { navigateTo, useRoute, useState } from '#imports'
23+
import { navigateTo, useNuxtApp, useRoute, useRuntimeConfig, useState } from '#imports'
2424
import { nuxtI18nInternalOptions, nuxtI18nOptionsDefault, NUXT_I18N_MODULE_ID, isSSG } from '#build/i18n.options.mjs'
2525
import {
2626
detectBrowserLanguage,
@@ -90,7 +90,6 @@ export async function finalizePendingLocaleChange(i18n: I18n) {
9090

9191
export async function loadAndSetLocale<Context extends NuxtApp = NuxtApp>(
9292
newLocale: string,
93-
context: Context,
9493
localeMessages: Record<Locale, LocaleInternalLoader[]>,
9594
i18n: I18n,
9695
{
@@ -106,6 +105,7 @@ export async function loadAndSetLocale<Context extends NuxtApp = NuxtApp>(
106105
cacheMessages?: Map<string, LocaleMessages<DefineLocaleMessage>>
107106
} = {}
108107
): Promise<[boolean, string]> {
108+
const nuxtApp = useNuxtApp()
109109
let ret = false
110110
const oldLocale = getLocale(i18n)
111111
__DEBUG__ && console.log('setLocale: new -> ', newLocale, ' old -> ', oldLocale, ' initial -> ', initial)
@@ -123,7 +123,7 @@ export async function loadAndSetLocale<Context extends NuxtApp = NuxtApp>(
123123
}
124124

125125
// call onBeforeLanguageSwitch
126-
const localeOverride = await onBeforeLanguageSwitch(i18n, oldLocale, newLocale, initial, context)
126+
const localeOverride = await onBeforeLanguageSwitch(i18n, oldLocale, newLocale, initial, nuxtApp)
127127
const localeCodes = getLocaleCodes(i18n)
128128
if (localeOverride && localeCodes && localeCodes.includes(localeOverride)) {
129129
if (localeOverride === oldLocale) {
@@ -162,7 +162,6 @@ type LocaleLoader = () => Locale
162162

163163
export function detectLocale<Context extends NuxtApp = NuxtApp>(
164164
route: string | Route | RouteLocationNormalized | RouteLocationNormalizedLoaded,
165-
context: any,
166165
routeLocaleGetter: ReturnType<typeof createLocaleFromRouteGetter>,
167166
nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>>,
168167
vueI18nOptions: I18nOptions,
@@ -188,7 +187,6 @@ export function detectLocale<Context extends NuxtApp = NuxtApp>(
188187
} = nuxtI18nOptions.detectBrowserLanguage
189188
? detectBrowserLanguage(
190189
route,
191-
context,
192190
nuxtI18nOptions,
193191
nuxtI18nInternalOptions,
194192
vueI18nOptions,
@@ -239,7 +237,7 @@ export function detectLocale<Context extends NuxtApp = NuxtApp>(
239237
nuxtI18nOptions.detectBrowserLanguage
240238
)
241239
if (!finalLocale && nuxtI18nOptions.detectBrowserLanguage && nuxtI18nOptions.detectBrowserLanguage.useCookie) {
242-
finalLocale = getLocaleCookie(context, { ...nuxtI18nOptions.detectBrowserLanguage, localeCodes }) || ''
240+
finalLocale = getLocaleCookie({ ...nuxtI18nOptions.detectBrowserLanguage, localeCodes }) || ''
243241
}
244242

245243
__DEBUG__ && console.log('detectLocale: finalLocale last (finalLocale, defaultLocale) -', finalLocale, defaultLocale)
@@ -253,7 +251,6 @@ export function detectLocale<Context extends NuxtApp = NuxtApp>(
253251

254252
export function detectRedirect<Context extends NuxtApp = NuxtApp>({
255253
route,
256-
context,
257254
targetLocale,
258255
routeLocaleGetter,
259256
nuxtI18nOptions,
@@ -263,12 +260,12 @@ export function detectRedirect<Context extends NuxtApp = NuxtApp>({
263260
to: Route | RouteLocationNormalized | RouteLocationNormalizedLoaded
264261
from?: Route | RouteLocationNormalized | RouteLocationNormalizedLoaded
265262
}
266-
context: Context
267263
targetLocale: Locale
268264
routeLocaleGetter: ReturnType<typeof createLocaleFromRouteGetter>
269265
nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>>
270266
calledWithRouting?: boolean
271267
}): string {
268+
const nuxtApp = useNuxtApp()
272269
const { strategy, differentDomains } = nuxtI18nOptions
273270
__DEBUG__ && console.log('detectRedirect: targetLocale -> ', targetLocale)
274271
__DEBUG__ && console.log('detectRedirect: route -> ', route)
@@ -292,7 +289,7 @@ export function detectRedirect<Context extends NuxtApp = NuxtApp>({
292289
routeLocaleGetter(route.to) !== targetLocale
293290
) {
294291
// the current route could be 404 in which case attempt to find matching route using the full path
295-
const routePath = context.$switchLocalePath(targetLocale) || context.$localePath(toFullPath, targetLocale)
292+
const routePath = nuxtApp.$switchLocalePath(targetLocale) || nuxtApp.$localePath(toFullPath, targetLocale)
296293
__DEBUG__ && console.log('detectRedirect: calculate routePath -> ', routePath, toFullPath)
297294
if (isString(routePath) && routePath && !isEqual(routePath, toFullPath) && !routePath.startsWith('//')) {
298295
/**
@@ -314,9 +311,9 @@ export function detectRedirect<Context extends NuxtApp = NuxtApp>({
314311
* let it be processed by the route of the router middleware.
315312
*/
316313
const switchLocalePath = useSwitchLocalePath({
317-
i18n: getComposer(context.$i18n),
314+
i18n: getComposer(nuxtApp.$i18n),
318315
route: route.to,
319-
router: context.$router
316+
router: nuxtApp.$router
320317
})
321318
const routePath = switchLocalePath(targetLocale)
322319
__DEBUG__ && console.log('detectRedirect: calculate domain or ssg routePath -> ', routePath)
@@ -443,12 +440,11 @@ export function extendPrefixable(differentDomains: boolean) {
443440
// override switch locale path intercepter, support domain
444441
export function extendSwitchLocalePathIntercepter(
445442
differentDomains: boolean,
446-
normalizedLocales: LocaleObject[],
447-
nuxt: NuxtApp
443+
normalizedLocales: LocaleObject[]
448444
): SwitchLocalePathIntercepter {
449445
return (path: string, locale: Locale): string => {
450446
if (differentDomains) {
451-
const domain = getDomainFromLocale(locale, normalizedLocales, nuxt)
447+
const domain = getDomainFromLocale(locale, normalizedLocales)
452448
__DEBUG__ && console.log('extendSwitchLocalePathIntercepter: domain -> ', domain, ' path -> ', path)
453449
if (domain) {
454450
return joinURL(domain, path)
@@ -461,32 +457,33 @@ export function extendSwitchLocalePathIntercepter(
461457
}
462458
}
463459

464-
export function extendBaseUrl<Context extends NuxtApp = NuxtApp>(
465-
baseUrl: string | BaseUrlResolveHandler<Context>,
466-
options: Pick<Required<NuxtI18nOptions<Context>>, 'differentDomains'> & {
467-
nuxt?: Context
460+
export function extendBaseUrl<Context = NuxtApp>(
461+
baseUrl: string | BaseUrlResolveHandler<NuxtApp>,
462+
options: Pick<Required<NuxtI18nOptions<NuxtApp>>, 'differentDomains'> & {
468463
localeCodeLoader: Locale | LocaleLoader
469464
normalizedLocales: LocaleObject[]
470465
}
471466
): BaseUrlResolveHandler<Context> {
472-
return (context: Context): string => {
467+
return (): string => {
468+
const ctx = useNuxtApp()
469+
const runtimeConfig = useRuntimeConfig()
473470
if (isFunction(baseUrl)) {
474-
const baseUrlResult = baseUrl(context)
471+
const baseUrlResult = baseUrl(ctx)
475472
__DEBUG__ && console.log('baseUrl: using localeLoader function -', baseUrlResult)
476473
return baseUrlResult
477474
}
478475

479476
const { differentDomains, localeCodeLoader, normalizedLocales } = options
480477
const localeCode = isFunction(localeCodeLoader) ? localeCodeLoader() : localeCodeLoader
481478
if (differentDomains && localeCode) {
482-
const domain = getDomainFromLocale(localeCode, normalizedLocales, options.nuxt)
479+
const domain = getDomainFromLocale(localeCode, normalizedLocales)
483480
if (domain) {
484481
__DEBUG__ && console.log('baseUrl: using differentDomains -', domain)
485482
return domain
486483
}
487484
}
488485

489-
const config = context.$config?.public?.i18n as { baseUrl?: string }
486+
const config = runtimeConfig?.public?.i18n as { baseUrl?: string }
490487
if (config?.baseUrl) {
491488
__DEBUG__ && console.log('baseUrl: using runtimeConfig -', config.baseUrl)
492489
return config.baseUrl

0 commit comments

Comments
 (0)