记录一次 uniapp vue2 国际化问题的排查

303 阅读2分钟

前言

这两天看到一个 uniapp vue2 国际化 的bug,这里记录一下这个bug的排查过程。

准备

现在 uniapp 支持 vue2 和 vue3,不同的 vue 版本,相关的api,配置,依赖等也有所不同。

问题截图如下:

image.png

可以看到是第一个具名格式(源码里称为叫 named)的国际化内容,没有传入 key,显示异常,第二个传入 key,显示正常。

我的测试项目是通过 hbuilderx 创建的,项目中本身是不包含 node_modules 的

image.png

但是我们却可以使用国际化的相关内容,奥秘在于 hbuilderx 这个编辑器,相关的一些依赖都内置在其中,

20250503112009_rec_.gif

uniapp-cli 是 vue2 版本的依赖包,uniapp-cli-vite 是 vue3 版本的依赖包,我们可以通过这里来查看依赖到 vue-i18n 的源码。

debug

由于问题是 web 平台,所以我们要运行到浏览器中,找到用到的产物文件

image.png

这里有个笨方法,在每个产物文件开头处加日志,我这里已经确认了是 vue-i18n.esm.js

问题是源于 $t 方法

image.png

key是我们传入的要国际化的字符串,locale是现在的语言,messages是现有的国际化对象

image.png

$t 是通过内部 i18n._t 处理的,再看下这个方法

image.png

方法内部会处理一下传入的参数,比如 $t('global.pleaseInput', { key: $t('login.tenantName') }) 转化出来就是 {key: '公司名称'}$t('global.pleaseInput') 就是 null

image.png

下面的处理方法是 _translate

image.png

这里的chain是适配的语言数组,['zh-Hans', 'zh', 'en-US', 'en'],会通过循环去处理各个语言,进入 _interpolate 方法

image.png

对应的传入的 _render 的参数是

  • 请输入 {key}
  • string
  • null
  • global.pleaseInput

另外一个是

  • 请输入 {key}
  • string
  • {key: '公司名称'}
  • global.pleaseInput

不同点就在于values参数

image.png

这个函数还调用 formatter 函数,透过名字也能大概推测这里会处理国际化字符串

image.png

parse 函数用来解析 token

image.png

compile 用来处理字符串

image.png

这个就是我们说的具名格式,values是我们传入的数据 {key: '公司名称'},转化之后就是 ['请输入 ', '公司名称'],而没传入就是 null,不会成功解析和转化,最后得到的是 ['请输入 {key}']

修复

至此,我们已经简单梳理了转化的整个流程,那么,如果让我们自己上手提pr修改该怎么做呢?

我的思路是,既然 valuesnull 会处理异常,那就写个函数,统一处理,有值就是默认值,无值就是空字符串。

image.png

image.png

正则那个方法是让deepseek写的,仅供参考,这个库内部有解析 token 的函数,可以拿来用那个。

这个版本是8.x的最后一个版本,目前还没看9.x是怎么处理的,等看了有空就再更新一篇文章

结语

如有疑问或想法,欢迎留言