国际化开发插件 i18n-Ally

i18n Ally

i18n Ally 这个插件,很早之前就从各种的 VS Code 插件分享贴中了解到,但是一直都没有好好利用起来。特别是我当前开发的项目是我自己魔改的一个国际化维护方式 i18n Ally 并不能很好的支持。
而我的一些个人项目,并不会使用到国际化。所以即使安装了这个插件已经有将近一年了,也没有使用起来。

这几天正巧要新增加一个语言到项目中,所以趁着这次机会就决定把插件使用起来。也可以做一次内部分享,方便一下同事。现在新增了很多国际化的需求,应该可以提供一些便利。

使用起来其实很方便,在 VS Code 当中安装完成,然后打开项目之后插件就会自动检测,要是当前项目已经有做国际化就可以直接在编辑器中看到效果了。

使用效果

这个时候可能会遇到一些问题,比如说会提示:

⚠ 没有找到文案文件。项目配置可能存在问题。

这个问题可能是由于两个情况导致的:

  1. 国际化目录自动检测失败,需要手动指定一下目录位置。

但是一般来说都会自动识别到的,我们可以在项目下的配置文件(.vscode/settings.json 或者 my-project.code-workspace)中查看到,是否已经自动配置了 i18n-ally.localesPaths 项。
所以最大的可能就是 👇

  1. 你的本地化语言配置文件是 .js 或者 .ts 后缀的(或者其他)。

这种情况的话,需要在上面提到的配置文件中配置 i18n-ally.enabledParsers 属性,开启对应的格式支持(当然也可以配置在全局)。

💡 From v2.0, formats other than JSON, YAML and JSON5 would be disabled by default.
💡 从 v2.0 开始,除 JSON, YAMLJSON5 以外的格式将默认禁用。
Locale Formats · lokalise/i18n-ally Wiki

一般来说问题就解决了,可以直接在编辑器打开任意使用到国际化插值的文件中查看到预览效果。例如标识符 {{ $t('common.hello') }} 显示成对应的本地化文本 {{ $t(你好) }}


🤦‍♂️ 也许会有一些其他的问题

有些同学会出现没有错误提示,但是在当前打开的文件中并没有查看到标识符被替换成为对应的语言文本内容。
仍然显示的是 {{ $t('common.hello') }} 这样的形式,并没有出现文本预览效果。

并且打开 i18n-Ally 面板检查 翻译树翻译进度 也查看不到文案内容,或者只有一部分的文案内容。这个时候需要打开输出面板(Ctrl + Shift + U ),并且在右侧下拉栏中切换到 i18n-ally 来查看具体的异常信息输出。

比如说我当前的开发项目,就是我当时魔改的一个国际化方案,是以数组的方式来维护国际化文本的:

// user.js
import { transferLocaleConfig } from '@/i18n/config'

const config = {
  'account': ['工号', 'No.'],
  'name': ['姓名', 'Name'],
  'company': ['公司', 'Company'],
  'dept': ['部门', 'Department'],
  'tel': ['电话', 'Tel'],
  'email': ['邮箱', 'E-Mail']
}

export default transferLocaleConfig(config)

因为当时并没有了解到 i18n-ally 这个插件,如果像一开始的方式直接维护 json 文件,就总是会出现一些意外情况:

  • 忘了翻译或者遗漏一些文本;
  • 多个语言的国际化文本 key 键不一致,或者命名空间冲突;

所以我改造成这样的方式维护国际化文件的,这样就不会出现上面的两个问题了。
但很明显我在引用的 config.js 文件的时候使用了别名 @,所以 i18n-ally 插件解析文件失败了。

可以从面板中看到这个报错信息:

🗃 Path Matcher Regex: /^(?<locale>[\w-_]+)\.(?<ext>m?js)$/

📂 Loading locales under d:\my_project\src\i18n
  📑 Loading (index) index.js [1710479593993.5425]
    🐛 Failed to load Error: Command failed: node "c:\Users\yogwang\.vscode\extensions\lokalise.i18n-ally-2.12.0\node_modules\ts-node\dist\bin.js" --dir "d:\my_project" --transpile-only --compiler-options "{\"importHelpers\":false,\"allowJs\":true,\"module\":\"commonjs\"}" "c:\Users\yogwang\.vscode\extensions\lokalise.i18n-ally-2.12.0\assets\loader.js" "d:\my_project\src\i18n\index.js"
Error: Cannot find module '@/i18n/config'
Require stack:
- d:\my_project\src\i18n\modules\user.js
- d:\my_project\src\i18n\en.js

修改改为相对目录,不使用别名引入就可以了。


但是使用 .js 文件的方式来维护可能会缓存的情况,比如说:

#1 当我添加了一些新的国际化字段之后,可能 i18n-ally 就不会对这些新增的文本做出更新响应。

这个问题 antfu 大佬当时说没有好的解决方式来绕过 👉 Need to restart vs code to update · Issue #97 · lokalise/i18n-ally
不过最后看到有一个PR解决了这个问题,但是我这边并没有即时更新,仍然需要重新加载VSCode才可以看到更新。

#2 不能使用 i18n-ally 这个插件提供的一些辅助功能,比如说 提取硬编码编辑模式

在文档中可以看到对于各种格式的支持情况,对于 jstsread-only
所以我并不建议大家学我这样的方式来处理,antfu 大佬也是建议使用 json 文件,以获得更好的插件支持。
👉 can’t make localepaths work · Issue #172 · lokalise/i18n-ally

Format Read Write Annotations Note
JSON
YAML Comments will NOT be preserved*
JSON5 Comments will NOT be preserved*
INI Comments will NOT be preserved*
properties Comments will NOT be preserved*
POT
JavaScript Read-only
TypeScript Read-only
PHP Read-only

其实可以借鉴插件仓库中的各种样例找出一个适合自己的实践方式 👉 Examples - lokalise/i18n-ally

另外的一些其他的常见问题可以查看文档中的 FAQ 👉 FAQ · lokalise/i18n-ally Wiki


🏃‍♂️ 使用 & 提速

前面我展示了 i18n-ally 对于翻译预览的辅助功能,对于文案的提取和编辑只是提了一嘴并没说如何使用。
插件对于文案的提取分为 手动提取自动提取(单文件 和 目录提取都可以)。但是前提都是项目的国际化文件被正确识别到了,并且是支持写入的格式。

使用手动提取的方式就是插件文档中提到的提取方式。文案被识别到之后悬停并点击 快速修复 选择 提取文案到i18n,也可以在左侧活动区块找到翻译字段面板在 hard-coded string 中选择对应的文案提取。

  • 这个时候如果文本有对应的翻译了,会直接在下方显示已存在的翻译文案,直接按序点选就完成提取和替换了。
  • 如果没有被翻译过,那么就需要手动输入键名来创建词条
    • 在输入键名的时候会在下方提示当前属性下的其他翻译文本,来辅助我们创建词条。

操作完成之后插件会自动在源语言配置文件中创建对应的词条了。
如果还想编辑其他的翻译文本,那么可以继续悬停,选择对应的语言来编辑,或者选择自动翻译(谷歌翻译可能会出现翻译失败需要调整翻译API)。也可以进入审阅模式同时编辑多种语言的翻译文本。

自动提取的话,就是整个组件开发完成之后在左侧文件管理器中找到目标文件/目录右键打开菜单选择 Extract all hard-coded strings(experimental) 就可以自动提取了。
自动提取时如果已经存在的文本,会自动替换成已经存在的国际化标识。如果不存在的话,就会把中文自动转换成拼音来创建对应的词条。

这个时候就会遇到一个问题,全部的词条都是扁平化的,不能按照命名空间的方式来创建。因为默认 namespace 是关闭的,需要手动开启并且配置 pathMatcher 规则。 👉 Namespaces · lokalise/i18n-ally Wiki
这部分比较麻烦,还没有好好研究,但是应该有提供示例 👉 Path Matcher · lokalise/i18n-ally Wiki 可以参考文档中给出的配置。

🌏 翻译进度 & 使用情况分析

项目开发到一定进度的时候,我们会不清楚是否所有的语言是否都已经完成了翻译工作,以及是否有一些翻译文本已经被删除了,但是业务组件中仍在使用。就需要用到 翻译进度使用情况分析 两个面板了。

使用情况分析

可以看到各个语言翻译的进度,会汇总全部语言的所有文本词条。如果有缺失没有翻译的,就可以在这里检查到。
以及一些已经在组件中使用,但是并没有完成国际化翻译的词条。


最后

可能有些人会好奇 /i18n/config.js 文件里面的内容,其实就是简单把数组结构替换成为对象的处理:

// i18n/config.js
const languageList = ['zh-cn', 'en']

// 创建一个空i18n对象
const createEmptyLocaleConfig = () => Object.fromEntries(languageList.map(key => [key, {}]))

// 配置文件转i18n对象
export const transferLocaleConfig = (data) => {
  const localeConfig = createEmptyLocaleConfig()
  for (const key in data) {
    languageList.forEach((lang, index) => {
      localeConfig[lang][key] = data[key][index]
    })
  }
  return localeConfig
}

然后在 en.js 中引入和然后使用 export default 导出聚合后的内容,就可以在 i18n-ally 中被正确分析到了。

// en.js
import common from './modules/common'
import user from './modules/user'

export default {
  ...common['en'],
  ...user['en'],
}

至于在 vue-i18n 中如何使用就是简单的 import 之后使用就可以了

// i18n/index.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'

// ...
import zhJson from './zh_cn'
import enJson from './en'

Vue.use(VueI18n)

const messages = {
  'zh-cn': {
    // ...
    ...zhJson
  },
  'en': {
    // ...
    ...enJson
  }
}

const i18n = new VueI18n({
  locale: localStorage.getItem('language') || process.env.VUE_APP_I18N_DEFAULT,
  messages
})

export default i18n

相关资源

i18n Ally - Visual Studio Marketplace
Examples - lokalise/i18n-ally