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

refactor: integrate vue-i18n-routing #2686

Merged
merged 15 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
refactor: integrate and replace vue-i18n-routing
  • Loading branch information
BobbieGoede committed Jan 10, 2024
commit 6a5fbf2a965fffbcfa3150a160941c0ddeb994ee
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"prepack": "pnpm build",
"release": "bumpp --commit \"release: v%s\" --push --tag",
"changelog": "gh-changelogen --repo=nuxt-community/i18n-module",
"dev": "pnpm dev:prepare && pnpm build && nuxi dev playground",
"dev": "pnpm dev:prepare && pnpm build --sourcemap && nuxi dev playground",
"dev:prepare": "nuxi prepare",
"dev:build": "nuxi build playground",
"dev:generate": "nuxi generate playground",
Expand Down Expand Up @@ -96,7 +96,6 @@
"ufo": "^1.3.1",
"unplugin": "^1.5.0",
"vue-i18n": "^9.9.0",
"vue-i18n-routing": "^1.2.0",
"vue-router": "^4.2.5"
},
"devDependencies": {
Expand Down
56 changes: 2 additions & 54 deletions pnpm-lock.yaml

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

2 changes: 0 additions & 2 deletions specs/fixtures/basic_usage/app.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<script setup lang="ts">
import { useLocaleHead } from 'vue-i18n-routing'

const head = useLocaleHead({ addSeoAttributes: true })
</script>

Expand Down
2 changes: 1 addition & 1 deletion specs/issues/2617.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('#2617', async () => {
consoleLogs.some(
log =>
log.type === 'warning' &&
log.text.includes('[vue-i18n-routing] Locale ISO code is required to generate alternate link')
log.text.includes('[nuxt-i18n-routing] Locale ISO code is required to generate alternate link')
)
).toBe(false)
})
Expand Down
4 changes: 2 additions & 2 deletions src/alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
VUE_I18N_PKG,
// VUE_I18N_BRIDGE_PKG,
// VUE_ROUTER_BRIDGE_PKG,
VUE_I18N_ROUTING_PKG,
// VUE_I18N_ROUTING_PKG,
SHARED_PKG,
MESSAGE_COMPILER_PKG,
CORE_PKG,
Expand Down Expand Up @@ -36,7 +36,7 @@ export async function setupAlias(nuxt: Nuxt, options: NuxtI18nOptions) {
modules[UTILS_H3_PKG] = `${UTILS_PKG}/dist/h3.mjs` // for `@intlify/utils/h3`
// modules[VUE_ROUTER_BRIDGE_PKG] = `${VUE_ROUTER_BRIDGE_PKG}/lib/index.mjs`
// modules[VUE_I18N_BRIDGE_PKG] = `${VUE_I18N_BRIDGE_PKG}/lib/index.mjs`
modules[VUE_I18N_ROUTING_PKG] = `${VUE_I18N_ROUTING_PKG}/dist/vue-i18n-routing.mjs`
// modules[VUE_I18N_ROUTING_PKG] = `${VUE_I18N_ROUTING_PKG}/dist/vue-i18n-routing.mjs`
modules[UFO_PKG] = UFO_PKG
modules[IS_HTTPS_PKG] = IS_HTTPS_PKG

Expand Down
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const UTILS_PKG = '@intlify/utils' as const
export const UTILS_H3_PKG = '@intlify/utils/h3' as const
// export const VUE_I18N_BRIDGE_PKG = '@intlify/vue-i18n-bridge' as const
// export const VUE_ROUTER_BRIDGE_PKG = '@intlify/vue-router-bridge' as const
export const VUE_I18N_ROUTING_PKG = 'vue-i18n-routing' as const
// export const VUE_I18N_ROUTING_PKG = 'vue-i18n-routing' as const
export const UFO_PKG = 'ufo' as const
export const IS_HTTPS_PKG = 'is-https' as const

Expand Down
2 changes: 1 addition & 1 deletion src/options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const parallelPlugin: boolean

export const STRATEGIES: typeof constants.STRATEGIES
export const DEFAULT_LOCALE: typeof constants.DEFAULT_LOCALE
export const DEFAULT_STRATEGY: keyof typeof constants.STRATEGIES
export const DEFAULT_STRATEGY: (typeof STRATEGIES)[keyof typeof STRATEGIES]
export const DEFAULT_TRAILING_SLASH: typeof constants.DEFAULT_TRAILING_SLASH
export const DEFAULT_ROUTES_NAME_SEPARATOR: typeof constants.DEFAULT_ROUTES_NAME_SEPARATOR
export const DEFAULT_LOCALE_ROUTE_NAME_SUFFIX: typeof constants.DEFAULT_LOCALE_ROUTE_NAME_SUFFIX
Expand Down
2 changes: 1 addition & 1 deletion src/routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export interface PrefixLocalizedRouteOptions {
*/
path: string
}
function prefixLocalizedRoute(
export function prefixLocalizedRoute(
localizeOptions: PrefixLocalizedRouteOptions,
options: LocalizeRoutesParams,
extra = false
Expand Down
33 changes: 5 additions & 28 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
import { computed } from 'vue'
import { createI18n } from 'vue-i18n'
import { createLocaleFromRouteGetter, registerGlobalOptions } from 'vue-i18n-routing'
import {
defineNuxtPlugin,
useRouter,
useRoute,
addRouteMiddleware,
defineNuxtRouteMiddleware,
useNuxtApp
} from '#imports'
import { defineNuxtPlugin, useRoute, addRouteMiddleware, defineNuxtRouteMiddleware, useNuxtApp } from '#imports'
import {
localeCodes,
vueI18nConfigs,
Expand All @@ -28,8 +20,6 @@ import {
navigate,
injectNuxtHelpers,
extendBaseUrl,
extendPrefixable,
extendSwitchLocalePathIntercepter,
_setLocale
} from '../utils'
import {
Expand All @@ -41,17 +31,16 @@ import {
} from '../internal'

import type { Composer, Locale, I18nOptions } from 'vue-i18n'
import type { ExtendProperyDescripters, VueI18nRoutingPluginOptions } from 'vue-i18n-routing'
import type { NuxtApp } from '#app'
import type { getRouteBaseName, localePath, localeRoute, switchLocalePath, localeHead } from '../routing/compatibles'
import { getComposer, getLocale, setLocale } from '../routing/utils'
import { extendI18n } from '../routing/extends/i18n'
import { extendI18n, type ExtendPropertyDescriptors, type VueI18nRoutingPluginOptions } from '../routing/extends/i18n'
import { createLocaleFromRouteGetter } from '../routing/extends/router'

export default defineNuxtPlugin({
name: 'i18n:plugin',
parallel: parallelPlugin,
async setup(nuxt) {
const router = useRouter()
const route = useRoute()
const { vueApp: app } = nuxt
const nuxtContext = nuxt as unknown as NuxtApp
Expand Down Expand Up @@ -91,18 +80,6 @@ export default defineNuxtPlugin({
vueI18nOptions.messages = vueI18nOptions.messages || {}
vueI18nOptions.fallbackLocale = vueI18nOptions.fallbackLocale ?? false

// register nuxt/i18n options as global
// so global options is reffered by `vue-i18n-routing`
registerGlobalOptions(router, {
...nuxtI18nOptions,
dynamicRouteParamsKey: 'nuxtI18n',
switchLocalePathIntercepter: extendSwitchLocalePathIntercepter(
nuxtI18nOptions.differentDomains,
normalizedLocales
),
prefixable: extendPrefixable(nuxtI18nOptions.differentDomains)
})

const getDefaultLocale = (defaultLocale: string) => defaultLocale || vueI18nOptions.locale || 'en-US'

// detect initial locale
Expand Down Expand Up @@ -265,7 +242,7 @@ export default defineNuxtPlugin({
}
}
},
onExtendExportedGlobal(g: Composer): ExtendProperyDescripters {
onExtendExportedGlobal(g: Composer): ExtendPropertyDescriptors {
return {
strategy: {
get() {
Expand Down Expand Up @@ -332,7 +309,7 @@ export default defineNuxtPlugin({
}
}
},
onExtendVueI18n(composer: Composer): ExtendProperyDescripters {
onExtendVueI18n(composer: Composer): ExtendPropertyDescriptors {
return {
strategy: {
get() {
Expand Down
8 changes: 4 additions & 4 deletions src/runtime/routing/extends/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ export interface VueI18nRoutingPluginOptions {
__vueI18nExtend?: VueI18nExtender
}

export interface ExtendProperyDescripters {
export interface ExtendPropertyDescriptors {
[key: string]: Pick<PropertyDescriptor, 'get'>
}
export type ExtendComposerHook = (compser: Composer) => void
export type ExtendVueI18nHook = (composer: Composer) => ExtendProperyDescripters
export type ExtendExportedGlobalHook = (global: Composer) => ExtendProperyDescripters
export type ExtendVueI18nHook = (composer: Composer) => ExtendPropertyDescriptors
export type ExtendExportedGlobalHook = (global: Composer) => ExtendPropertyDescriptors

export interface ExtendHooks {
onExtendComposer?: ExtendComposerHook
Expand Down Expand Up @@ -214,7 +214,7 @@ function extendProperyDescripters(
exported: any, // eslint-disable-line @typescript-eslint/no-explicit-any
hook?: ExtendVueI18nHook | ExtendExportedGlobalHook
): void {
const properties: ExtendProperyDescripters[] = [
const properties: ExtendPropertyDescriptors[] = [
{
locales: {
get() {
Expand Down
99 changes: 99 additions & 0 deletions src/runtime/routing/extends/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { isString, isObject, makeSymbol } from '@intlify/shared'
import { warn, getLocalesRegex } from '../utils'

import type { I18nRoutingOptions } from '#build/i18n.options.mjs'
import type { RouteLocationNormalized, RouteLocationNormalizedLoaded, Router } from 'vue-router'

/**
* Global options for i18n routing
*/
export type I18nRoutingGlobalOptions<Context = unknown> = Pick<
I18nRoutingOptions<Context>,
| 'defaultLocale'
| 'defaultDirection'
| 'defaultLocaleRouteNameSuffix'
| 'trailingSlash'
| 'routesNameSeparator'
| 'strategy'
| 'prefixable'
| 'switchLocalePathIntercepter'
| 'dynamicRouteParamsKey'
> & { localeCodes?: string[] }

const GlobalOptionsRegistry = makeSymbol('nuxt-i18n-routing-gor')

/**
* Register global i18n routing option registory
*
* @param router - A router instance, about router type
* @param options - A global options, about options type, see {@link I18nRoutingGlobalOptions}
*/
export function registerGlobalOptions<Context = unknown>(
router: Router,
options: I18nRoutingGlobalOptions<Context>
): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const _options: I18nRoutingGlobalOptions | undefined = (router as any)[GlobalOptionsRegistry]
if (_options) {
warn('already registered global options')
} else {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(router as any)[GlobalOptionsRegistry] = options
}
}

/**
* Get global i18n routing options
*
* @param router - A router instance, about router type
*
* @returns - {@link I18nRoutingGlobalOptions | global options} from i18n routing options registory, if registered, return it, else empty object
*/
export function getGlobalOptions(router: Router): I18nRoutingGlobalOptions {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (router as any)[GlobalOptionsRegistry] ?? {}
}

export function createLocaleFromRouteGetter(
localeCodes: string[],
routesNameSeparator: string,
defaultLocaleRouteNameSuffix: string
) {
const localesPattern = `(${localeCodes.join('|')})`
const defaultSuffixPattern = `(?:${routesNameSeparator}${defaultLocaleRouteNameSuffix})?`
const regexpName = new RegExp(`${routesNameSeparator}${localesPattern}${defaultSuffixPattern}$`, 'i')
const regexpPath = getLocalesRegex(localeCodes)

/**
* extract locale code from given route:
* - if route has a name, try to extract locale from it
* - otherwise, fall back to using the routes'path
*/
const getLocaleFromRoute = (route: RouteLocationNormalizedLoaded | RouteLocationNormalized | string): string => {
// extract from route name
if (isObject(route)) {
if (route.name) {
const name = isString(route.name) ? route.name : route.name.toString()
const matches = name.match(regexpName)
if (matches && matches.length > 1) {
return matches[1]
}
} else if (route.path) {
// Extract from path
const matches = route.path.match(regexpPath)
if (matches && matches.length > 1) {
return matches[1]
}
}
} else if (isString(route)) {
const matches = route.match(regexpPath)
if (matches && matches.length > 1) {
return matches[1]
}
}

return ''
}

return getLocaleFromRoute
}
2 changes: 1 addition & 1 deletion src/runtime/routing/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const inBrowser = typeof window !== 'undefined'

export function warn(msg: string, err?: Error): void {
if (typeof console !== 'undefined') {
console.warn(`[vue-i18n-routing] ` + msg)
console.warn(`[nuxt-i18n-routing] ` + msg)
/* istanbul ignore if */
if (err) {
console.warn(err.stack)
Expand Down
Loading