小程序I18n最佳实践案例

相关学习推荐:微信小程序教程

背景

I18n = Internationalization,国际化,因为单词由首末字符i/n和中间18个字母组成,简称i18n。对程序来说,就是要在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面,以支持不同语言的人顺利使用程序。

业务背景

互联网行业进入下半场,精细化运营是关键。多语言支持能让产品更好地服务境内的其他语言用户,也为产品出海打下基础,随着 WeChat/Alipay 的全球化,你的小程序是否做好准备了呢?

4月初,滴滴出行小程序团队接到支持英文版的需求,预计上线时间为6月上旬。当前滴滴出行小程序集成的众多业务线和各种公共库,展示给用户的有前端硬编码的静态文本和服务端下发的文案,都要同步接入多语言。考虑到小程序当前的体量,光文本收集、语料翻译、npm package 支持,联调,测试,沟通成本等等,并且前端开发只投入1.5人力的情况下,时间是蛮紧迫的,但是我们抗住了压力,最终英文版滴滴出行小程序如期上线,截止目前运行稳定,用户反馈良好,得到了超出预期的收益。

当然这一切得益于各团队同学的高效工作,和各团队的通力配合,更得益于部门技术团队 Mpx框架优雅的多语言能力支持。划重点来咯,所谓工欲善其事必先利其器,如果你的公司业务需要开发小程序,也需要接入多语言,那么请搬好小板凳,我们来看一下小程序框架 Mpx 是如何优雅支持多语言能力。相信看完这篇,可以帮助你认识 Mpx(https://github.com/didi/mpx) ,加深对框架的理解,最终利用 Mpx 框架高效迭代小程序,年终奖多出那部分可以打赏一下作者,买杯咖啡哈(偷笑.jpg)

以下是滴滴出行小程序的中英文版本对比:

滴滴出行微信小程序i18n

也欢迎大家在微信/支付宝里搜索滴滴出行小程序,实际使用感受下。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内部流程示意图

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 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API。 因此在逻辑层,Mpx 将注入的 WXS 语法转化为 JS,通过 webpack 注入到当前模块。例如 WXS 全局方法 getRegExp/getDate 在 JS 中是无法调用的,Mpx将它们分别转化成 JS 模块,再通过 webpack addVariable 将模块注入到 bundle.js 中。 同理,Mpx 会将编译时注入的 i18n wxs 翻译函数和 i18n 配置对象挂载到全局 global 对象上,利用 mixin 混入到页面组件,并监听 i18n 配置对象,这样JS和模板中即可直接调用 i18n 翻译函数,实现数据响应。

以上便是 Mpx 框架在小程序中支持 i18n 能力的技术细节,由于 WXS 是可以在视图层执行的类 JS 语法的一门语言,这样就减少了小程序逻辑层和视图层的通信耗时,提升性能。但是由于实现依赖类 WXS 能力,以及 WXS 执行环境的限制,目前模板上可直接使用的翻译函数包括 $t/$tc/$te ,如果需要格式化数字或日期可以使用对应的翻译函数在 JS 中 Mpx 提供的计算属性中实现。

输出 web 时使用 i18n

Mpx同时还支持转换产出H5,而 Mpx 提供的 i18n 能力在使用上与 vue-i18n 基本一致,输出 web 时框架会自动引入 vue-i18n,并使用当前的 Mpx i18n 配置信息对其进行初始化,用户无需进行任何更改,即可输出和小程序表现完全一致的 i18n web 项目。

对比

上面分析了 Mpx 框架的 i18n 方案的技术细节,我们来看下和其他方案的对比,主要是和 uniapp - 基于 Vue 编写小程序的方案,和微信官方的方案,两者提供的 i18n 支持与Mpx的对比有何优劣。

uniapp的方案

uniapp 提供了对 i18n 能力的支持,是直接引入vue-i18n。但小程序中无法在模板上调用 JS 方法,本质上是利用计算属性 Computed 转换好语言,然后利用模板插值在小程序模板中使用。

模板中:<view>{{ message.hello }}</view>

JS里需要写:

  computed: {  
    message () {  
      return { hello: this.$t('message.hello') }
    }
  }复制代码

因此该方案存在一个性能问题,最终的渲染层所看到的文本还是通过 setData 跨线程通信完成,这样就会导致线程间通信增多,性能开销较大。

并且,早期这种形式使用成本较高,后来 uniapp 也针对其做过优化,实现了可以在模板上写 $t() 的能力,使用上方便了不少。

这个 $t() 的实现是在编译时候识别到 $t 就自动替换,帮你替换成一个 uniapp 的 computed 数据,因此数据部分还是和之前一样要维护两份。尤其是模板上的for循环,即使 for 里只有一个数据要被转换,整个列表都要被替换成一个计算属性,在线程间通信时进一步加大了性能开销。

微信官方的方案

微信小程序本身也提供了一个 i18n 的方案,仓库地址是:wechat-miniprogram/miniprogram-i18n 。

这个方案从 i18n 本身的实现来讲和Mpx框架的设计是类似的,也是基于 WXS 实现(英雄所见略同啊)。但因为周边配套上没有完整的体系,整体使用体验上就也略逊于基于Mpx框架来开发支持 i18n 的国际化小程序了。

主要的点就是,官方提供的方案,要基于 gulp 工具进行一次额外构建,同时在JS中使用时候还要额外引入一个 behavior 去让JS中也可以使用翻译能力。

而Mpx框架通过一次统一的Webpack构建产出完整的内容,用户无需担心语言包更新后忘记重新构建,在JS中使用的时候不光更方便,而且语言信息还是个响应式的,任何组件都可以很方便地监听语言值的变化去做一些其他的事情。

最后,Mpx的 i18n 方案对比微信官方的方案还有个巨大的优点,结合Mpx的跨平台能力,能实现均以这个方案,一套代码产出支持微信/支付宝/百度/QQ/头条多个平台的支持 i18n 的小程序。

总结

Mpx 框架专注小程序开发,期望为开发者提供最舒适的开发体验,有众多优秀的功能特性,帮助开发者提效。本文介绍的是其内置的 i18n 能力,通过对比分析得出相比其他框架方案在使用成本和性能等方面有明显的优势,欢迎各位有相关需求的同学进行体验尝试。

想了解更多编程学习,敬请关注php培训栏目!

以上就是小程序I18n最佳实践案例的详细内容,更多请关注编程之家其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


概述 消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验。 订阅消息推送位置:服务通知 订阅消息下发条件:用户自主订阅 订阅消息卡片跳转能力:点击查看详情可提爱转至该小程序的页面 消息类型 一次性订阅消息 一次性订阅消息用于解决用户使用小程序后,后续服务
判断H5页面环境在微信中还是小程序中 用小程序提供的wx.miniProgram.getEnv可以获取环境参数 &lt;script type=&quot;text/javascript&quot; src=&quot;https://res.wx.qq.com/open/js/jweixin-1.
wx.reLaunch和wx.navigateTo,wx.navigateTo的区别 2019-03-23 11:18:05 wx.navigateTo 用于保留当前页面、跳转到应用内的某个页面,使用 wx.navigateBack可以返回到原页面。对于页面不是特别多的小程序,通常推荐使用 wx.n
微信小程序如何从数组里取值_微信小程序 传值取值的几种方法总结 小程序里常见的取值有以下几种,一个完整的项目写下来,用到的概率几乎是100%。 列表index下标取值 页面传值 form表单取值 1. 列表index下标取值 实现方式是:data-index=&quot;{{index}}&quot
H5项目接入微信授权登录,通过 UA 区分微信还是普通浏览器: let&#160;ua&#160;=&#160;navigator.userAgent.toLowerCase(); let&#160;isWeixin&#160;=&#160;ua.indexOf(&#39;micromessenge
微信小程序获取data-xx=&quot;&quot;属性的值,自定义属性设置和获取(data-) 微信小程序&lt;view class=&quot;details-btn&quot; data-taskId=&quot;111&quot; bindtap=&#39;taskdetails&#39
小程序报错:TypeError: Cannot read property ‘addEventListener‘ of undefined 解决办法 将调试基础库由2.16.0(或者当前的) -&gt; 2.14.1 解决问题
H5跳转微信小程序-成功案例(VUE)(踩坑无数) TuoMei 已于 2022-07-29 09:52:22 修改 准备工作 根据官方提供的资料需准备以下几点: 1、已认证的服务号 2、绑定JS接口安全域名 (在微信公众平台设置) 3、IP白名单 (在微信公众平台设置) 4、将小程序和H5公众号进
微信小程序 页面跳转和数据传递实例详解 这篇文章主要介绍了微信小程序 页面跳转和数据传递实例详解的相关资料,这里附有实例代码帮助到家学习理解,需要的朋友可以参考下 微信小程序 页面跳转和数据传递 1.先导 在Android中,我们Activity和Fragment都有栈的概念在里面,微信小程序页面也
情景1.拉取公司代码演示: 因为github有墙,这里我们以gitee(码云)为例作为演示 (其实就是国产github,也非常好用~) 步骤一:打开Git界面 先在一个空文件夹右击Git Bash Here,打开git界面 步骤二:输入克隆远程仓库指令 别人复制的链接在这里获取 拿到别人赋值的链接自
如何开发微信小程序? 作为一名10多年一直从事互联网平台开发的从业者,我来回答下这个问题吧。 微信小程序开发流程总体可以归纳为4个步骤, 老张带您捋一捋整个环节,小白用户可以收藏了。 好了废话不多说,开始! 一、开发前小程序需要准备的资料 我们在开发微信小程序前,需要准备下相关资料。这个资料主要是后
原生小程序开发优化方案 为了更好的制定优化方案,我们 有必要先了解下小程序的底层架构、以及与普通网页开发的差异 小程序最终渲染载体与当下一些热门的技术 Flutter、React Native等不同,依然是浏览器内核,而不是原生客户端。 而对于传统的网页来说,UI 渲染和 JS 脚本是在同一个线程中
1,不要下两倍尺寸的图片, 小程序本身自己就会对元素缩小两倍,设计图片的一杯就已经很清晰了。 2,图片压缩,(主要是压缩静态资源,ps 可以压缩,然后有一些在线压缩工具,保持600-800kb 的静态) 3,通用的代码组件化 4,是在工程量太大可以分包,分包现在最大支持20m(一般都不会去分包的)
文章浏览阅读189次。人工智能研究实验室OpenAI在2022年11月30日发布了自然语言生成模型ChatGPT,上线两个月就已经超过一亿用户,成为了人工智能界当之无愧的超级大网红。ChatGPT凭借着自身强大的拟人化及时应答能力迅速破圈,引起了各行各业的热烈讨论。简单来说ChatGPT就是可以基于用户文本输入自动生成回答的人工智能聊天机器人。那肯定会有人说这不就是Siri嘛,虽然都是交互机器人但是两者的差别可老大了。那么ChatGPT在人机交互时为什么会有这么出色的表现?它到底会不会取代搜索引擎?90%的人真的会因为ChatG
文章浏览阅读193次。8. 导航和路由管理:掌握小程序的导航方式,如使用wx.navigateTo跳转页面、使用wx.redirect重定向页面等,学会实现页面之间的跳转和传参。1. 小程序的基本概念和架构:了解小程序的定义、特点以及与传统APP的区别,掌握小程序的运行环境、组件和API等基本概念。10. 支付功能:学习小程序的支付方式,如微信支付、支付宝支付等,了解支付流程和注意事项,学会实现小程序的支付功能。9. 用户授权和登录:了解小程序的用户授权机制,如获取用户信息、调用微信API等,学会实现用户的登录和注册功能。_微信小程序开发知识点总结
文章浏览阅读4.8k次,点赞7次,收藏18次。一、准备工作1. 安装微信开发者工具,并登录微信小程序账号;2. 准备斗地主游戏的图片资源;3. 准备斗地主游戏的音效资源;二、创建小程序1. 打开微信开发者工具,点击“新建小程序”,输入小程序名称,选择小程序的项目目录,点击“创建”;2. 在小程序的项目目录中,新建文件夹“images”,将准备好的斗地主游戏的图片资源放入“images”文件夹中;3. 在小程序的项目目录中,新建文件夹“sounds”,将准备好的斗地主游戏的音效资源放入“sounds”文件夹中;三、编写代码1. 在小程_扑克牌微信小程序代码
文章浏览阅读3.9k次,点赞3次,收藏7次。一、准备工作:1. 安装微信开发者工具,创建小程序项目;2. 准备游戏角色图片;3. 准备游戏背景音乐;二、实现步骤:1. 创建游戏页面,添加游戏角色图片,添加游戏背景音乐;2. 创建游戏角色类,定义游戏角色属性,如角色名称、角色图片、角色能力等;3. 创建游戏类,定义游戏属性,如游戏人数、游戏角色、游戏规则等;4. 创建游戏控制类,定义游戏流程,如游戏开始、游戏结束、游戏角色分配等;5. 创建游戏界面,实现游戏流程,如游戏开始、游戏结束、游戏角色分配等;6. 创建游戏结果页面,显示游戏_微信小程序游戏代码
文章浏览阅读1.7k次。1. 创建小程序项目:使用微信开发者工具创建一个小程序项目,并在项目中添加一个页面,用于模拟聊天。 2. 定义数据结构:定义一个数据结构,用于存储聊天记录,包括发送者、接收者、消息内容等信息。 3. 实现聊天功能:实现聊天功能,包括发送消息、接收消息、显示消息等功能。 4. 实现界面:使用微信小程序的界面框架,实现聊天界面,包括聊天记录列表、输入框等。代码示例:// 定义数据结构var chatData = { sender: '', receiver: '', message: '' };_制作聊天对话小程序代码
文章浏览阅读2.1k次。1、创建小程序项目:使用微信开发者工具,新建一个小程序项目,输入项目名称,选择项目目录,点击“创建”按钮,即可创建小程序项目。2、添加页面:在小程序项目中,可以添加多个页面,每个页面都有自己的页面文件,比如首页、分类页、购物车页、我的页面等。3、添加组件:在小程序项目中,可以添加多个组件,比如商品列表组件、购物车组件、订单组件等,用于在页面中显示商品信息、购物车信息、订单信息等。4、添加接口:在小程序项目中,可以添加多个接口,用于获取商品信息、购物车信息、订单信息等,以便在页面中显示。5、_微信开发者工具做一个我的商城