perf: 优化体积,highlight.js按需导入与i18n按需加载 (#696)
* perf: 优化打包体积,highlight.js按需导入与i18n按需加载 1. highlight.js: 从全量导入改为 core + 注册27种常用语言,减少约500~800KB 2. i18n: 只同步加载en语言包,其他8种语言改为异步加载,首屏减少约350~400KB 3. 使用vue-i18n的setLocaleMessage API动态注册语言包 4. 新增switchLocale函数统一处理语言切换 5. 同步更新相关测试文件的mock路径和API适配 * 修复类型断言
This commit is contained in:
committed by
GitHub
parent
1b4733e755
commit
f6df0fecfa
@@ -1,19 +1,14 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import { messages } from './messages'
|
||||
import { en, loadLocale, supportedLocales } from './messages'
|
||||
import type { SupportedLocale } from './messages'
|
||||
|
||||
const saved = localStorage.getItem('hermes_locale')
|
||||
|
||||
const supportedLocales = ['en', 'zh', 'zh-TW', 'ja', 'ko', 'fr', 'es', 'de', 'pt'] as const
|
||||
type SupportedLocale = (typeof supportedLocales)[number]
|
||||
|
||||
function resolveLocale(saved: string | null): SupportedLocale {
|
||||
if (saved && (supportedLocales as readonly string[]).includes(saved)) {
|
||||
return saved as SupportedLocale
|
||||
}
|
||||
|
||||
// Normalize a single BCP-47 tag to a supported locale key.
|
||||
// Covers zh-Hant-TW, zh-TW, zh-HK, zh-MO, zh-Hant → zh-TW
|
||||
// zh-Hans-*, zh-CN, zh-SG, zh → zh
|
||||
function normalize(tag: string): SupportedLocale | null {
|
||||
const lower = tag.toLowerCase()
|
||||
if (lower.startsWith('zh')) {
|
||||
@@ -38,9 +33,28 @@ function resolveLocale(saved: string | null): SupportedLocale {
|
||||
return 'en'
|
||||
}
|
||||
|
||||
const locale = resolveLocale(saved)
|
||||
|
||||
export const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: resolveLocale(saved),
|
||||
locale: 'en',
|
||||
fallbackLocale: 'en',
|
||||
messages,
|
||||
messages: { en },
|
||||
})
|
||||
|
||||
export async function setupI18n(): Promise<void> {
|
||||
if (locale !== 'en') {
|
||||
const msgs = await loadLocale(locale)
|
||||
if (msgs) {
|
||||
i18n.global.setLocaleMessage(locale, msgs as any)
|
||||
}
|
||||
;(i18n.global.locale as any).value = locale
|
||||
}
|
||||
}
|
||||
|
||||
export async function switchLocale(newLocale: string): Promise<void> {
|
||||
const msgs = await loadLocale(newLocale)
|
||||
if (msgs) {
|
||||
i18n.global.setLocaleMessage(newLocale, msgs as any)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,9 @@
|
||||
import de from './locales/de'
|
||||
import en from './locales/en'
|
||||
import es from './locales/es'
|
||||
import fr from './locales/fr'
|
||||
import ja from './locales/ja'
|
||||
import ko from './locales/ko'
|
||||
import pt from './locales/pt'
|
||||
import zh from './locales/zh'
|
||||
import zhTW from './locales/zh-TW'
|
||||
|
||||
export type LocaleMessages = Record<string, unknown>
|
||||
export type LocaleMessages = Record<string, any>
|
||||
|
||||
export const rawMessages = {
|
||||
'en': en,
|
||||
'zh': zh,
|
||||
'zh-TW': zhTW,
|
||||
'ja': ja,
|
||||
'ko': ko,
|
||||
'fr': fr,
|
||||
'es': es,
|
||||
'de': de,
|
||||
'pt': pt,
|
||||
} satisfies Record<string, LocaleMessages>
|
||||
export const supportedLocales = ['en', 'zh', 'zh-TW', 'ja', 'ko', 'fr', 'es', 'de', 'pt'] as const
|
||||
export type SupportedLocale = (typeof supportedLocales)[number]
|
||||
|
||||
function isPlainObject(value: unknown): value is LocaleMessages {
|
||||
return !!value && typeof value === 'object' && !Array.isArray(value)
|
||||
@@ -42,11 +25,25 @@ export function mergeMessagesWithFallback(
|
||||
return merged
|
||||
}
|
||||
|
||||
export const messages = Object.fromEntries(
|
||||
Object.entries(rawMessages).map(([locale, localeMessages]) => [
|
||||
locale,
|
||||
locale === 'en'
|
||||
? localeMessages
|
||||
: mergeMessagesWithFallback(en, localeMessages),
|
||||
]),
|
||||
) as typeof rawMessages
|
||||
const localeLoaders: Record<string, () => Promise<{ default: LocaleMessages }>> = {
|
||||
'zh': () => import('./locales/zh'),
|
||||
'zh-TW': () => import('./locales/zh-TW'),
|
||||
'ja': () => import('./locales/ja'),
|
||||
'ko': () => import('./locales/ko'),
|
||||
'fr': () => import('./locales/fr'),
|
||||
'es': () => import('./locales/es'),
|
||||
'de': () => import('./locales/de'),
|
||||
'pt': () => import('./locales/pt'),
|
||||
}
|
||||
|
||||
export { en }
|
||||
|
||||
export async function loadLocale(locale: string): Promise<LocaleMessages | null> {
|
||||
if (locale === 'en') return en
|
||||
|
||||
const loader = localeLoaders[locale]
|
||||
if (!loader) return null
|
||||
|
||||
const mod = await loader()
|
||||
return mergeMessagesWithFallback(en, mod.default)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user