npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@alicloud/xconsole-intl-extended

v1.0.0

Published

强化 Intl,以最佳实践和规范,统一样式,减少代码量

Downloads

4

Readme

@alicloud/xconsole-intl-extended

@alicloud/console-components-intl 的封装,使其更易用。

该版本依赖 @alicloud/console-components-intl 版本 2.x,如果是 1.x 可以使用 @ali/wind-x-intl

吐槽 @alicloud/console-components-intl

| 问题 | 改进 | |---------------------------------------------------|--------------------------------------------------------------------------| | 对 @alicloud/console-components-intl 的使用有加载顺序的要求 | 不需要 | | 没有样式规范 | 定义了一套方便用户的规则,可以按照 key 的后缀指令选择是返回字符串还是带标准样式的 JSX,既保证样式标准性,又可以避免断句、断章等问题 | | 没有类型保护,编译期无法检测到某个 key 不存在,从而导致线上问题 | 通过 TS 泛型,既保证代码的完整性,又能够避免线上问题 | | 很难单独使用在 npm 包中 | 因为是工厂方法,可以创建多个实例 | | 没有对 locale 的 key 做兼容 | 对大小和连字符等做了较强的兼容 |

安装

tnpm i -S react @alicloud/console-components @alicloud/console-components-intl styled-components @alicloud/xconsole-intl-extended

@alicloud/xconsole-intl-extended 之前的是它的 peer dependency,必须由使用者安装。

设置

首先请非常冷酷无情地删掉狗屎的 initializer.js

在你项目的 src 下建一个目录,并创建如下文件(也可以按照你的个人喜好):

src/
 └─ intl/
     ├─ locales/
     │   ├─ en-us.json
     │   ├─ ...
     │   └─ zh-cn.json
     ├─ index.ts
     └─ messages.ts

intl/

建议在你的 webpack 配置下,为 src 目录配置 alias :(个人习惯,Xconsole 下是 ~),比如在 webpack.config.base.json 里:

const path = require('path');
// ...

module.exports = {
  // ...
  resolve: {
    alias: {
      ':': path.resolve(__dirname, '../src')
    }
    // ...
  }
  // ...
}

如果你用 TS,修改 tsconfig.json

{
  "compilerOptions": {
    // ...
    "paths": {
      ":/*": ["src/*"]
    }
    // ...
  }
}

intl/locales/[locale].json

locales 下只是对 美杜莎 上的一个导出和备份,主要是为了在本地仓库有个参考,可以快速定位到正确的 key。

intl/message.ts

import fallbackMessages from './locales/en-us.json'; // locales 下的 json 文件最多就是个参考,但还是会打一个到包里做兜底

export default {
  ...fallbackMessages,
  // ↓ 开发期间「增加」新的文案,发布前必须提交到 medusa,并删除之间的文案 - BEGIN
  // ↑ 开发期间「增加」新的文案,发布前必须提交到 medusa,并删除之间的文案 - END
  ...window.SOME_GLOBAL_MESSAGES // window 或哪里可以直接拿到的 medusa 输出的对象
  // ↓ 开发期间「修改」已有的文案,发布前必须提交到 medusa,并删除之间的文案 - BEGIN
  // ↑ 开发期间「修改」已有的文案,发布前必须提交到 medusa,并删除之间的文案 - END
};

注意:SOME_GLOBAL_MESSAGES 视你的具体应用而定。

intl/index.ts

import createIntl from '@alicloud/xconsole-intl-extended';

import messages from './messages';

const intl = createIntl(messages, LOCALE, { // LOCALE 视你应用的具体情况而定,你也可以通过 options 做一些定制
  extraValues
});

export default intl;

export const { // 你也可以不必输出它们,而直接使用 intl.xx 进行引用
  getLocale,
  intlDate,
  intlNumber,
  intlPercentage,
  intlPercentageTuple,
  intlByte,
  intlByteTuple,
  intlCurrency,
  intlConst,
  intlChoices
} = intl;

如何使用

记住:在你的项目里,你永远只跟 :/intl 打交道,绝对不要染指 @alicloud/console-components-intl

import intl, {
  // other stuff
} from ':/intl';

// 静态调用
intl(...);

// 在 JSX 中
<div>{intl(...)}</div>

关于返回类型

intl 方法虽然返回的类型只有 string,但实际可能返回 JSX.Element(在指定 !lines!html 的情况下),这个非常不好写,又不适合用泛型(不知怎么回事会返回 any)。

好在大多数情况下,intl 仅用于展示端,stringJSX.Element 可以无感。

如果要强行指定 JSX.Element 的话,就强行转换类型吧:

const message = intl('xxx!html') as unknown as JSX.Element;

国际化规范(最佳实践)

关于 key

  • 全小写,单词之间以 _ 分隔
  • 建议以 : 做分隔(. 也行),该分隔符一般
  • 一般是 对象:类型约定:含义?参数!长相
    • 对象:表示功能对象,但在某些包下面,有明确的上下文的时候可以不需要
    • 类型约定:文案的类型
    • 含义:表示文案的意思,需要让读者看到它就知道大致的意思,而不需要进一步看文案的内容,如果有插值则以 {val1,val2} 的形式挂上
    • 参数:如果内部有 select 语句则带上参数,如 ?attr?op?status?type
    • 长相:用 !html 表示内容里边有 HTML 元素,!lines 表示内容里边的换行需要解析成 <p><ul><ol>
  • 尽可能聚合,如用户的属性 user?attr,然后内部使用 select
  • 通用的文案以 _ 打头,如 _?op

关于 value

  • 不断句,即不能有 我有 + 个女朋友 两条,而是应该用插值 我有 {n, number} 个女朋友
  • 不断章,相关联的文案放一个 key 里,不可一行文案对一个 key,见过 xx1xx2... 然后在代码里把它们拼成一个段落(可能是列表)的行为,恶心至极
  • 注意标点,中文下不允许有英文标点,英文下不允许有中文标点
  • 英文、数字、HTML inline 元素,若和中文贴着,两者之间加空格
  • 仅允许 <a><em><code><strong><kbd>这几个 inline 元素
  • <ul><li>*␣ 打头(注意有空格)
  • <ol><li>1.␣2.␣...打头(注意有空格)
  • 用作例子的部分,以 <code> 包裹

关于 key 的「类型约定」建议

我发现很多人对「类型」一点都不感冒,什么是「属性」,什么是「操作」一点都没有概念,导致写出来的文案虽然在用户看来没有问题,但定义的却一塌糊涂。

一般我会用 一个 单词来表示文案的类型,每种类型在含义、书写上都会有一定的特点,在一个项目下,不可能有太多的类型,以下是我在项目中常用的类型:

| 单词 | 简写 | 含义 | 场景 | 文案规范 | |-----------|-----|-----|------------------------------------|------------------------------| | attr | a | 属性 | 标题 | 名词,英文遵循首每个单词(除介词、冠词等)字母大写 | | op | o | 属性 | 按钮 | 动词,英文遵循首每个单词(除介词、冠词等)字母大写 | | type | t | 类型 | 字段展示 | 名词,英文遵循首每个单词(除介词、冠词等)字母大写 | | status | s | 状态 | 字段展示 | 形容词,英文遵循首每个单词(除介词、冠词等)字母大写 | | title | - | 标题 | 标题 | 名词,英文遵循首每个单词(除介词、冠词等)字母大写 | | label | l | 标题 | 按钮、字段展示 | 名词/动词,英文遵循首每个单词(除介词、冠词等)字母大写 | | message | m | 长句子 | 标题 | 必须有结束标点,不可断句,不可断章 | | phrase | p | 短句子 | 标题 | 没有结束标点的句子(不建议) |

以上,我们可以将在特定对象的 attroptypestatus 进行聚合,比如:

export default {
  'user:attr:id': '用户 ID',
  'user:attr:name': '用户名',
  'user:op:create': '创建用户',
  'user:op:edit': '编辑用户',
  'user:op:delete': '删除用户',
  'user:type:normal': '普通',
  'user:type:vip': 'VIP',
  'user:type:svip': '超级 VIP',
  'user:status:new': '未认证',
  'user:status:verified': '已认证',
  'user:status:unregstered': '已注销',
};

聚合后,可以是这样:

export default {
  'user?attr': `{attr, select,
ID {用户 ID}
NAME {用户名}
other {{attr}}}`,
  'user?op': `{op, select,
CREATE {创建用户}
EDIT {编辑用户}
DELETE {删除用户}
other {{op}}}`,
  'user?type': `{type, select,
NORMAL {普通}
VIP {VIP}
SVIP {超级 VIP}
other {{type}}}`,
  'user?status': `{status, select,
NEW {未认证}
VERIFIED {已认证}
UNREGSTERED {已注销}
other {{status}}}`
};

我更推荐这种聚合的定义方式,它有以下好处:

  1. 更内聚,相关的内容一定会定义在一个地方
  2. 可以用 intlChoices 搭配常量枚举快速生成选项列表
  3. 可以用 intlConst 搭配常量枚举快速转化常量为文案

FAQ

可以直接用 @alicloud/console-components-intl 么?

可以,但一万个不推荐。你可以在你的 intl/index.ts 的最末把 @alicloud/console-components-intl export 出去再用,但千万不要直接用 @alicloud/console-components-intl, 原因是你在别人 import 的 @alicloud/console-components-intl 有可能是没有初始化完毕的——这就是那个臭烘烘的 initializer.js 的来由。

文案中可否有 HTML?

可以,首先你的 key 在末尾要带上 HTML 指令 !html(你可以自定义)。

其次,不要有 block 级别的元素,可以用 strongemcodekbda,这些元素会有一定的样式。

如何转义花括号?

This '{isn''t}' obviousThis {isn't} obvious

参考 https://unicode-org.github.io/icu/userguide/format_parse/messages/#quotingescaping

文案如何不断章?

不断句和不断章,这个在国际化的场景下非常重要。不断句可以利用插值,那么不断章(即一个文案中可能有多个段落)怎么处理呢?

你的 key 需要有 !lines 指令(同样可以自定义),你写文案的时候,该文案是带换行(\n)的。

文案中的每一行,会被解析成 pul > li(该行以 1.␣2.␣ 等打头)或 ol > li(该行以 *␣ 打头)。

!html!lines 是可以合起来用的,比如 !html!lines!lines!html(建议选择一种风格,不要都用)。

文案中的链接怎么跟渠道链接配置结合?

你只需要在调用工厂方法的时候,第三个 options 参数中传入 extraValues 即可:

windXIntl(messages, LOCALE, { // LOCALE 视你应用的具体情况而定,你也可以通过 options 做一些定制
  extraValues: LINKS
});

以上,LINKS 是你的应用在 viper 配置的渠道链接的输出。

而你在定义你的文案时,这么定义:

{
  "x:message:about_xx_with_some_link!html": "...,详情可以查看 <a href=\"{help:xxx}\" target=\"_blank\">帮助文档</a>"
}

注意 help:xxx 不可定义成 help.xxx,会报错(至少我当时用的时候是这样)。

于是,当你 intl('x:message:about_xx_with_some_link!html') 的时候,其中的链接自然而然地被替换成了渠道链接中对应的配置。

但是,如果渠道链接是需要参数的,就无法这么做了。

文案中有 HTML 和换行,但 key 末尾没有指令,如何正常展示?

首先,强烈推荐 key 末尾带上 !html!lines 指令,它的好处在于看到 key 就知到它长什么样,而且你不需要额外的编码就可以自动展示成你期望的样式。

但如果你一定不加,你可以用 intl 的第三个参数,htmllines 可以同时存在,也可以只有一个为 true

intl('x:message:with_html_but_no_indicators', undefined, {
  html: true,
  lines: true
})

如何避免传错 key?

你必须本地有一份「完整」的兜底文案,这很重要,一是保证代码的完整性,二是,在使用 TS 的场景下,可以帮你避免输错 key 的场景。