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
@@ -5,9 +5,10 @@ const highlightJsMock = vi.hoisted(() => ({
|
||||
highlight: vi.fn((content: string, { language }: { language: string }) => ({
|
||||
value: `<span class="mock-${language}">${content}</span>`,
|
||||
})),
|
||||
registerLanguage: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('highlight.js', () => ({
|
||||
vi.mock('highlight.js/lib/core', () => ({
|
||||
default: highlightJsMock,
|
||||
}))
|
||||
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { describe, expect, it, beforeAll } from 'vitest'
|
||||
import { readdirSync, readFileSync } from 'fs'
|
||||
import { join, relative } from 'path'
|
||||
|
||||
import { changelog } from '@/data/changelog'
|
||||
import { messages, rawMessages } from '@/i18n/messages'
|
||||
import { loadLocale, supportedLocales } from '@/i18n/messages'
|
||||
import en from '@/i18n/locales/en'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
|
||||
const SOURCE_ROOT = join(process.cwd(), 'packages/client/src')
|
||||
|
||||
const allMessages: Record<string, Record<string, unknown>> = { en }
|
||||
|
||||
function walkFiles(dir: string, files: string[] = []): string[] {
|
||||
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
||||
const path = join(dir, entry.name)
|
||||
@@ -93,15 +97,23 @@ function labelLength(value: unknown): number {
|
||||
}
|
||||
|
||||
describe('i18n locale coverage', () => {
|
||||
// Keys that are newly added but not yet translated in all locales
|
||||
const ALLOWED_MISSING_KEYS = new Set([
|
||||
'changelog.new_0_5_4_7',
|
||||
'chat.sessionNotFound',
|
||||
])
|
||||
|
||||
beforeAll(async () => {
|
||||
const results = await Promise.all(
|
||||
supportedLocales.filter(l => l !== 'en').map(async l => {
|
||||
const msgs = await loadLocale(l)
|
||||
if (msgs) allMessages[l] = msgs
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('defines every statically referenced translation key in the English source locale', () => {
|
||||
const missing = collectLiteralTranslationKeys()
|
||||
.filter((key) => !hasPath(rawMessages.en, key))
|
||||
.filter((key) => !hasPath(en, key))
|
||||
.filter((key) => !ALLOWED_MISSING_KEYS.has(key))
|
||||
|
||||
expect(missing).toEqual([])
|
||||
@@ -109,7 +121,7 @@ describe('i18n locale coverage', () => {
|
||||
|
||||
it('defines every statically referenced translation key in effective runtime messages', () => {
|
||||
const requiredKeys = collectLiteralTranslationKeys()
|
||||
const missing = Object.entries(messages).flatMap(([locale, localeMessages]) =>
|
||||
const missing = Object.entries(allMessages).flatMap(([locale, localeMessages]) =>
|
||||
requiredKeys
|
||||
.filter((key) => !hasPath(localeMessages, key))
|
||||
.filter((key) => !ALLOWED_MISSING_KEYS.has(key))
|
||||
|
||||
@@ -42,6 +42,9 @@ vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: (key: string) => key,
|
||||
}),
|
||||
createI18n: () => ({
|
||||
global: { locale: { value: 'en' }, setLocaleMessage: vi.fn() },
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/useTheme', () => ({
|
||||
|
||||
Reference in New Issue
Block a user