但是要管理这些英文键名比较麻烦,命名就很头疼。而且阅读代码的时候也很难从键名快速识别出对应的中文。后面发现 VS Code 有相关的插件,可以显示出对应的中文,但是代码找起来还是有点麻烦。再加上产品的多语言版本一直没有提上日程,时间久了就嫌麻烦,慢慢地就直接在模板里写中文了。
结果,该来的还是来了。产品突然说最近要快速推出英文版,后续还有其他语言。一开始的想法是直接用 Chrome 浏览器自带的 Google 翻译功能,怎么快怎么来。但经过一番测试,发现了不少问题。
首先机翻的效果肯定是要打折扣的,但这还在接受范围内。最关键的是会影响到功能使用。什么问题呢?由于项目是用 Vue.js 开发的单页应用,页面内容完全是用 JS 动态渲染的。有些对话框内的文字 Google 翻译就忽略了。
另外,Google 翻译只处理了 DOM 文本节点,input输入框内的文字(包括placeholder)被忽略了。最严重的问题是,经过 Google 翻译处理后的 DOM 元素,竟然失去了 Vue 响应式特性,数据变化后 DOM 内的文字不会更新了!
如果要继续采用浏览器 Google 翻译的方案,就要解决这几个问题。通过调试发现 Google 翻译用的 JS 脚本是嵌入到浏览器 VM 里的,通过 HTTP 调用翻译服务,然后修改 DOM 元素。JS 脚本是压缩混淆过的,格式化后也很难看。想要找到更新 DOM 的代码,然后用自己的逻辑去覆盖?眼睛都看瞎了,还是算了。
Google 翻译JS代码
鉴于以上原因,浏览器自带的 Google 翻译方案基本不考虑了。
现在只剩下第二种方案了,语言配置文件和页面结构分离。前面提过,vue-i18n用得不彻底,如果把所有组件重新规范化,工作量太大了。有没有办法不修改现有代码,也能实现文本翻译呢?很自然地就想到了 Google 翻译的思路,直接对页面渲染结果进行翻译。自己翻译的优势就是,可以精细地控制 DOM 操作,比如可以把输入框里的文本和placeholder也翻译出来。
同时,经过研究发现,Vue 组件通过数据绑定渲染出来的 DOM 元素,包含的文本内容不能直接通过 innerHTML或者innerText修改,这样会导致响应式失效。解决办法是操作它的子元素,也就是文本节点(nodeType为3的节点),修改它的 textContent属性。
多语言配置映射表
跟 Google 翻译不同之处在于,我们采用静态翻译,也就是通过多语言配置文件映射。 vue-i18n 是每种语言准备一个 JSON 文件,属性名用英文,用命名空间(多层级对象)的方式避免命名冲突。我直接简化了,用一个 JS 对象存储所有语言版本,键名就是页面用到的中文。随着日积月累的开发迭代,这些中文散落在几百个文件里……我的做法是用 VS Code 全局正则搜索,把查找结果复制出来,写一个 JS 方法把这些字符串处理成 JS 对象。
前面提过,如果在 DOM 渲染后再执行翻译,页面性能非常差。于是想到了 Vue 本身的渲染过程,能不能拦截 Vue 组件渲染过程,插入一些额外的逻辑呢?通过扒源码发现,Vue 原型上有个__patch__方法,每次更新 DOM 的时候都会执行。就从这里入手, 重写这个方法,对还没挂载到文档树的 DOM 元素执行翻译操作。
Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。