Skip to content

[Bug report] i18n: key 以数字开头紧跟 "+"(如 "500+ reviews")时 $t 翻译失败,返回 key 本身 #2526

@ASkyBig

Description

@ASkyBig

问题描述

1. 问题触发的条件

i18n 的 message key 以纯数字开头、紧跟 + 时(如 "500+ reviews""1000+ reviews""45,000+ users"),$t() 翻译失败,直接返回 key 本身。

  • 触发与语言无关,由 key 的结构(数字 + +)决定。
  • 模板 {{ $t('500+ reviews') }} 和 JS this.$t('500+ reviews') 都会复现。
  • 对照:+ 不在纯数字后面时(如 "reviews 500+""Pro+ features")不受影响,翻译正常。

2. 期望的表现

locale = zh-CN 时,$t('500+ reviews') 返回对应译文 "500+ 条评论"

3. 实际的表现

$t('500+ reviews') 返回 key 本身 "500+ reviews"(未翻译)。

locale = zh-CN,messages 同时定义了两个 key:
  $t('hello')          → "你好"          ✅
  $t('reviews 500+')   → "评论 500+"     ✅  (+ 不在数字后)
  $t('500+ reviews')   → "500+ reviews"  ❌  (期望 "500+ 条评论")

根因分析(已定位到源码)

文件:@mpxjs/webpack-plugin/lib/runtime/i18n.wxs

key 被 parsePath 当成路径/算术表达式解析:'500+ reviews'['500', '+', 'reviews'],随后 outPutByPath'500' 当数字字面量、'+' 当加法,算出 500 + messages['reviews'] = 500 + undefined = NaN

resolve 的兜底只判断了 == null,接不住 NaN(NaN == nullfalse):

function resolve (messages, locale, key) {
  if (messages && messages[locale] && key) {
    var format = getPathValue(messages[locale], key)
    if (format == null) {          // ❌ NaN == null 为 false,兜底被跳过
      format = messages[locale][key]
    }
    return format                  // 返回了 NaN → translate 见非字符串 → return key
  }
}

对照 'Pro+ features'(字母 +)得到的是 undefined,能被 == null 接住,所以正常——这也是为什么"字母 +"已修好、"数字 +"仍坏。

建议修复(保守、零破坏):兜底额外接住 NaN(用 format !== format 判 NaN,wxs 环境可用):

- if (format == null) {
+ if (format == null || format !== format) {
    format = messages[locale][key]
  }

环境信息描述

  1. 系统类型:macOS
  2. Mpx 依赖版本:
    • @mpxjs/core: 2.10.24
    • @mpxjs/webpack-plugin: 2.10.24
    • @mpxjs/api-proxy: 2.10.21
  3. 小程序开发者工具信息:
    • 小程序平台:微信小程序
    • 开发者工具版本:⚠️ * 2.01.2510290 darwin-arm64*
    • 基础库版本:⚠️ 3.16.1

最简复现 demo

可下载地址:https://github.com/ASkyBig/mpx-i18n-test

复现步骤:

git clone https://github.com/ASkyBig/mpx-i18n-test
cd mpx-i18n-test
npm install        # 安装到 @mpxjs/webpack-plugin@2.10.24(自带此 bug)
npm run build      # 产物输出到 dist/wx

用微信开发者工具打开 dist/wx,首页(pages/index)渲染三行:

渲染 期望 实际
{{ $t('hello') }} 你好 你好 ✅
{{ $t('reviews 500+') }} 评论 500+ 评论 500+ ✅
{{ $t('500+ reviews') }} 500+ 条评论 500+ reviews ❌

关键配置(mpx.config.js):

i18n: {
  locale: "zh-CN",
  messages: {
    "en-US": { hello: "hello", "500+ reviews": "500+ reviews", "reviews 500+": "reviews 500+" },
    "zh-CN": { hello: "你好", "500+ reviews": "500+ 条评论", "reviews 500+": "评论 500+" },
  },
},
image

对应修复PR: #2527

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions