相关学习推荐:微信小程序教程
背景
i18n = internationalization,国际化,因为单词由首末字符i/n和中间18个字母组成,简称i18n。对程序来说,就是要在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面,以支持不同语言的人顺利使用程序。
业务背景
互联网行业进入下半场,精细化运营是关键。多语言支持能让产品更好地服务境内的其他语言用户,也为产品出海打下基础,随着 wechat/alipay 的全球化,你的小程序是否做好准备了呢?
4月初,滴滴出行小程序团队接到支持英文版的需求,预计上线时间为6月上旬。当前滴滴出行小程序集成的众多业务线和各种公共库,展示给用户的有前端硬编码的静态文本和服务端下发的文案,都要同步接入多语言。考虑到小程序当前的体量,光文本收集、语料翻译、npm package 支持,联调,测试,沟通成本等等,并且前端开发只投入1.5人力的情况下,时间是蛮紧迫的,但是我们抗住了压力,最终英文版滴滴出行小程序如期上线,截止目前运行稳定,用户反馈良好,得到了超出预期的收益。
当然这一切得益于各团队同学的高效工作,和各团队的通力配合,更得益于部门技术团队 mpx框架优雅的多语言能力支持。划重点来咯,所谓工欲善其事必先利其器,如果你的公司业务需要开发小程序,也需要接入多语言,那么请搬好小板凳,我们来看一下小程序框架 mpx 是如何优雅支持多语言能力。相信看完这篇,可以帮助你认识 mpx(https://github.com/didi/mpx) ,加深对框架的理解,最终利用 mpx 框架高效迭代小程序,年终奖多出那部分可以打赏一下作者,买杯咖啡哈(偷笑.jpg)
以下是滴滴出行小程序的中英文版本对比:
也欢迎大家在微信/支付宝里搜索滴滴出行小程序,实际使用感受下。ps:切换语言的方法是,打开小程序,点击左上角用户头像,进入侧边栏设置页面,点击切换中英文即可体验。
技术背景
在上述业务背景下,mpx 框架——滴滴自研的专注提升小程序开发体验的增强型小程序框架,内建 i18n 能力便提上日程。
与 web 不同,小程序(本文以微信小程序为例)运行环境采用双线程架构设计,渲染层的界面使用 webview 进行渲染,逻辑层采用 jscore 线程运行 js脚本。逻辑层数据改变,通过 setdata 将数据转发到 native(微信客户端),native 再将数据转发到渲染层,以此更新页面。由于线程间通信成本较高,实际项目开发时需要控制频次和数量。另外小程序的渲染层不支持运行 js ,一些如事件处理等操作无法在渲染层实现,因此微信官方提供了一套脚本语言 wxs ,结合 wxml ,可以构建出页面的结构(不了解 wxs ?戳这里)。
基于小程序的双线程架构设计,实现 i18n 存在一些技术上的难点与挑战,由于 mpx 框架早期构建起来的强大基础,最终得以优雅支持多语言能力,实现了和vue-i18n 基本一致的使用体验。
使用
在使用上,mpx 支持 i18n 能力提供的 api 与 vue-i18n 大体对齐,用法上也基本一致。
模板中使用 i18n
编译阶段通过用户配置的 i18n 字典,结合框架内建的翻译函数通过 wxs-i18n-loader 合成为可执行的 wxs 翻译函数,并自动注入到有翻译函数调用的模板中,具体调用方式如下图。
// mpx文件<template> <view> <view>{{ $t('message.hello', { msg: 'hello' })}}</view> <!-- formatteddatetime计算属性,可基于locale变更响应刷新 --> <view>{{formatteddatetime}}</view> </view></template>复制代码js 中使用 i18n
通过框架提供的 wxs2js 能力,将 wxs 翻译函数转换为 js 模块注入到 js 运行时,使运行时环境中也能够调用翻译函数。
// mpx文件<script> import mpx, { createcomponent } from '@mpxjs/core' createcomponent({ ready () { // js中使用 console.log(this.$t('message.hello', { msg: 'hello' })) // 局部locale变更,生效范围为当前组件内 this.$i18n.locale = 'en-us' settimeout(() => { // 全局locale变更,生效范围为项目全局 mpx.i18n.locale = 'zh-cn' }, 10000) }, computed: { formatteddatetime () { return this.$d(new date(), 'long') } } })</script>复制代码定义 i18n 字典
项目构建时传入 i18n 配置对象,主要包括语言字典和默认语言类型。
new mpxwebpackplugin({ i18n: { locale: 'en-us', // messages既可以通过对象字面量传入,也可以通过messagespath指定一个js模块路径,在该模块中定义配置并导出,datetimeformats/datetimeformatspath和numberformats/numberformatspath同理 messages: { 'en-us': { message: { hello: '{msg} world' } }, 'zh-cn': { message: { hello: '{msg} 世界' } } }, // messagespath: path.resolve(__dirname, '../src/i18n.js') }})复制代码如果是通过 mpx 提供的 cli 工具生成的项目,这部分配置会在 mpx.conf.js 文件中,不光可以直接内联写在该文件中,也可以指定语言包的路径。
以上,mpx 的 i18n 方案接入成本低,使用优雅,体验优秀。直观感受可参考下面 mpx i18n demo :github.com/didi/mpx/tr…
方案
mpx框架的 i18n 支持几乎完全实现了 vue-i18n 的全部能力,下面我们来详细说明 mpx 框架 i18n 能力的具体实现。
方案探索
基于小程序运行环境的双线程架构,我们尝试了不同方案,具体探索过程如下:
方案一:基于 mpx 框架已提供的数据增强能力 computed 计算属性,来支持 i18n 。该方案与 uniapp 的实现思路相似(后文会进行对比分析),存在一定不足,包括线程通信带来的性能开销和for循环场景下的处理较复杂等,最终放弃。
方案二:基于 wxs js 支持 i18n 适配。通过视图层注入 wxs,将 wxs 语法转换为 js 后注入到逻辑层,这样视图层和逻辑层均可实现 i18n 适配,并且在一定程度上有效减少两个线程间的通信耗时,提高性能。
从性能和合理性上考虑,我们最终采用了方案二进行 mpx 的 i18n 方案实现。
mpx i18n 架构设计图
由于各大小程序平台上,wxs 语法和使用均存在较大差异,因此该方案实现过程中也存在一些技术上的难点,这些难点基于 mpx 框架的早期构建起来的跨平台能力也一一得以攻克,具体如下。
实现难点wxs 在模板中运行的跨平台处理
wxs 是运行在视图层中的 js,可以减少与逻辑层通信耗时,提高性能。因此 mpx 框架在迭代初期便已支持在模板和 js 运行环境使用 wxs 语言,并且针对小程序跨平台 wxs 语法进行抹平。
在模板中,mpx 自定义一个 webpack chunk template,以微信 wxs 作为 dsl,利用 babylon 将注入的 wxs 转化成 ast,然后遍历 ast 节点,抹平各大平台对 wxs 语法的处理差异,输出各平台可以识别的类 wxs 文件。目前主要支持微信(wxs)、支付宝(sjs)、百度(filter)、qq(qs)、头条(sjs)等小程序平台。
wxs 在逻辑层运行的跨平台处理
wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致。并且 wxs 的运行环境和其他 javascript 代码是
商标注册代理机构靠谱吗云服务器与虚拟主机有什么区别网络营销容易踩到的那些坑淘宝店铺初期该如何运营腾讯云服务器买哪个好邮箱不能打开-企业邮局国外的网站空间怎么样影响云服务器价格的因素有哪些啊