动态导入语言包是现代JS国际化最轻量灵活的方式,需扁平命名规范、错误捕获降级、全局消息绑定、DOM实时更新及URL/LocalStorage运行时切换。

用 import() 动态导入语言包是现代 JS 国际化最轻量、最灵活的方式,它能按需加载、避免首屏冗余、天然支持代码分割。关键不是“能不能导入”,而是“怎么导入得稳、换得顺、兜得住”。
语言包组织要扁平 + 命名规范
把每种语言存为独立 JSON 文件,路径和命名必须可预测,否则动态拼接会出错:
-
✅ 推荐结构:
locales/en.json、locales/zh-CN.json、locales/ja-JP.json -
❌ 避免嵌套或不一致:
locales/zh/chinese.json或locales/en_us.json(下划线 vs 连字符) - 所有 JSON 文件保持 key 结构完全一致,比如都有
"submit": "Submit"和"submit": "提交",缺失 key 时靠降级逻辑兜底
用 import() 加载,但必须加错误捕获和回退
import() 返回 Promise,不能裸用。加载失败(如 404、网络中断)必须有 fallback,否则页面文案变空白:
- 先尝试加载目标语言,失败后立即加载默认语言(如
en) - 用
localStorage缓存已成功加载的语言包内容,避免重复请求 - 示例核心逻辑:
async function loadLocale(locale) {<br> try {<br> const mod = await import(`./locales/${locale}.json`);<br> return mod.default || mod;<br> } catch (err) {<br> // 加载失败,降级到 en<br> const fallback = await import('./locales/en.json');<br> return fallback.default || fallback;<br> }<br>}
加载后要绑定到统一翻译函数,并触发 DOM 更新
光加载进内存没用,得让 t('save') 能查到新内容,还得让带 data-i18n 的元素立刻刷新:
- 维护一个全局
messages对象,每次加载完就赋值:messages = loadedJSON -
t(key)函数只做一件事:查messages[key],查不到就返回 key 本身(避免空字符串) - 调用
applyTranslations()扫描并更新所有[data-i18n]元素的textContent或placeholder等属性
配合 URL 或 localStorage 实现运行时切换
用户点“切换成中文”,不能只改变量,要真正重新加载 + 渲染:
- 把当前语言存进
localStorage,下次打开自动读取 - 也支持 URL 参数(如
?lang=zh-CN),优先级高于 localStorage - 切换函数示例:
async function setLocale(lang) { messages = await loadLocale(lang); applyTranslations(); } - 注意:切换时不刷新页面,所有文本实时更新,适合 SPA 场景


















