# 多语言机制与使用方式

  • 支持用户设置偏好语言(language),持久化保存
  • 用户访问 Engage 网页时,系统会先获取用户的偏好语言。如果没有,则取浏览器内 localStorage 设置(localStorage.getItem('engage-language')),可选的值有 en-US 、zh-CN 。
  • 读取微前端工程目录下的 i18n/index.js,加载所有语言的 locale messages。
  • 将 locale messages 作为 createMfeApp 的 i18nMessages 参数传入
  • Vue 会加载 vue-i18n 插件,为接下来的每个组件实例注册 $t() 方法。
  • 组件内使用 $t(key)this.$t(key) 来执行多语言展示

# 关于 key

由于前期我们的组件内基本使用中文描述,所以我们的多语言 key 也是以中文为基础。为了避免多个微前端之间相同中文在不同情境下翻译不同可能造成冲突,要求每个前端工程有对应的 key prefix。这样,一个 key 就是由 prefix + 中文构成,如 e:确定 表示的是 engage-common-fe 工程里中文确定的多语言 key,pt:确定 表示的是 platform-mfe 工程里中文确定的多语言 key。prefix 的取值可以跟应用的缩写保持一致。如 wechat-mfe 工程内,key 前缀是 wc:

# 历史数据改造方法

@engage/fe-cli 提供了多个脚本,用于最大可能性地自动识别、抽取 i18n key。它的原理是基于中文的正则匹配,外加对 vue template、script 等上下文的判断,实现较为智能的自动识别哪些地方需要进行多语言改造。当然,也不能完全依赖此工具。在工具运行完后,还要配以人工审查、查漏补缺等方式确保完整性、准确性。下面是具体的实施步骤。

# 1. 工程配置

  1. 首先确保工程 workspace 内没有任何脏数据,即所有的修改都已提交(commit)到 Git 仓库。
  2. 更新 @engage/fe-cli 到最新版:yarn add @engage/fe-cli -D -E --registry=http://registry.npm.gridsum.com
  3. 在 package.json 中增加 i18nPrefix 属性。一般使用应用缩写,如 "i18nPrefix": "pt:","i18nPrefix": "wf:",

如果工程有遗留的 $l() 等方法,需要自行删除(可以用正则移除)。$l() 已经不再支持了。

# 2. 自动识别多语言位置

在工程根目录下,运行 node_modules/.bin/engage-fe-cli-i18n-detection,将会自动识别中文,替换为 $t('<prefix><中文>')。执行完后,需要进行人工审查。方法如下:

  1. 将 VSCode 拖到大屏幕上,宽度最大化

  2. 打开 VSCode Git 视图,查看到所有的文件变化,一个一个打开对比窗口。

  3. 对于 vue template 中的识别,属性(props)需要自行在前面增加 :,否则会变成一个纯字符串。示例如下:
    image

    • 这里需要在属性前面加 :,CMD+S 保存后,VSCode(eslint-vue-plugin)会自动将其格式化为
      image
  4. 对于英文与中文混搭使用的,脚本不能识别。如 创建 SSO 用户 会被识别为两段,$t('创建') SSO $t('用户')。这在某些地方会产生代码错误,而且业务上说还是合在一起好。这种地方就需要手动修正了。

  5. 如果组件内文件级全局变量里也有中文,这里替换后再运行是会产生运行时错误的(因为 this 是 undefined)。可以把这些全局变量迁移到组件的 data(){} 中,或使用其他方法改造。
    image

  6. 人工检查下各个文件,看是否还有漏的地方

i18n-detection 虽然被设计为可以支持重复、多次运行,但一般此步骤只需要执行一次。您可以尝试多次运行,但一定要确保是在代码文件已经 Stage 或 Commit 后再进行,否则可能产生的数据混乱,我可不负责任哦😯

# 3. 自动抽取多语言 Key

当所有的地方都使用 $t() 替换后,就可以运行 node_modules/.bin/engage-fe-cli-i18n-extract 来自动抽取出 i18n key 了。它会自动生成 src/i18n/index.jssrc/i18n/zh-CN.jssrc/i18n/en-US.js 三个文件。其中 zh-CN.js 已经翻译完毕,en-US.js 为待翻译文件。稍后就可以把 en-US.js 发给产品或运营人员,由他们进行翻译。

i18n-extract 是可以多次运行的。

# 4. 微前端中注入

在 createMfeApp 中传入 i18nMessages 即可

import i18nMessages from './i18n';

const mfeApp = createMfeApp({
  component: App, router, i18nMessages,
});

# 5. 运行工程并验证

  1. npm run dev,运行一下代码
  2. 确认命令行不会有报错
  3. 确认界面上中文显示都正常
  4. 在浏览器 DevTools 中,设置语言为英文(localStorage.setItem('engage-language', 'en-US'))。
  5. 刷新下页面,查看英文效果(此时原中文部分应该展示为空白)
  6. 填充 en-US.js 中某个 key 的翻译,查看界面上是否有了。如果有值,说明改造成功。

# 以后多语言代码怎么写?

后面还是以中文为主写代码,只是在需要翻译的地方,使用 $t(<prefix><中文>),而不是纯粹的中文啦。然后使用 node_modules/.bin/engage-fe-cli-i18n-extract 重新提取一下 Key 就好了。