在 Vue 3 + TypeScript 语言包项目中用好 i18n Ally(含 Monorepo)
如果你在用 Vue 3、vue-i18n,文案放在 src/i18n/lang/*.ts 这种 TypeScript 对象里,而不是 json / yaml,装完 i18n Ally 后经常出现:
- 代码里
t('xxx')旁边不显示翻译 - 侧边栏 / 编辑器里搜不到 key
- 输出日志里明明已经
Loading locales,却像「半死不活」
本文按我们实际踩坑总结了一套可复现的配置,并标出最关键的一行代码(很多人卡在这里)。
一、适用场景
- 编辑器:VS Code 或 Cursor(底层兼容 VS Code 扩展)
- 框架:Vue 3 + vue-i18n(
useI18n()/模板里$t) - 语言包:
.ts文件,结构为嵌套对象,例如menu.menuName - 仓库:Monorepo(语言包路径不在仓库根目录的
locales/,而在apps/xxx/...)
若你的项目完全符合以上几条,按下面做一般能一次点亮。
二、安装扩展
在扩展市场搜索:i18n Ally(发布者一般为 Lokalise,扩展 id常见为 lokalise.i18n-ally)。
安装后建议先 重载窗口:Ctrl+Shift+P → Developer: 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,避免无关解析器干扰。 |
enabledFrameworks | vue + 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.ts、zh_CN.ts 等。 |
namespace: false | key 已是 menu.xxx 形式时,避免再套一层「文件命名空间」逻辑。 |
monopoly: true | Monorepo 里减少和其它目录「抢解析权」的干扰。 |
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 相对路径会对不上)。
七、常见坑速查
-
enabledFrameworks里写vue-i18nSchema 不允许,会报错;用
vue+vue-sfc即可。 -
displayLanguage写成zh-CN,文件却是zh_CN.ts显示语言与文件名不一致时,容易出现「加载了但匹配怪」的问题;统一命名或在设置里与文件对齐。
-
只打开子包目录
localesPaths是相对当前工作区根的;根不对则永远找不到语言包。 -
语言包只有
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 行为整理;若你使用的版本较旧,建议升级到较新版本后再对照本文。