要让 Vite 将国际化词典单独打包成独立 chunk,需在 vite.config.ts 中通过 rollupOptions.output.manualChunks 匹配 src/locales/*.json 路径,为每种语言生成如 locales-zh-CN.[hash].js 的专属 chunk;同时改用 import(../locales/${locale}.json) 动态加载,并通过占位引用或插件防止 tree-shaking 误删。

要让 Vite 把国际化词典(语言包)单独打包成独立 chunk,核心是利用 rollupOptions.output.manualChunks 配合模块路径识别,同时避免语言文件被合并进主包或 vendor。关键不在“多语言切换逻辑”,而在于构建时让每个语言 JSON 文件生成专属 JS chunk,并确保运行时能按需加载。
语言文件统一放在 src/locales 下
结构清晰便于识别和管理:
src/locales/zh-CN.jsonsrc/locales/en-US.jsonsrc/locales/ja-JP.json
不建议直接 import 所有语言文件(如 import zh from './locales/zh-CN.json'),否则会全量打入 bundle。应改用动态路径 + import() 或通过插件控制打包时机。
在 vite.config.ts 中配置 manualChunks 拆分语言包
利用 Rollup 的分片机制,匹配语言文件路径,为每种语言生成独立 chunk:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
build: {
rollupOptions: {
output: {
manualChunks(id) {
// 匹配 src/locales/*.json 路径
const localeMatch = id.match(/src[/\]locales[/\](w+-w+).json$/);
if (localeMatch) {
return `locales/${localeMatch[1]}`;
}
}
}
}
}
这样构建后会生成类似 locales-zh-CN.[hash].js、locales-en-US.[hash].js 等独立文件,不混入 vendor 或 main。
配合 vue-i18n 或 i18next 实现按需加载
以 vue-i18n v9 为例,语言包不再静态 import,而是运行时动态加载:
// composables/useI18n.ts
export function loadLocaleMessages(locale) {
const messages = import(`../locales/${locale}.json`)
.then((mod) => mod.default)
.catch(() => ({}));
return messages;
}
搭配 i18n.setLocaleMessage(locale, messages) 使用,确保只加载当前需要的语言,其他语言 chunk 不会进入初始加载。
注意避免 tree-shaking 误删语言文件
如果语言文件未被任何代码显式引用(比如纯靠字符串拼接路径加载),Vite 构建时可能因 tree-shaking 移除它们。解决办法有两个:
- 在入口或某个常驻模块中做一次“占位引用”:
import '../locales/zh-CN.json'; import '../locales/en-US.json';(仅用于保留,不实际使用) - 使用
vite-plugin-static-import或自定义插件,在 build 阶段强制将 locales 目录下所有 JSON emit 为 chunk
推荐后者,更干净可控,也适配懒加载场景。

















