「BBFE前端团队」以生产消费模式设计国际化方案

简介: 「BBFE前端团队」以生产消费模式设计国际化方案

引子


我之前也介绍过我们的团队 草系码猿🌿 用一年经历带你了解BBFE是个怎样的前端团队|Be Better Front End, 未来我也会为大家带来更多我们团队的实践探索,敬请期待~


下面由我们团队为大家分享BBFE在国际化方向的探索与思考



背景


一个软件产品走向国际市场,在不同的国家和地区使用,必然要在设计软件时考虑国际化。那么国际化是啥呢?维基百科中有如下定义:


国际化 是指在设计软件时,将软件与特定语言及地区脱钩的过程。当软件被移植到不同的语言及地区时,软件本身不用做内部工程上的改变或修正。


这就要求我们进行软件开发时,不应该为每个语言环境都开发单独版本,浪费大量的开发成本,而应该将需要翻译和替换的文本、图片等资源从源代码中提取出来,以配置文件的形式进行管理,即多语言国际化配置文件


提取后的软件项目称为国际化通用版项目,配置文件称为语言包,国际化通用版项目与不同的语言包就能使软件支持不同的语言环境,实现国际化。


网络异常,图片无法展示
|


现状


我们看看使用 Vue 的软件项目是怎么做到多语言国际化的。


通常,我们会选用 Vue 官方推荐的 Vue-i18n 方案,使用 Vue-i18n 实现国际化需要 6 个步骤:


  1. 开发者使用源语言(如中文)开发项目;


网络异常,图片无法展示
|


  1. 开发者手动从源代码中提取源语言包配置文件;


网络异常,图片无法展示
|


  1. 开发者将源代码中源语言(如中文)改写为使用语言包的标记方法;


网络异常,图片无法展示
|


  1. 开发者将提取的语言包转换为约定的格式提供给翻译供应商;
  2. 翻译供应商完成翻译,按约定的格式交付目标语言(如英文)包;
  3. 开发者生成可使用的目标语言包,软件项目按需使用;


网络异常,图片无法展示
|


多语言国际化配置文件随着项目规模扩大而增加,开发者需要不断重复上述过程。


面对小型的软件项目,手动维护还比较轻松,然而面对大型规模的软件项目,手动维护过程就显得极其繁琐,且容易出错导致问题不断。


以奇安信的大型管控系统为例,前端团队采用上述多语言国际化方案后,便带来痛苦的迭代及维护工作。整个软件项目的国际化开发过程中,共计手动产出 120+ 个英文语言包,因国际化手动工作而导致的相关 BUG 超过 180 个。


反思


采用上述多语言国际化方案后,我们经历了一段痛苦的开发过程。

我们总结该方案在大型中后台系统的应用场景存在 3 个缺陷:


  1. 提取语言包的过程需要开发者手动参与,过程繁琐效率低下且极易出错;
  2. 代码中语言包标记方法使用"文本 Key" ,无法有效阅读理解,维护成本高;
  3. 系统启动过程中全量加载目标语言包,延迟内容呈现,降低用户体验;


我们分析缺陷方案出现的根本原因,是没有事先思考与设计多语言国际化的目标与用例,采纳的社区方案并不能保障上来就是干的靠谱预期。我们将项目磕磕绊绊的勉强交付,受伤后才思考多语言国际化究竟在做什么事,达成哪些目标。


针对旧版方案的上述问题,我们决定探索符合 BBFE 实际需要的多语言国际化新方案,并制定 3 个目标:


  1. 用自动化工具代替手动提取语言包的工作,降低成本保障正确性;
  2. 能使用源语言(中文)编写代码,增强代码可读性与可维护性;
  3. 奇安信前端框架QP内置按需加载目标语言包的能力,提升系统运行性能;


调研


建立目标后,我们调研学习国际化领域的相关知识与协议,深入理解多个成熟的国际化开源方案,发现大致分为 2 种思路:


  1. 软件项目配合不同的目标语言编译输出不同的项目制品,部署于不同的服务环境,代表方案:Angular-i18n;
  2. 软件项目编译输出为一个标准制品,系统在运行过程中根据语言环境加载对应的目标语言资源,代表方案:Vue-i18n , i18next , kiwi 等;


网络异常,图片无法展示
|


其中,我们对 Angular的国际化方案( Angular-i18n ) 分析如下:


  1. 开发者使用源语言编写代码,标记出需要翻译的文本。对于比较复杂的文本信息(不同语言有不同的复数描述规则和语法结构)使用 ICU 消息格式编写;
  2. 使用命令行工具将标记过的文本提取为 XLIFF 格式的语言包模板
  3. 为每种目标语言生成独立的 XLIFF 语言包文件,把语言包提供给翻译供应商;
  4. 为一个或多个语言环境构建项目制品时,使用命令行工具合并目标语言包;


方案的使用过程比较方便,且部分满足我们对新方案的目标所需。如使用命令行工具提取语言包,及使用源语言标记文本翻译。


XLIFF\ICU 是国际化领域的协议与方案,以下为简介:


XLIFF


XLIFF(XML Localisation Interchange File Format,即XML本地化交换文件格式)是一种基于XML协议的交换格式,旨在标准化国际化、本地化过程中在工具之间传递可本地化数据的方式。


可以包含一些给翻译人员提供的附加信息,使翻译人员能更好地翻译。


网络异常,图片无法展示
|


同时,也是因为 XLIFF 是标准的解决方案,各应用市场也存在给翻译人员使用的 XLIFF 翻译工具,如 XLIFF editor、Poeditor 等,下图所示是 XLIFF editor 的使用界面:


网络异常,图片无法展示
|


ICU


为在国际化过程中需要根据各地的风俗和语言习惯,实现对数字、货币、时间、日期、和消息的格式化、解析,对字符串进行大小写转换、整理、搜索和排序等功能,ICU (International Components for Unicode,Unicode 国际化标准组件)应运而生,它是一套成熟、广泛使用的C/C++、Java和.NET 类库集。我们可以利用 ICU 消息格式 定义解决翻译中常见的复数、选择占位等复杂形式,下图所示是 ICU消息格式 表示复数的一种情况:


网络异常,图片无法展示
|


问题


然而,我们发现 Angular-i18n 方案也存在一些实际问题:

  1. 只提供模版内的标记方法,对于脚本逻辑的文本,没有提供官方解决方案;
  2. 编译为不同语言的项目制品,会提升项目制品部署及路由配置的复杂度;


思考


我们经过调研,并进行充分的讨论与思考,逐步理清围绕多语言国际化配置文件的两个重要模式,即 生产语言包 和 消费语言包 。


当下前端的国际化开源方案,以生产语言包和消费语言包的角度整理如下图:


网络异常,图片无法展示
|


结合奇安信产品的国际化需求,我们对国际化的新方案期望如下:


一、生产语言包:自动化工具代替大量手动提取语言包的操作。Angular-i18n 使用命令行工具提取生成 XLIFF 标准的语言包模板,是可以借鉴的部分。

二、消费语言包:按需加载目标语言环境的配置文件,系统运行过程中可切换目标语言。对于文本描述复杂的信息(如复数、时间等),需要标准解决方案。Vue-i18n 在浏览器运行时加载语言包,Angular-i18n 采用 ICU 格式编写复杂文本,是可以借鉴的部分。


综合 Angular-i18n 与 Vue-i18n 方案中可借鉴的部分,再加上BBFE团队的整体方案设计与优化,便形成奇安信的多语言国际化的新方案(即千星平台内置的国际化标准方案)。


方案


接下来,我们捋捋新版多语言国际化方案,并阐述其中的设计思路:


1.标记


首先,我们标记出需要翻译的文本内容。


对于普通文本,使用 tx 方法来标记,而 tx 方法在不同的使用场景又有不一样的使用变形。


在 Vue 模板中,我们使用 $tx 来标记:


$tx('你好,世界!')


而在 js 文件中,我们使用QP框架的全局方法 qp.i18n.tx 来标记:


export const sayHello = (name) => {
  return qp.i18n.tx('你好,{name}', {name});
}


如果需要给标记的文本提供更多描述信息(通常是方便翻译人员工作参考),可以使用标记方法提供的第 2 个参数,如:


<span>
  {{ $tx('你好,世界!', '首页|用户进入网站的欢迎界面') }}
</span>


如上代码编写,首页|用户进入网站的欢迎界面 这部分补充信息也被提取至语言包模板(XLIFF格式),提供给翻译人员使用。


对于复数、时间等复杂信息的文本,须使标记方法的第 1 个参数使用 ICU message format


<span>
  {{ $tx('{minutes, plural, =0 {刚刚} =1 {一分钟前} other {# 分钟}}更新', {minutes}, '更新时间|使用 ICU 格式') }}
</span>


实现上,会使用 intl-messageformat 包转译上述 ICU 特殊标记。


如果,需要翻译的文本嵌于复杂的 DOM 结构,则使用QP框架的全局组件 Translate ,以避免文本被 DOM 结构截断上下文信息,如:


<Translate i18n="i18n">
  <b>国际化</b>
  <span>(i18n)是一个过程,用于对你的应用进行设计和准备以便在全球不同地区使用。</span>
</Translate>


Translate 组件包裹的 DOM 结构会以翻译单元的形式提供给翻译人员(符合XLIFF 的定义)。


对于需要从服务端获取的目标语言文本,如字典等,会提供 t 方法用于标记,方法同 Vue-i18n,需要定义文本 key 在浏览器运行时显示目标文本。


值得注意的是,使用 t 方法标记的信息不再被提取工具所提取至语言包模板。


2.提取语言包模板


其次,将需要翻译的文本标记之后,便可以抽取源语言包模板。


我们提供命令行工具,将需要翻译的文本提取为 XLIFF 格式的语言包模板。


按需生成目标语言的 XLIFF 配置文件(即语言包),把语言包提供给翻译供应商,供应商翻译完毕后也将返还目标语言的  XLIFF 配置文件(即目标语言包)。


3.项目配置目标语言包


然后,软件项目需要配置的语言包分为 2 类,即软件项目源码内提取并翻译的目标语言包软件项目依赖的 NPM Package 的语言包


  • 对于软件项目源码内提取并翻译的目标语言包(XLIFF 格式


提取并翻译的 XLIFF 目标语言包包含提供给翻译人员的附加信息,这些信息是为翻译人员做更好的工作参考。


以项目制品的系统运行过程而言,这些附加信息是冗余的,包含冗余信息的目标语言包对于系统运行带来不必要的负担,且在浏览器解析 XLIFF 文件也会耗费运行时性能。

于是,我们对已翻译好的目标语言包再次提取关键信息,生成体积小且容易在浏览器运行时使用的 json 文件。这便是命令行工具的第二个功能:将 XLIFF 语言包转换为 json 语言包。转换后的 json 语言包只包含翻译单元的 key 及对应的目标语言文本信息:


网络异常,图片无法展示
|


  • 对于依赖的 NPM Package 中的语言包


每个语言环境会对应独立的目标语言 js 文件,系统启动时会按照语言环境引入目标语言包。目标语言 js 文件名遵循 BCP47 的命名规则,如匹配美式英语的语言环境,就需要创建名为 en-US.js 的目标语言文件,该文件需导入( import )项目所有依赖的 NPM Package 目标语言环境的语言包,以数组方式导出( export) 。


// src/configs/dependency-locales/en-US.js
import somePackageEn from 'some-package/dist/locales/en-US.js';
import anotherPackageEn from 'another-package/dist/locales/en-US.json';
export default [somePackageEn, anotherPackageEn]; // 多个第三方 package 的语言包以数组的形式导出


4.按需加载目标语言包


最后,QP框架内置目标语言包切换的策略,如下图:


网络异常,图片无法展示
|


QP框架根据不同的语言环境加载对应的目标语言包,此处是框架内置规则,不再赘述。


总结


本文讲述 BBFE 在奇安信的大型管控系统开发多语言国际化方案的心路历程。

尽管我们以基于Vue的项目为案例,甚至数次提到内置于QP框架的多语言国际化方案(QP框架是奇安信前端统一研发平台--千星平台的基础设施之一)。仍然希望BBFE 在国际化方案研发过程中的思考可以为各位阅读者提供一点帮助。


本文所述的多语言国际化方案是汲取优秀案例 Angular-i18n 及 Vue-i18n 的设计思路,使用 XLIFF / ICU / BCP47 等国际化通用标准。能够「站在巨人的肩膀上」做出的每一点改进,都应归功于前端开源社区文化的繁盛,BBFE 感谢前辈们


未来,我们应该需要一个更加完备的多语言国际化工作平台(如下图)去维护语言包的工作流(抽取、转换、集成等),国际化工作远不止于多语言处理,国际化的探索之路值得我们共同期待与挑战。


网络异常,图片无法展示
|


参考资料


XLIFF 维基百科:en.wikipedia.org/wiki/XLIFF

ICU : unicode-org.github.io/icu/

CLDR : cldr.unicode.org/

BCP47 : tools.ietf.org/search/bcp4…

Angular-i18n:angular.cn/guide/i18n

Vue-i18n : kazupon.github.io/vue-i18n

i18nNext : www.i18next.com/

react-intl-universal: github.com/alibaba/rea…

kiwi : github.com/alibaba/kiw…

相关文章
|
1月前
|
前端开发 JavaScript UED
不可思议!前端小白如何靠这些技巧逆袭,成为团队中的闪耀之星?
前端开发对初学者来说充满挑战,但通过正确的方法和技巧,你可以从新手蜕变为高手。本文分享前端小白逆袭的秘诀,包括夯实HTML、CSS与JavaScript基础,掌握前端框架与库,提升性能优化技巧,以及持续学习与分享。示例代码展示了简单的HTML+CSS+JavaScript页面和Vue组件,帮助你逐步进阶。
24 4
|
1月前
|
前端开发 数据可视化 搜索推荐
深入剖析极态云优雅的前端框架设计方案(上)
最近在体验极态云,这款低代码软件开发产品,发现其前端框架设计方案很优雅很强大! 在接下来的学习过程中,我将持续输出自己对极态云前端框架设计方案的深入理解,包括具体的使用技巧、优势分析以及可能的应用场景等方面的内容,希望能为大家提供有价值的参考。
|
2月前
|
缓存 前端开发 UED
前端 8 种图片加载优化方案梳理
本文首发于微信公众号“前端徐徐”,详细探讨了现代网页设计中图片加载速度优化的重要性及方法。内容涵盖图片格式选择(如JPEG、PNG、WebP等)、图片压缩技术、响应式图片、延迟加载、CDN使用、缓存控制、图像裁剪与缩放、Base64编码等前端图片优化策略,旨在帮助开发者提升网页性能和用户体验。
397 0
|
2月前
|
JavaScript 前端开发 应用服务中间件
Vue开发中,在实现单页面应用(SPA)前端路由时的hash模式和history模式的区别及详细介绍
Vue开发中,在实现单页面应用(SPA)前端路由时的hash模式和history模式的区别及详细介绍
45 0
|
3月前
|
前端开发
前端web入门第四天】03 显示模式+综合案例热词与banner效果
本文档介绍了HTML中标签的三种显示模式:块级元素、行内元素与行内块元素,并详细解释了各自的特性和应用场景。块级元素独占一行,宽度默认为父级100%,可设置宽高;行内元素在同一行显示,尺寸由内容决定,设置宽高无效;行内块元素在同一行显示,尺寸由内容决定,可设置宽高。此外,还提供了两个综合案例,包括热词展示和banner效果实现,帮助读者更好地理解和应用这些显示模式。
|
3月前
|
Web App开发 前端开发 JavaScript
Web前端项目的跨平台桌面客户端打包方案之——CEF框架
Chromium Embedded Framework (CEF) 是一个基于 Google Chromium 项目的开源 Web 浏览器控件,旨在为第三方应用提供嵌入式浏览器支持。CEF 隔离了底层 Chromium 和 Blink 的复杂性,提供了稳定的产品级 API。它支持 Windows、Linux 和 Mac 平台,不仅限于 C/C++ 接口,还支持多种语言。CEF 功能强大,性能优异,广泛应用于桌面端开发,如 QQ、微信、网易云音乐等。CEF 开源且采用 BSD 授权,商业友好,装机量已超 1 亿。此外,GitHub 项目 CefDetector 可帮助检测电脑中使用 CEF
486 3
|
4月前
|
设计模式 JavaScript 前端开发
Vue.js 组件设计模式:在前端热潮中找到归属感,打造可复用组件库,开启高效开发之旅!
【8月更文挑战第22天】Vue.js 以其高效构建单页应用著称,更可通过精良的组件设计打造可复用组件库。组件应职责单一、边界清晰,如一个显示文本并触发事件的按钮组件,通过 props 传递标签文本,利用插槽增强灵活性,允许父组件注入动态内容。结合 CSS 预处理器管理和封装独立模块,配以详尽文档,有效提升开发效率及代码可维护性。合理设计模式下,组件库既灵活又强大,持续实践可优化项目工作流。
64 1
|
4月前
|
缓存 前端开发 JavaScript
前端性能优化方案
【8月更文挑战第15天】前端性能优化方案
44 2
|
3月前
|
编解码 前端开发 JavaScript
前端移动端适配方案
【9月更文挑战第8天】前端移动端适配方案
118 0
|
5月前
|
前端开发 JavaScript 开发者
条件判断的模式问题之为什么不建议在前端日常业务开发中使用OOP的责任链模式实践
条件判断的模式问题之为什么不建议在前端日常业务开发中使用OOP的责任链模式实践