我是前端西瓜哥。考虑到年后就是程序员跳槽的高峰期,从今天开始我的公众号日更内容全面转向 Web 前端面试和跳槽相关话题。
西瓜哥我前几个月入职新公司,接手了同事的国际化需求。陆陆续续搞了几个月,发现国际化看起来简单,实际落地却是困难重重。
因为国际化是系列工程,是需要团队所有成员在整个产品的迭代开发的每个流程中去考虑的。
本文就从前端开发的角度在国际化遇到的问题。
国际化是什么?
国际化怎么理解?狭义上指的是产品可以提供除了本地外的其他国家的文案的能力。更准确来说,国际化是让产品和服务能够适应不同国家地区,打入它们的市场。国际化的英文为 internationalization,为了方便,通常会简写为 i18n(开头的 i、中间的 18 个字符、末尾的 n)。
一个好的产品国际化,应该是从产品设计之初就考虑国际化的,并且在迭代设计开发中也要考虑进来。这样能大量减少后期为支持更多语言而修改设计和代码所耗费的时间精力。
但实际上国内公司的产品的目标用户主要是国内用户。他们对出海抱有迟疑的态度,对出海的业务并不抱太大期待。当然随着国内市场日趋饱和,不少公司尝试将产品出海并且其中一些获得了不少成果,比如 tiktok。总体上国内的产品基本上不会在设计之初就非常认真地考虑国际化的。
比较常见的情况是,产品开发到一定程度,想要尝试进军海外,才出现了国际化需求,这个需求往往是长期的,需要一点点改造系统。我就是这种情况。原因是一个客户有海外部门,希望支持英语。
判断用户的语言
要实现国际化,首先要确定用户的语言。
对于浏览器,前端可以通过 navigator.language
拿到用户的语言,后端则可以通过 HTTP 请求的 Accept-Language
头字段判断。当然用户自信设置语言也要进行考虑。
我们需要考虑的场景很多:
- 用户设置了语言;
- 用户未设置语言;
- 一个不需要校验用户的接口;
- 用户收到的邮件应显示的语言;
- 按需加载语言包。解决方案可以看我的一篇旧文:前端国际化,该如何实现按需加载语言包?
语言的标准
很遗憾,国际化并没有语言标识符的标准,这会让在我们开发时遇到很多问题。
比如简体中文的标识可以为 zh
、 zh_CN
和 zh-CN
,每个人的理解不同,可能会选择不同的标准,和同事对接时就需要做额外的工作:不同标准的语言标识符之间的转换。
涉及到国际化的第三方库也可能会出现这种问题。
所以我们需要设置一个标准,并要求团队内的成员都遵循这个标准。建议参照流行的国际化库使用的标准,也就是 BCP 47 语言标记。
样式
不同语言表达相同的意思,需要的文本量不同,这就导致文案长度不固定。这就要求我们在视觉设计和开发时就要进行考虑。
我接手国际化需求后,发现过去的视觉设计和开发没有考虑到国际化的情况。
比如一些按钮,只有两个汉字的宽度,开发就写死宽度,让文字居中了。但需要国际化翻译为英文后发现这个宽度就放不下了,需要改为按钮不设宽度并设置 padding 来自适应文字。
有些宽度固定,考虑国际化后可能要重新设计,最后设计师说我们把文字截断加上省略号吧,划上去可以通过 tooltip 查看完整文案。这是相当别扭的做法。
总结几个设计和开发考虑国际化,需要注意的点:
- 考虑可能会换行的情况;
- 尽量不要使用固定宽度;
- 设计列表时,尽量考虑纵向排布而不是横向排布;
- 考虑空格的情况,这个是针对词之间留空格的情况。flex 布局下,空格会被忽略,需要做特殊处理。
文案维护
国际化比较麻烦的是文案维护工作。
理论上我们需要将不同的语言放到不同的 JSON 文件里,比如 zh-CN.json
和 en-US.json
。它们都会有相同的 key,然后 value 是不同的。语言包按需加载后,我们在代码中可以通过 t('confirm')
拿到文案 确认
或是 Confirm
。
一个方案是程序员手动增删修改 JSON 文件的字段,提交代码时很容易出现冲突问题,产品也无法直接对文案进行配置,需要程序员帮忙,就会造成一些沟通成本。
也有更好的方案,就是我所在公司使用的方案是 使用在线协作表格,我们维护一个含有不同国家标志符字段的表格,让开发和产品在上面配置不同国家的文案。改好后,开发就会拉取表格内容转换为 JSON 文件。
但是,这两种方案都会有相同的一些问题:
- 一些废弃的文案没有删除,主要是不敢删,怕出问题。有个方案是扫描项目代码,移除没用到的文案,但前提是我们用的 key 不能是动态的,这样才能不出现遗漏。
- 复用还是语义化。一些文案可能会在多个模块中重复出现,理论上可以都用同一个文案 id,以减少文件大小。但是可能过了一阵子,某个模块的文案做了修改,导致其他模块不需要改的文案也跟着变动了。可以让不同的模块分别用各自的 key,但带来的是文件数据的冗余。复用还是语义化,这是要考虑的问题。
- 不好管理。谁不小心删了某一行、某个字段,我们是较难发现的。
- 重复问题。出现了多个相同的 key,读取 JSON 数据的时候就会只保留一个。
其他
- 自己公司设计的组件库,也需要将国际化的考虑进去。如果不考虑,每个用到的地方都要手动传入文案,开发体验极差。
- 货币、时间等习惯问题。如果你是当地人,可能就无法判断文案是否合理。
- 后端接口返回的错误信息也要做国际化。
产品的国际化是一个系统工程,开发的每个流程都需要考虑,需要考虑的细节也很多。看起来只是替换文案,其实里面涉及到了相当多的子场景和方案。
我的这篇文章只是说了文案的替换,是狭义的国际化。一个真正合格的国际化,应该还要考虑用户使用习惯,针对不同国家进行不同的运营活动等这些非技术层面的东西。
我是前端西瓜哥,致力于分享 Web 前端开发技术,欢迎关注我