可在模块顶层用 await import() 加载语言包,结合 navigator.language 提取主语言码并设置 fallback,通过 try/catch 实现 locale 逐级降级加载,导出统一 messages 对象,注意协调 DOM 就绪时机。

可以在模块顶层直接用 await import() 加载对应语言包,配合环境判断和错误兜底,既简洁又可控。
根据 navigator.language 自动匹配
浏览器语言信息最可靠,优先取 navigator.language 或降级到 navigator.userLanguage:
- 提取主语言码(如
zh-CN→zh,en-US→en) - 预设 fallback 语言(通常是
en),避免小众 locale 导致加载失败 - 语言包文件建议按
locales/zh.js、locales/en.js组织
支持运行时 fallback 机制
单靠 await import() 容易因路径不存在而报错,应包裹 try/catch 并提供降级路径:
- 先尝试完整 locale(
zh-CN) - 再试主语言(
zh) - 最后回退到默认语言(
en) - 每个 import 都配
catch,不中断后续逻辑
导出统一的 messages 对象供全局使用
语言包模块应默认导出一个扁平对象(如 { hello: '你好', goodbye: '再见' }),顶层模块汇总后导出为命名空间:
- 用
const messages = await loadLocale(...)封装加载逻辑 - 确保最终
export { messages },其他模块可直接import { messages } from './i18n.js' - 避免在顶层重复 await,把加载逻辑收口到一个函数里更利于测试和复用
注意模块加载时机与 DOM 就绪的协调
如果语言包加载后要立刻渲染 UI,需确认 DOM 已就绪:
- 顶层 await 不等待
DOMContentLoaded,所以不能假定document.body存在 - 可在 await 后加
await new Promise(r => document.addEventListener('DOMContentLoaded', r)) - 或更稳妥地:在加载完成后,用
requestIdleCallback或queueMicrotask延迟渲染


















