5 分钟前端国际化

发布于 2024-11-08 23:19:33 字数 3868 浏览 0 评论 0

需要国际化的 react 项目已经迭代了 1 年多,文件众多,包含了 jsx 和普通的 js 对象文件。粗略估计有几千个中文词条。本文先介绍了采用的国际化方案,然后给出了国际化的过程和一个自己开发的脚本 i18n-pick ,按照教程,可以帮助前端 jsx 项目 5 分钟快速国际化。

方案选择

先大体上介绍下我选择的国际化方案。国际化方案很多,我这里列举主要的几种:

  • 编译期间转化:例如 wepack 的 i18n-webpack-plugin,打包的时候对_('key') 进行转义
  • 运行期间转化:react-intl 等,把中文词条写成 intl.get() 的方式,在运行时获取中文文案
  • wordpress 的 getText 方案:gettext 是一个 filter 钩子,用来替换和本地化翻译文本,替换 __()、_e()、_x()、_ex() 和 _n() 函数包含的文本

由于项目中我选择了 antd 作为视觉组件库。所以想和 antd 提供的官方的国际化方式保持统一。antd 推荐的是 react-intl,不过另一款类似的 react-intl-universal 也有不少人推荐,两者都比较成熟。所以我对两种进行了比较:

 react-intlreact-intl-universal
切换不刷新页面
js 文件支持(重要)
名词单双数,默认值,html
无破坏性劣(装饰器的代码实现会改变 ref)

名词单双数,默认值,html 这种功能两者都有。我这里就不多说了,具体的功能感兴趣的可以去看下 API。比较关注的其实是 js 文件支持那块。react-intl 只支持在 jsx 文件的内容中使用,但是由于项目配置化编程的缘故,很多中文是写在 js 对象中的。react-intl 不支持在普通 js 对象中使用,很不方便。而且他的装饰器实现会改变组件的 ref。他唯一的好处是他的切换不需要刷新页面,不过这种低频的操作刷新页面倒也无妨。

针对以上的原因,最终选择了 react-intl-universal 作为国际化方案。不过后来真实使用的时候,发现他提供的支持 js 对象的方式不是很好,于是还是直接采取了 react-intl-universal 的思想。简单的包装了下他们的依赖 intl-messageformat~这里不详细描述了,他的 api 官网文档可以查到。

国际化方案选择完了之后,开始执行阶段。以上无论是选择哪种方案,编码时基本都要求一种特殊的形式。要么 intl.get(),要么是文案前加上_#这种。对于已经迭代了很久的项目,这就涉及到了一项力气活。对中文文案进行提取以及替换。在这里就直接分享脚本 i18n-pick ,描述下整个的国际化过程了。

使用教程

主要分为 3 步,安装,扫描和提取,然后使用翻译工具来进行词条的翻译,具体步骤如下:

安装

cnpm i i18n-pick cnpm 用的淘宝镜像,会快一些。

扫描

./node_modules/i18n-pick/bin/i18n-pick.js scan [path] 命令最后的 path 选择你的代码目录,运行完成后会在项目根目录生成 i18n-messages 文件夹,包含 jsx.text,text.text 和 zh-CH.json 三个文件。具体实现是调用了 babel 的 transformFileSync 方法,在编译成语法树的时候,解析下面几种 babel-type

  • JSXAttribute
  • JSXText
  • AssignmentExpression
  • ObjectProperty
  • ArrayExpression

这里的基本含括了所有的情况,如果有遗漏的,欢迎联系我。将解析的这几种的 value 与/[\u4e00-\u9fa5]/进行比对。将包含中文文案的文件名,行数,文案内容记录下来。JSX 内的中文文案存到 jsx.text,一般 JS 内的中文文案存到 text.text。

分开存的原因是因为替换的时候,JSX 内的文案需要加上大括号才行。

同时我会把提取出来的文案内容存到了 zh-CH.json 中。这里为了配合翻译工具 atool-i10n 的使用,json 中的存储格式也是按照他的要求提供的。这里有个小 tip,参见附录。

提取

./node_modules/i18n-pick/bin/i18n-pick.js pick 然后执行 pick 操作,就是将 jsx.text,text.text 文件的内容按行分析,对文件进行内容替换。这里最开始我将 key 值定为了自增长的数字。为了保证源码一定的阅读性,我同时将原文案以 /**/ 注释的形式标在文末。后来,吸取了评论区 lany9527 同学的建议。将中文作为了 key 值~~然后我会在文件头部 import 一下依赖。

base/reactIntlUnicersal 这个文件需要自己放到自己的项目中,代码可以参考 链接

翻译

然后建议安装 atool-l18n 这种翻译工具,直接翻译成英文文案。就可以编译运行了~当然后续还得有一些 css 的调整工作。 cnpm i atool-l10n

node_modules/.bin/atool-l10n

总结

本文主要是分享了一个文案提取的脚本,来让前端 jsx 项目快速国际化。如有使用上的问题,欢迎在评论区询问~

tip

多谢评论区 lany9527 同学的建议,脚本已经更新。不再以自增长的数字作为 key 值了。换成以中文名作为 key 进行提取,已经更新脚本~

附录

1. 目前脚本不支持中文中有换行的情况,所以得修正下 scan 之后的三个文件的内容。并且这部分内容得手动去替换。不过这种情况很少,我的项目扫出 2000 个词条只有两条有这个问题。

2. 第二种是 pick 操作执行之后可能会编译出错,那是因为你的项目中可能手写了 \n 这样的文案,得手动处理下这种情况。

3. 第三种是不支持中文中含有 \" 的情况,这部分也得自己处理,原因是我以中文作为 key,为了提取后的值过 eslint,得用单引号引起来。就得对双引号单引号进行转义。无法处理已经转义过的内容。在完成了文案的转化之后可以再用 scan 命令扫描一遍,看下哪些没有处理好的,再手动处理下~

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

如梦亦如幻

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

回眸一遍

文章 0 评论 0

一心憧憬

文章 0 评论 0

沙与沫

文章 0 评论 0

mb_L9V1seZC

文章 0 评论 0

angellghost

文章 0 评论 0

旧梦荧光笔

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文