feat: i18n locales lazy loading (#482)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
This commit is contained in:
parent
2c00f8ba6d
commit
c75bb79786
@ -13,7 +13,8 @@
|
|||||||
"test:unit": "vitest",
|
"test:unit": "vitest",
|
||||||
"typecheck": "vue-tsc --noEmit",
|
"typecheck": "vue-tsc --noEmit",
|
||||||
"up": "taze major -I",
|
"up": "taze major -I",
|
||||||
"postinstall": "npx simple-git-hooks"
|
"postinstall": "npx simple-git-hooks",
|
||||||
|
"sizecheck": "npx vite-bundle-visualizer"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@unocss/reset": "^0.50.6",
|
"@unocss/reset": "^0.50.6",
|
||||||
@ -55,6 +56,7 @@
|
|||||||
"unplugin-vue-components": "^0.24.1",
|
"unplugin-vue-components": "^0.24.1",
|
||||||
"unplugin-vue-macros": "^1.10.1",
|
"unplugin-vue-macros": "^1.10.1",
|
||||||
"vite": "^4.2.0",
|
"vite": "^4.2.0",
|
||||||
|
"vite-bundle-visualizer": "^0.6.0",
|
||||||
"vite-plugin-inspect": "^0.7.17",
|
"vite-plugin-inspect": "^0.7.17",
|
||||||
"vite-plugin-pages": "^0.29.0",
|
"vite-plugin-pages": "^0.29.0",
|
||||||
"vite-plugin-pwa": "^0.14.4",
|
"vite-plugin-pwa": "^0.14.4",
|
||||||
|
873
pnpm-lock.yaml
873
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { t, availableLocales, locale } = useI18n()
|
import { availableLocales, loadLanguageAsync } from '~/modules/i18n'
|
||||||
|
|
||||||
const toggleLocales = () => {
|
const { t, locale } = useI18n()
|
||||||
|
|
||||||
|
const toggleLocales = async () => {
|
||||||
// change to some real logic
|
// change to some real logic
|
||||||
const locales = availableLocales
|
const locales = availableLocales
|
||||||
locale.value = locales[(locales.indexOf(locale.value) + 1) % locales.length]
|
const newLocale = locales[(locales.indexOf(locale.value) + 1) % locales.length]
|
||||||
|
await loadLanguageAsync(newLocale)
|
||||||
|
locale.value = newLocale
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { Locale } from 'vue-i18n'
|
||||||
import { createI18n } from 'vue-i18n'
|
import { createI18n } from 'vue-i18n'
|
||||||
import { type UserModule } from '~/types'
|
import { type UserModule } from '~/types'
|
||||||
|
|
||||||
@ -5,21 +6,45 @@ import { type UserModule } from '~/types'
|
|||||||
// https://vitejs.dev/guide/features.html#glob-import
|
// https://vitejs.dev/guide/features.html#glob-import
|
||||||
//
|
//
|
||||||
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
|
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
|
||||||
const messages = Object.fromEntries(
|
const i18n = createI18n({
|
||||||
Object.entries(
|
legacy: false,
|
||||||
import.meta.glob<{ default: any }>('../../locales/*.y(a)?ml', { eager: true }))
|
locale: '',
|
||||||
.map(([key, value]) => {
|
messages: {},
|
||||||
const yaml = key.endsWith('.yaml')
|
})
|
||||||
return [key.slice(14, yaml ? -5 : -4), value.default]
|
|
||||||
}),
|
const localesMap = Object.fromEntries(
|
||||||
)
|
Object.entries(import.meta.glob('../../locales/*.yml'))
|
||||||
|
.map(([path, loadLocale]) => [path.match(/([\w-]*)\.yml$/)?.[1], loadLocale]),
|
||||||
|
) as Record<Locale, () => Promise<{ default: Record<string, string> }>>
|
||||||
|
|
||||||
|
export const availableLocales = Object.keys(localesMap)
|
||||||
|
|
||||||
|
const loadedLanguages: string[] = []
|
||||||
|
|
||||||
|
function setI18nLanguage(lang: Locale) {
|
||||||
|
i18n.global.locale.value = lang as any
|
||||||
|
if (typeof document !== 'undefined')
|
||||||
|
document.querySelector('html')?.setAttribute('lang', lang)
|
||||||
|
return lang
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadLanguageAsync(lang: string): Promise<Locale> {
|
||||||
|
// If the same language
|
||||||
|
if (i18n.global.locale.value === lang)
|
||||||
|
return setI18nLanguage(lang)
|
||||||
|
|
||||||
|
// If the language was already loaded
|
||||||
|
if (loadedLanguages.includes(lang))
|
||||||
|
return setI18nLanguage(lang)
|
||||||
|
|
||||||
|
// If the language hasn't been loaded yet
|
||||||
|
const messages = await localesMap[lang]()
|
||||||
|
i18n.global.setLocaleMessage(lang, messages.default)
|
||||||
|
loadedLanguages.push(lang)
|
||||||
|
return setI18nLanguage(lang)
|
||||||
|
}
|
||||||
|
|
||||||
export const install: UserModule = ({ app }) => {
|
export const install: UserModule = ({ app }) => {
|
||||||
const i18n = createI18n({
|
|
||||||
legacy: false,
|
|
||||||
locale: 'en',
|
|
||||||
messages,
|
|
||||||
})
|
|
||||||
|
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
|
loadLanguageAsync('en')
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user