《Vue3 + TS 语言包:i18n Ally 不显示翻译?这份配置我踩完坑了》

13 阅读5分钟

在 Vue 3 + TypeScript 语言包项目中用好 i18n Ally(含 Monorepo)

如果你在用 Vue 3vue-i18n,文案放在 src/i18n/lang/*.ts 这种 TypeScript 对象里,而不是 json / yaml,装完 i18n Ally 后经常出现:

  • 代码里 t('xxx') 旁边不显示翻译
  • 侧边栏 / 编辑器里搜不到 key
  • 输出日志里明明已经 Loading locales,却像「半死不活」

本文按我们实际踩坑总结了一套可复现的配置,并标出最关键的一行代码(很多人卡在这里)。


一、适用场景

  • 编辑器:VS CodeCursor(底层兼容 VS Code 扩展)
  • 框架:Vue 3 + vue-i18nuseI18n() /模板里 $t
  • 语言包: .ts 文件,结构为嵌套对象,例如 menu.menuName
  • 仓库:Monorepo(语言包路径不在仓库根目录的 locales/,而在 apps/xxx/...

若你的项目完全符合以上几条,按下面做一般能一次点亮。


二、安装扩展

在扩展市场搜索:i18n Ally(发布者一般为 Lokalise,扩展 id常见为 lokalise.i18n-ally)。

安装后建议先 重载窗口Ctrl+Shift+PDeveloper: Reload Window


三、工作区配置(.vscode/settings.json

仓库根目录(Monorepo 一定是最外层根,而不是某个 apps/xxx)放 .vscode/settings.json,示例如下(请把 localesPaths 改成你真实的语言包目录):

{
  "editor.inlayHints.enabled": "on",
  "i18n-ally.localesPaths": ["apps/your-app/src/i18n/lang"],
  "i18n-ally.enabledParsers": ["ts"],
  "i18n-ally.enabledFrameworks": ["vue", "vue-sfc"],
  "i18n-ally.displayLanguage": "zh_CN",
  "i18n-ally.sourceLanguage": "zh_CN",
  "i18n-ally.languageTagSystem": "none",
  "i18n-ally.keystyle": "nested",
  "i18n-ally.pathMatcher": "{locale}.ts",
  "i18n-ally.namespace": false,
  "i18n-ally.monopoly": true,
  "i18n-ally.annotations": true,
  "i18n-ally.annotationInPlace": true,
  "i18n-ally.annotationMaxLength": 120,
  "i18n-ally.annotationDelimiter": " => ",
  "i18n-ally.theme.annotation": "#ff4d4f",
  "i18n-ally.theme.annotationBorder": "#ff4d4f55",
  "i18n-ally.regex.usageMatchAppend": [
    "\bt\(\s*['"`]({key})['"`]\s*[),]"
  ]
}

逐项说明(建议收藏对照)

配置项作用
localesPaths语言包目录,相对 Monorepo 根目录。写错层级 = 全盘不工作。
enabledParsers只开 ts,避免无关解析器干扰。
enabledFrameworksvue + vue-sfc 覆盖单文件组件。注意:没有 vue-i18n 这个枚举值,写了会被 VS Code 标红。
displayLanguage / sourceLanguage要和文件名 / 项目 locale 命名一致。你是 zh_CN.ts 就写 zh_CN,不要写 zh-CN(除非你真的用那种命名)。
languageTagSystem: none避免把 zh_CN 自动规范成 zh-CN 导致和文件名对不上。
keystyle: nested语言包是 { menu: { menuName: '...' } } 这种嵌套结构。
pathMatcher{locale}.ts 对应 en.tszh_CN.ts 等。
namespace: falsekey 已是 menu.xxx 形式时,避免再套一层「文件命名空间」逻辑。
monopoly: trueMonorepo 里减少和其它目录「抢解析权」的干扰。
annotations / annotationInPlace行内显示翻译注释的开关。
editor.inlayHints.enabled部分环境下行内提示依赖编辑器能力,建议打开。
regex.usageMatchAppend兜底匹配 t('key')(含 useI18n() 解构出的 t)。

主题色两行可按喜好删改;看不清注释时,用高对比颜色很管用。


四、语言文件:最关键的一行(export default

很多人语言包长这样(只有命名导出):

export const zh_CN = {
  menu: {
    menuName: '菜单名称'
  }
};

在部分版本下,i18n Ally 对 TS 语言包的索引会不稳定,表现为:日志里能加载文件,但树里搜不到 key、行内也不显示

解决办法:在文件末尾增加默认导出(与原有命名导出并存即可):

export const zh_CN = {
  menu: {
    menuName: '菜单名称'
  }
};

export default zh_CN;

其它语言同理,例如 en.ts

export const en = { /* ... */ };
export default en;

业务代码里继续 import { zh_CN } from './lang/zh_CN' 不用改,只是多了一条给工具链用的入口。


五、常用操作命令

  • 重载窗口Developer: Reload Window
  • 刷新用法I18n Ally: Refresh Usage
  • 打开 i18n Ally 编辑器I18n Ally: Open Editor

改完 settings.json 或语言包后,至少执行一次重载或 Refresh。


六、自查:输出面板看什么

Ctrl+Shift+U 打开输出,右上角通道选 i18n Ally(或带 i18n Ally 字样的通道)。

健康日志大致包含:

  • Workspace root 指向你的 Monorepo 根
  • Loading locales under ... 路径正确
  • 列出 zh_CN.ts / en.ts
  • 打开 .vue 时有 Loading sfc ...

若根目录错了,优先检查:是否用文件夹打开了 Monorepo 根,而不是只打开了 apps/xxx 子目录(子目录打开时,localesPaths 相对路径会对不上)。


七、常见坑速查

  1. enabledFrameworks 里写 vue-i18n

    Schema 不允许,会报错;用 vue + vue-sfc 即可。

  2. displayLanguage 写成 zh-CN,文件却是 zh_CN.ts

    显示语言与文件名不一致时,容易出现「加载了但匹配怪」的问题;统一命名或在设置里与文件对齐。

  3. 只打开子包目录

    localesPaths 是相对当前工作区根的;根不对则永远找不到语言包。

  4. 语言包只有 export const,没有 export default

    容易出现编辑器搜不到 key;按第四节补默认导出。


八、多应用 Monorepo

若多个 app 各有 src/i18n/lang,可将 localesPaths 配成数组,例如:

"i18n-ally.localesPaths": [
  "apps/app-a/src/i18n/lang",
  "apps/app-b/src/i18n/lang"
]

key 若在不同 app 中重复,要靠业务约定或拆工作区;一般团队会按 app 开窗口只把当前开发的 app 路径写进设置


九、结语

i18n Ally 对 JSON/YAML 支持最省心;TS 嵌套对象只要配对 路径 + 命名 + 默认导出,体验可以接近前者。若本文对你有帮助,欢迎转发;有其它栈(React、i18next)也可在评论里补充你的配置片段,方便后人检索。

参考


本文示例配置与说明基于 i18n Ally 2.x 行为整理;若你使用的版本较旧,建议升级到较新版本后再对照本文。