构建工具提取html待翻译文本需覆盖data-i18n类属性、textcontent及js模板字符串;语言包须扁平化、统一命名规范、按需动态加载,并禁用json key混淆,否则运行时留白或失效。

怎么用构建工具提取 HTML 里的待翻译文本
构建时自动提取文案,比人肉 grep 或手动维护 key 列表靠谱得多。但提取逻辑必须覆盖所有实际渲染的文本来源,否则漏掉的 key 会在上线后留白。
-
data-i18n、data-i18n-placeholder、data-i18n-title这类属性是提取主入口,工具需能识别带后缀的变体 - HTML 中内联
textContent(如<p>登录</p>)不能被忽略——很多团队只扫 data 属性,结果静态文案全翻不了 - JS 模板字符串里拼接的文案(如
document.querySelector('h1').textContent = '欢迎';)需要 Babel 插件或自定义 AST 解析,i18next-parser支持但默认不开启 - 提取后生成的 key 必须统一小写+下划线,避免
navHome和nav_home冲突;建议加前缀隔离模块,比如login.submit_btn
JSON 语言包怎么组织才不被构建流程拖垮
构建工具(如 Webpack/Vite)加载语言包时,路径和结构稍有偏差就会静默失败,不是报错而是 fallback 到空字符串。关键不在“有没有”,而在“能不能被 resolve 到”。
- 语言文件路径必须固定:建议统一放在
src/locales/en-US.json、src/locales/zh-CN.json,不要嵌套多层或用动态文件名 - 每个 JSON 文件必须扁平结构,禁止嵌套对象:
{"common": {"submit": "提交"}}是错的,应为{"common_submit": "提交"} - Vite 用户注意:
import.meta.glob加载多语言包时,路径通配符必须匹配实际文件名,glob('./locales/*.json')不会匹配./locales/zh-Hans.json如果文件名含连字符但 glob 没声明 - Webpack 的
require.context要显式指定扩展名,require.context('./locales', false, /\.json$/)比/\.js$/少个字母就全挂
构建产物里如何避免语言包体积爆炸
全量打包所有语言包进 JS bundle,会让首屏加载变慢,尤其当支持 10+ 语言时。按需加载不是可选项,是必须项。
- 用
import()动态导入语言包,而不是import zh from './locales/zh-CN.json'—— 后者会让 Webpack 把它打进初始 chunk - Vite 中推荐写法:
const lang = await import(`../locales/${locale}.json`),配合build.rollupOptions.output.manualChunks把各语言包单独切出 - Webpack 需配置
splitChunks.chunks: 'all'并确保 language 文件路径满足 chunk 分割条件,否则import()仍可能被合并 - 别在构建时做语言包合并(如把 en + zh 打包成一个对象),这会让 tree-shaking 失效,未使用的语言键依然留在产物里
切换语言时 DOM 更新为什么失效或错乱
构建后的代码跑在浏览器里,但很多问题根源其实在构建阶段埋下的——比如事件监听器绑定方式、模板编译时机、或 SSR 与 CSR 渲染差异。
- 如果用了 Vue 或 React,且组件内文本靠
t('key')渲染,构建时没启用响应式更新机制(如 Vue 的watchlocale 变化、React 的useEffect监听),切换语言后 DOM 不刷新 - 纯 HTML + JS 方案中,若构建时把翻译函数打进了 IIFE 或立即执行闭包,而没暴露全局接口,运行时调用
translate()会报ReferenceError - SSR 渲染的页面,构建时若没把服务端语言检测结果注入到前端上下文(如
window.__INITIAL_LOCALE__),客户端初始化就会用错语言,再切也晚了 - 最隐蔽的坑:构建压缩(Terser)把语言包 key 名混淆了,比如
"btn_submit"被缩成"a",而 HTML 里写的还是data-i18n="btn_submit"—— 关键要关掉 JSON 文件的 mangling
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











