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",
|
||||
"typecheck": "vue-tsc --noEmit",
|
||||
"up": "taze major -I",
|
||||
"postinstall": "npx simple-git-hooks"
|
||||
"postinstall": "npx simple-git-hooks",
|
||||
"sizecheck": "npx vite-bundle-visualizer"
|
||||
},
|
||||
"dependencies": {
|
||||
"@unocss/reset": "^0.50.6",
|
||||
@ -55,6 +56,7 @@
|
||||
"unplugin-vue-components": "^0.24.1",
|
||||
"unplugin-vue-macros": "^1.10.1",
|
||||
"vite": "^4.2.0",
|
||||
"vite-bundle-visualizer": "^0.6.0",
|
||||
"vite-plugin-inspect": "^0.7.17",
|
||||
"vite-plugin-pages": "^0.29.0",
|
||||
"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">
|
||||
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
|
||||
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>
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import type { Locale } from 'vue-i18n'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import { type UserModule } from '~/types'
|
||||
|
||||
@ -5,21 +6,45 @@ import { type UserModule } from '~/types'
|
||||
// https://vitejs.dev/guide/features.html#glob-import
|
||||
//
|
||||
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
|
||||
const messages = Object.fromEntries(
|
||||
Object.entries(
|
||||
import.meta.glob<{ default: any }>('../../locales/*.y(a)?ml', { eager: true }))
|
||||
.map(([key, value]) => {
|
||||
const yaml = key.endsWith('.yaml')
|
||||
return [key.slice(14, yaml ? -5 : -4), value.default]
|
||||
}),
|
||||
)
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: '',
|
||||
messages: {},
|
||||
})
|
||||
|
||||
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 }) => {
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
messages,
|
||||
})
|
||||
|
||||
app.use(i18n)
|
||||
loadLanguageAsync('en')
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user