Published on

我的国际化webpack插件

Authors
  • avatar
    Name
    McDaddy(戣蓦)
    Twitter

自动国际化插件

安利一款自动化国际化插件 ts-auto-i18n-plugin

为什么要有一个插件

之前我写了一个auto-i18n的脚本,通过交互式的命令行操作把国际化的整个流程串联起来,主要解决了自动翻译和步骤过于琐碎的问题,但是没有解决国际化依然是一个额外操作的本质问题。作为一个毫无技术含量的开发步骤如何做到0负担是这个插件的实现目标。

要解决的问题

  • 在编写代码的过程中,自动得去完成i18n的抽取翻译和locale资源文件替换
  • 与当前的国际化方案需要兼容
  • 更方便的命名空间管理,想象下现在如果想把一个词从A空间迁移到B空间要花几个步骤?也是因为这个手动成本太高,目前项目中存在非常多重复的翻译存在于不同的空间下
  • 生产模式下,如何确保__NOT_TRANSLATED__不会被打包进去
  • 解决Google Translate API的稳定性问题
  • 实现在代码中只写中文,做到更直观的开发体验(每次从页面关键字找源文件,总是要隔着一个zh.json特别难受), 顺便避免英文翻译过长需要自定义short key的问题。之前想通过JSDoc来解决这个问题,但是成本还是有点大。当然这个问题的最直接解决方法不是本插件的目的,最彻底的解决方法应该是把默认语言设置为中文,但是老项目要改成本太大

实现过程

如何实现抽取和转化

loader实现法

最开始的实现版本是想写一个loader来通过正则表达式来匹配包装后的i18n源码,从而做到自动的抽取和翻译。但是发现的问题是正则有匹配错误的风险,最主要体现在正则很难忽略被注释的代码,同时要考虑各种奇怪的写法如何匹配,虽然可以适配但是成本比较高

// i18n.('测试')
/** 
	i18n.('测试') 
*/

i18n.s('测试',  // 换行+注释
'fdp')

语法树实现法

相对而言效率更高,无匹配错误的方案。模仿了下ts-import-plugin的实现,遍历语法树的同时还能做到生成新的语法树节点(i18n.t)替换原来的i18n.s

如何实现自动翻译

在开发模式下,启动一个自动轮询,自动收集语法树解析后得到的未翻译的语句列表,然后交给Google Translate API解决

如何解决翻译不稳定问题

调研了下Google Translate的服务机制,对免费用户确实不会太友好,但是可以通过申请Google Cloud账号用免费流量来解决

解决通用性的问题

目标这是一款可以用于所有用i18next作为国际化框架且只实现中翻英项目的插件,加入了一系列自定义配置项和对特殊情况的处理,具体流程参考下面的流程图

效果

demo

每次编译后的自动翻译:

image-20210119134645568

流程图

i18n-plugin

总结

通过此插件基本就把之前的主要手动流程都自动化了,开发者唯一需要关注的就是在最后提交代码前认真检查下locale文件的翻译结果是否合理。

此插件目前已经在FDP标品大规模铺开使用,稳定性已经得到了验证,欢迎试用和提bug

What's next?

既然可以通过遍历语法树在编译阶段改变源码,那么是否可以实现无侵入式的埋点?通过自定义一个埋点的属性在JSX中,遍历React.createElement或者jsx.runtime节点来动态抽取和替换节点。