Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: memory leak #2616

Merged
merged 3 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 16 additions & 19 deletions src/runtime/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from 'vue-i18n-routing'
import { hasProtocol } from 'ufo'
import isHTTPS from 'is-https'
import { useRequestHeaders, useRequestEvent, useCookie as useNuxtCookie } from '#imports'
import { useRequestHeaders, useRequestEvent, useCookie as useNuxtCookie, useRuntimeConfig, useNuxtApp } from '#imports'
import { nuxtI18nOptionsDefault, NUXT_I18N_MODULE_ID, isSSG } from '#build/i18n.options.mjs'

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

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

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

export function getLocaleCookie(
context: any,
{
useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie,
cookieKey = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey,
localeCodes = []
}: Pick<DetectBrowserLanguageOptions, 'useCookie' | 'cookieKey'> & {
localeCodes?: readonly string[]
} = {}
): string | undefined {
export function getLocaleCookie({
useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie,
cookieKey = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey,
localeCodes = []
}: Pick<DetectBrowserLanguageOptions, 'useCookie' | 'cookieKey'> & {
localeCodes?: readonly string[]
} = {}): string | undefined {
__DEBUG__ && console.log('getLocaleCookie', { useCookie, cookieKey, localeCodes })
if (!useCookie) {
return
Expand All @@ -134,7 +131,6 @@ export function getLocaleCookie(

export function setLocaleCookie(
locale: string,
context: any,
{
useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie,
cookieKey = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey,
Expand Down Expand Up @@ -197,7 +193,6 @@ export const DefaultDetectBrowserLanguageFromResult: DetectBrowserLanguageFromRe

export function detectBrowserLanguage<Context extends NuxtApp = NuxtApp>(
route: string | Route | RouteLocationNormalized | RouteLocationNormalizedLoaded,
context: any,
nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>>,
nuxtI18nInternalOptions: DeepRequired<NuxtI18nInternalOptions>,
vueI18nOptions: I18nOptions,
Expand Down Expand Up @@ -253,13 +248,13 @@ export function detectBrowserLanguage<Context extends NuxtApp = NuxtApp>(

// get preferred language from cookie if present and enabled
if (useCookie) {
matchedLocale = cookieLocale = getLocaleCookie(context, { ...nuxtI18nOptions.detectBrowserLanguage, localeCodes })
matchedLocale = cookieLocale = getLocaleCookie({ ...nuxtI18nOptions.detectBrowserLanguage, localeCodes })
localeFrom = 'cookie'
__DEBUG__ && console.log('detectBrowserLanguage: cookieLocale', cookieLocale)
}
// try to get locale from either navigator or header detection
if (!matchedLocale) {
matchedLocale = getBrowserLocale(nuxtI18nInternalOptions, context)
matchedLocale = getBrowserLocale(nuxtI18nInternalOptions)
localeFrom = 'navigator_or_header'
__DEBUG__ && console.log('detectBrowserLanguage: browserLocale', matchedLocale)
}
Expand Down Expand Up @@ -369,9 +364,11 @@ export function getLocaleDomain(locales: LocaleObject[]): string {
return host
}

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

Expand All @@ -383,7 +380,7 @@ export function getDomainFromLocale(localeCode: Locale, locales: LocaleObject[],
if (process.server) {
const {
node: { req }
} = useRequestEvent(nuxt)
} = useRequestEvent(nuxtApp)
protocol = req && isHTTPS(req) ? 'https:' : 'http:'
} else {
protocol = new URL(window.location.origin).protocol
Expand Down
30 changes: 15 additions & 15 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ import {
getLocale,
getComposer
} from 'vue-i18n-routing'
import { defineNuxtPlugin, useRouter, useRoute, addRouteMiddleware, defineNuxtRouteMiddleware } from '#imports'
import {
defineNuxtPlugin,
useRouter,
useRoute,
addRouteMiddleware,
defineNuxtRouteMiddleware,
useNuxtApp
} from '#imports'
import {
localeCodes,
vueI18nConfigs,
Expand Down Expand Up @@ -65,7 +72,7 @@ export default defineNuxtPlugin({
const { vueApp: app } = nuxt
const nuxtContext = nuxt as unknown as NuxtApp

const vueI18nOptions: I18nOptions = await loadVueI18nOptions(vueI18nConfigs, nuxtContext)
const vueI18nOptions: I18nOptions = await loadVueI18nOptions(vueI18nConfigs, useNuxtApp())

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

nuxtI18nOptions.baseUrl = extendBaseUrl(nuxtI18nOptions.baseUrl, {
differentDomains,
nuxt: nuxtContext,
localeCodeLoader: defaultLocale,
normalizedLocales
})
Expand All @@ -103,7 +109,7 @@ export default defineNuxtPlugin({
registerGlobalOptions(router, {
...nuxtI18nOptions,
dynamicRouteParamsKey: 'nuxtI18n',
switchLocalePathIntercepter: extendSwitchLocalePathIntercepter(differentDomains, normalizedLocales, nuxtContext),
switchLocalePathIntercepter: extendSwitchLocalePathIntercepter(differentDomains, normalizedLocales),
prefixable: extendPrefixable(differentDomains)
})

Expand All @@ -112,7 +118,6 @@ export default defineNuxtPlugin({
// detect initial locale
let initialLocale = detectLocale(
route,
nuxt.ssrContext,
getLocaleFromRoute,
nuxtI18nOptions,
vueI18nOptions,
Expand Down Expand Up @@ -167,7 +172,6 @@ export default defineNuxtPlugin({
} = nuxtI18nOptions.detectBrowserLanguage
? detectBrowserLanguage(
route,
nuxtContext,
nuxtI18nOptions,
nuxtI18nInternalOptions,
vueI18nOptions,
Expand Down Expand Up @@ -207,7 +211,7 @@ export default defineNuxtPlugin({
})
composer.setLocale = async (locale: string) => {
const localeSetup = isInitialLocaleSetup(locale)
const [modified] = await loadAndSetLocale(locale, nuxtContext, localeMessages, i18n, {
const [modified] = await loadAndSetLocale(locale, localeMessages, i18n, {
useCookie,
differentDomains,
initial: localeSetup,
Expand All @@ -222,7 +226,6 @@ export default defineNuxtPlugin({

const redirectPath = detectRedirect({
route: { to: route },
context: nuxtContext,
targetLocale: locale,
routeLocaleGetter: getLocaleFromRoute,
nuxtI18nOptions
Expand All @@ -246,11 +249,10 @@ export default defineNuxtPlugin({
}
composer.differentDomains = differentDomains
composer.defaultLocale = defaultLocale
composer.getBrowserLocale = () => _getBrowserLocale(nuxtI18nInternalOptions, nuxt.ssrContext)
composer.getLocaleCookie = () =>
_getLocaleCookie(nuxt.ssrContext, { ...nuxtI18nOptions.detectBrowserLanguage, localeCodes })
composer.getBrowserLocale = () => _getBrowserLocale(nuxtI18nInternalOptions)
composer.getLocaleCookie = () => _getLocaleCookie({ ...nuxtI18nOptions.detectBrowserLanguage, localeCodes })
composer.setLocaleCookie = (locale: string) =>
_setLocaleCookie(locale, nuxt.ssrContext, nuxtI18nOptions.detectBrowserLanguage || undefined)
_setLocaleCookie(locale, nuxtI18nOptions.detectBrowserLanguage || undefined)

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

const locale = detectLocale(
to,
nuxt.ssrContext,
getLocaleFromRoute,
nuxtI18nOptions,
vueI18nOptions,
Expand All @@ -468,7 +469,7 @@ export default defineNuxtPlugin({
const localeSetup = isInitialLocaleSetup(locale)
__DEBUG__ && console.log('localeSetup', localeSetup)

const [modified] = await loadAndSetLocale(locale, nuxtContext, localeMessages, i18n, {
const [modified] = await loadAndSetLocale(locale, localeMessages, i18n, {
useCookie,
differentDomains,
initial: localeSetup,
Expand All @@ -483,7 +484,6 @@ export default defineNuxtPlugin({

const redirectPath = detectRedirect({
route: { to, from },
context: nuxtContext,
targetLocale: locale,
routeLocaleGetter: nuxtI18nOptions.strategy === 'no_prefix' ? () => locale : getLocaleFromRoute,
nuxtI18nOptions,
Expand Down
41 changes: 19 additions & 22 deletions src/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from 'vue-i18n-routing'
import { joinURL, isEqual } from 'ufo'
import { isString, isFunction, isArray, isObject } from '@intlify/shared'
import { navigateTo, useRoute, useState } from '#imports'
import { navigateTo, useNuxtApp, useRoute, useRuntimeConfig, useState } from '#imports'
import { nuxtI18nInternalOptions, nuxtI18nOptionsDefault, NUXT_I18N_MODULE_ID, isSSG } from '#build/i18n.options.mjs'
import {
detectBrowserLanguage,
Expand Down Expand Up @@ -90,7 +90,6 @@ export async function finalizePendingLocaleChange(i18n: I18n) {

export async function loadAndSetLocale<Context extends NuxtApp = NuxtApp>(
newLocale: string,
context: Context,
localeMessages: Record<Locale, LocaleInternalLoader[]>,
i18n: I18n,
{
Expand All @@ -106,6 +105,7 @@ export async function loadAndSetLocale<Context extends NuxtApp = NuxtApp>(
cacheMessages?: Map<string, LocaleMessages<DefineLocaleMessage>>
} = {}
): Promise<[boolean, string]> {
const nuxtApp = useNuxtApp()
let ret = false
const oldLocale = getLocale(i18n)
__DEBUG__ && console.log('setLocale: new -> ', newLocale, ' old -> ', oldLocale, ' initial -> ', initial)
Expand All @@ -123,7 +123,7 @@ export async function loadAndSetLocale<Context extends NuxtApp = NuxtApp>(
}

// call onBeforeLanguageSwitch
const localeOverride = await onBeforeLanguageSwitch(i18n, oldLocale, newLocale, initial, context)
const localeOverride = await onBeforeLanguageSwitch(i18n, oldLocale, newLocale, initial, nuxtApp)
const localeCodes = getLocaleCodes(i18n)
if (localeOverride && localeCodes && localeCodes.includes(localeOverride)) {
if (localeOverride === oldLocale) {
Expand Down Expand Up @@ -162,7 +162,6 @@ type LocaleLoader = () => Locale

export function detectLocale<Context extends NuxtApp = NuxtApp>(
route: string | Route | RouteLocationNormalized | RouteLocationNormalizedLoaded,
context: any,
routeLocaleGetter: ReturnType<typeof createLocaleFromRouteGetter>,
nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>>,
vueI18nOptions: I18nOptions,
Expand All @@ -188,7 +187,6 @@ export function detectLocale<Context extends NuxtApp = NuxtApp>(
} = nuxtI18nOptions.detectBrowserLanguage
? detectBrowserLanguage(
route,
context,
nuxtI18nOptions,
nuxtI18nInternalOptions,
vueI18nOptions,
Expand Down Expand Up @@ -239,7 +237,7 @@ export function detectLocale<Context extends NuxtApp = NuxtApp>(
nuxtI18nOptions.detectBrowserLanguage
)
if (!finalLocale && nuxtI18nOptions.detectBrowserLanguage && nuxtI18nOptions.detectBrowserLanguage.useCookie) {
finalLocale = getLocaleCookie(context, { ...nuxtI18nOptions.detectBrowserLanguage, localeCodes }) || ''
finalLocale = getLocaleCookie({ ...nuxtI18nOptions.detectBrowserLanguage, localeCodes }) || ''
}

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

export function detectRedirect<Context extends NuxtApp = NuxtApp>({
route,
context,
targetLocale,
routeLocaleGetter,
nuxtI18nOptions,
Expand All @@ -263,12 +260,12 @@ export function detectRedirect<Context extends NuxtApp = NuxtApp>({
to: Route | RouteLocationNormalized | RouteLocationNormalizedLoaded
from?: Route | RouteLocationNormalized | RouteLocationNormalizedLoaded
}
context: Context
targetLocale: Locale
routeLocaleGetter: ReturnType<typeof createLocaleFromRouteGetter>
nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>>
calledWithRouting?: boolean
}): string {
const nuxtApp = useNuxtApp()
const { strategy, differentDomains } = nuxtI18nOptions
__DEBUG__ && console.log('detectRedirect: targetLocale -> ', targetLocale)
__DEBUG__ && console.log('detectRedirect: route -> ', route)
Expand All @@ -292,7 +289,7 @@ export function detectRedirect<Context extends NuxtApp = NuxtApp>({
routeLocaleGetter(route.to) !== targetLocale
) {
// the current route could be 404 in which case attempt to find matching route using the full path
const routePath = context.$switchLocalePath(targetLocale) || context.$localePath(toFullPath, targetLocale)
const routePath = nuxtApp.$switchLocalePath(targetLocale) || nuxtApp.$localePath(toFullPath, targetLocale)
__DEBUG__ && console.log('detectRedirect: calculate routePath -> ', routePath, toFullPath)
if (isString(routePath) && routePath && !isEqual(routePath, toFullPath) && !routePath.startsWith('//')) {
/**
Expand All @@ -314,9 +311,9 @@ export function detectRedirect<Context extends NuxtApp = NuxtApp>({
* let it be processed by the route of the router middleware.
*/
const switchLocalePath = useSwitchLocalePath({
i18n: getComposer(context.$i18n),
i18n: getComposer(nuxtApp.$i18n),
route: route.to,
router: context.$router
router: nuxtApp.$router
})
const routePath = switchLocalePath(targetLocale)
__DEBUG__ && console.log('detectRedirect: calculate domain or ssg routePath -> ', routePath)
Expand Down Expand Up @@ -443,12 +440,11 @@ export function extendPrefixable(differentDomains: boolean) {
// override switch locale path intercepter, support domain
export function extendSwitchLocalePathIntercepter(
differentDomains: boolean,
normalizedLocales: LocaleObject[],
nuxt: NuxtApp
normalizedLocales: LocaleObject[]
): SwitchLocalePathIntercepter {
return (path: string, locale: Locale): string => {
if (differentDomains) {
const domain = getDomainFromLocale(locale, normalizedLocales, nuxt)
const domain = getDomainFromLocale(locale, normalizedLocales)
__DEBUG__ && console.log('extendSwitchLocalePathIntercepter: domain -> ', domain, ' path -> ', path)
if (domain) {
return joinURL(domain, path)
Expand All @@ -461,32 +457,33 @@ export function extendSwitchLocalePathIntercepter(
}
}

export function extendBaseUrl<Context extends NuxtApp = NuxtApp>(
baseUrl: string | BaseUrlResolveHandler<Context>,
options: Pick<Required<NuxtI18nOptions<Context>>, 'differentDomains'> & {
nuxt?: Context
export function extendBaseUrl<Context = NuxtApp>(
baseUrl: string | BaseUrlResolveHandler<NuxtApp>,
options: Pick<Required<NuxtI18nOptions<NuxtApp>>, 'differentDomains'> & {
localeCodeLoader: Locale | LocaleLoader
normalizedLocales: LocaleObject[]
}
): BaseUrlResolveHandler<Context> {
return (context: Context): string => {
return (): string => {
const ctx = useNuxtApp()
const runtimeConfig = useRuntimeConfig()
if (isFunction(baseUrl)) {
const baseUrlResult = baseUrl(context)
const baseUrlResult = baseUrl(ctx)
__DEBUG__ && console.log('baseUrl: using localeLoader function -', baseUrlResult)
return baseUrlResult
}

const { differentDomains, localeCodeLoader, normalizedLocales } = options
const localeCode = isFunction(localeCodeLoader) ? localeCodeLoader() : localeCodeLoader
if (differentDomains && localeCode) {
const domain = getDomainFromLocale(localeCode, normalizedLocales, options.nuxt)
const domain = getDomainFromLocale(localeCode, normalizedLocales)
if (domain) {
__DEBUG__ && console.log('baseUrl: using differentDomains -', domain)
return domain
}
}

const config = context.$config?.public?.i18n as { baseUrl?: string }
const config = runtimeConfig?.public?.i18n as { baseUrl?: string }
if (config?.baseUrl) {
__DEBUG__ && console.log('baseUrl: using runtimeConfig -', config.baseUrl)
return config.baseUrl
Expand Down