- Published on
我的国际化webpack插件
- Authors
- Name
- McDaddy(戣蓦)
自动国际化插件
安利一款自动化国际化插件 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作为国际化框架且只实现中翻英项目的插件,加入了一系列自定义配置项和对特殊情况的处理,具体流程参考下面的流程图
效果
每次编译后的自动翻译:
流程图
总结
通过此插件基本就把之前的主要手动流程都自动化了,开发者唯一需要关注的就是在最后提交代码前认真检查下locale文件的翻译结果是否合理。
此插件目前已经在FDP标品大规模铺开使用,稳定性已经得到了验证,欢迎试用和提bug
What's next?
既然可以通过遍历语法树在编译阶段改变源码,那么是否可以实现无侵入式的埋点?通过自定义一个埋点的属性在JSX中,遍历React.createElement
或者jsx.runtime
节点来动态抽取和替换节点。