最常见原因是路径拼错或模块解析失败,导致资源未加载;应先检查fetch/import路径、构建工具配置及JSON响应内容是否为纯JSON且无BOM。

为什么 i18n 配置文件根本没加载?
最常见的情况是路径拼错或模块解析失败,浏览器控制台里看不到请求,或者报 404。这时候别急着查翻译键,先确认资源是否真被拉下来了。
检查点:
- fetch 或 import() 的路径是否带了多余前缀(比如误写成 /locales/zh-CN.json,但实际部署在 ./locales/zh-CN.json)
- 使用 import.meta.url 构造相对路径时,没用 new URL(..., import.meta.url),导致路径解析错乱
- Webpack/Vite 等构建工具把 .json 当静态资源处理了,但没配 public 目录或没启用 asset 模块解析
JSON.parse 报错:Unexpected token ?
这通常不是语法问题,而是响应体不是纯 JSON —— 比如服务器返回了 HTML 错误页(404 页面)、重定向响应、或加了 BOM 头的 UTF-8 文件。
实操建议:
- 在 fetch 后加 response.text() 打印原始响应,确认内容是否为预期 JSON 字符串
- 用编辑器另存为「UTF-8 无 BOM」格式,尤其 Windows 下用记事本保存的 JSON 容易带 BOM
- 如果走后端接口(如 /api/i18n/zh-CN),确保接口 Content-Type 是 application/json,而不是 text/html 或 text/plain
键存在但值始终是空字符串或 fallback
说明配置读取成功,但运行时匹配逻辑出错了。常见于语言标签不一致(如代码里用 zh,但文件名是 zh-CN.json),或 Intl.Locale 解析后生成了带 unicode 扩展的 tag(如 zh-CN-u-ca-gregory)。
调试方法:
- 打印 navigator.language 和你实际传给 i18n 初始化的 locale 值,逐字符比对
- 检查是否启用了 fallbackLocale,且 fallback 文件存在;否则遇到未定义 locale 会静默回退到空对象
- 若用 vue-i18n 或 i18next,确认 loadPath 或 messages 是同步赋值还是异步加载完成后再调用 useI18n()
Vite / Webpack 中 JSON 被当作模块导入却没生效
ESM 下 import zh from './locales/zh-CN.json' 看似没问题,但若该 JSON 是动态路径(如 import(`./locales/${lang}.json`)),Vite 默认不支持带变量的 import() 动态导入 JSON,Webpack 则需配置 json 类型规则。
立即学习“前端免费学习笔记(深入)”;
解决方式:
- Vite 中改用 import.meta.glob('./locales/*.json', { eager: true }) 预加载所有语言包
- Webpack 5+ 可直接 import() JSON,但要确保 resolve.extensions 包含 '.json'
- 避免在 define 或 process.env 中硬编码 locale,它们在构建时就被替换成字符串,无法响应运行时切换
真正麻烦的往往不是读不到文件,而是读到了、解析了、也挂载了,但某个嵌套层级的 key 被意外覆盖,或 merge 逻辑把用户配置吞掉了——这种得靠打日志进 createI18n 内部的 messages 参数才能揪出来。



















