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

i18n-locales-shared

v1.0.0

Published

Single source of truth for i18n keys (multi-frontend & multi-backend)

Readme

i18n-repo 独立仓库国际化技术方案(前后端通用)

1. 目标

建立 独立 i18n 仓库(Single Source of Truth),实现:

  • 多前端、多后端 共用同一 Key 源,前后端统一 Key
  • 多语言可扩展
  • 通过 Key 前缀(应用/域) 避免多端 Key 冲突
  • 可 CI 校验(Key 一致、占位符一致)
  • 可版本化发布,多端可钉版本、分批升级

2. 总体架构

2.1 单源多端消费

frontend-web    ─┐
frontend-admin  ─┤
frontend-mobile ─┼── @company/i18n-locales (NPM / Git / CDN)
backend-user    ─┤
backend-order   ─┤
backend-payment ─┘
                        │
                        ▼
                   i18n-repo(唯一 Key 源)
  • 多前端:共用同一 NPM 包,通过 Key 前缀(域) 区分应用,避免 Key 冲突。
  • 多后端:共用同一 Key 源,API 统一返回 message_key,由前端或网关按语言解析;后端可不依赖 NPM 包,仅维护 Key 字符串常量或从 i18n-repo 同步定义。

3. 仓库结构规范

i18n-repo/
 ├── locales/
 │   ├── en-US.json
 │   ├── zh-CN.json
 │   └── ja-JP.json
 ├── keys/
 │   ├── frontend/         # 前端团队维护(仅前端展示用 Key)
 │   │   ├── common.json
 │   │   ├── explorer.json
 │   │   ├── faucet.json
 │   │   ├── dex.json
 │   │   └── indexer.json
 │   └── backend/          # 后端团队维护(仅后端返回用 Key)
 │       ├── common.json
 │       ├── explorer.json
 │       ├── faucet.json
 │       ├── dex.json
 │       └── indexer.json
 ├── scripts/
 │   ├── validate-keys.js
 │   └── build.js
 └── package.json
  • 域划分:业务域为 common、explorer、faucet、dex、indexerlocales/*.json 为单文件合并所有 Key。
  • 前后端文件分离(避免冲突):同一域下前端只改 keys/frontend/<domain>.json,后端只改 keys/backend/<domain>.json互不编辑同一文件,避免合并冲突;看路径即可知道 Key 是给前端用还是后端用。同一 Key 只能出现在 frontend 或 backend 其一,不能重复。
  • 多域引用:一个前端可以同时引用多个域(如 common + explorer + faucet),按需使用对应 Key;引入整包时所有 Key 在同一份 locale 中,使用时 t('common.ui.submit')t('explorer.block.title') 等混用即可。若需按域按需加载减小体积,可在 build 中按域产出多份 JSON 供前端分别引用。

4. Key 命名规范(防冲突核心)

4.1 命名规则(域 + 消费端 + 业务)

<domain>.<consumer>.<module>.<feature>.[<action>]
  • <domain>:业务域,本项目为 common、explorer、faucet、dex、indexer
  • <consumer>(必选)从 Key 本身就能看出是前端还是后端定义,避免前后端误用同一 Key 或重复定义。
    • 前端:固定用 ui,表示前端展示用(如 common.ui.login.titleexplorer.ui.block.title)。
    • 后端:用 error(错误码文案)、api(接口返回文案)等,表示后端返回用(如 common.error.networkexplorer.error.not_found)。

4.2 示例

| 域 | 前端 Key(.ui.) | 后端 Key(.error. / .api.*) | | -- | ----------------- | ----------------------------- | | common | common.ui.login.title、common.ui.submit | common.error.network | | explorer | explorer.ui.block.title、explorer.ui.tx.detail | explorer.error.not_found(示例) | | faucet | faucet.ui.claim.title、faucet.ui.claim.success | — | | dex | dex.ui.swap.title、dex.ui.pool.add | — | | indexer | indexer.ui.status.title、indexer.ui.sync.pending | — |

4.3 规则

  • 全小写
  • 使用 . 分层
  • 域后紧跟消费端:前端统一 .<domain>.ui.*,后端统一 .<domain>.error.*.<domain>.api.*看 Key 即知归属
  • 禁止硬编码文案
  • 禁止重复 Key(同一 Key 字符串只能出现一次)

5. 文案文件格式规范

5.1 占位参数(可选)

可以。 本地化翻译中支持占位参数,格式为 {参数名}(如 {name}{code}{count})。同一 Key 在各语言中的参数名必须一致,仅文案内容可不同。

示例(locales):

"common.ui.welcome": "欢迎,{name}",
"common.error.with_code": "错误码:{code}"
  • 前端:传入变量替换占位符。例如 i18next:t('common.ui.welcome', { name: '张三' }) → 「欢迎,张三」。
  • 后端:API 返回 message_key + params,由前端或网关做替换。例如 { "message_key": "common.ui.welcome", "params": { "name": "张三" } }

CI 校验时建议检查:同一 Key 在各语言中的占位符集合一致(如 zh 有 {name} 则 en、ja 也须有 {name})。

locales/zh-CN.json

{
  "common.ui.login.title": "登录",
  "common.ui.submit": "提交",
  "common.error.network": "网络错误",
  "explorer.ui.block.title": "区块",
  "explorer.ui.tx.detail": "交易详情",
  "faucet.ui.claim.title": "领取",
  "faucet.ui.claim.success": "领取成功",
  "dex.ui.swap.title": "兑换",
  "dex.ui.pool.add": "添加流动性",
  "indexer.ui.status.title": "索引状态",
  "indexer.ui.sync.pending": "同步中"
}

locales/en-US.json

{
  "common.ui.login.title": "Login",
  "common.ui.submit": "Submit",
  "common.error.network": "Network error",
  "explorer.ui.block.title": "Block",
  "explorer.ui.tx.detail": "Transaction detail",
  "faucet.ui.claim.title": "Claim",
  "faucet.ui.claim.success": "Claim succeeded",
  "dex.ui.swap.title": "Swap",
  "dex.ui.pool.add": "Add liquidity",
  "indexer.ui.status.title": "Indexer status",
  "indexer.ui.sync.pending": "Syncing"
}

6. 前端接入(React / Vue 通用)

6.1 安装依赖

npm install @company/i18n-locales i18next

6.2 初始化 i18n

import zh from '@company/i18n-locales/zh-CN.json'
import en from '@company/i18n-locales/en-US.json'

const resources = {
  zh: { translation: zh },
  en: { translation: en }
}

6.3 使用 Key(按域,前端用 .ui.*)

t('common.ui.login.title')
t('common.ui.submit')
t('explorer.ui.block.title')
t('faucet.ui.claim.success')

6.4 一个前端引用多个域

一个前端可以同时使用多个域的 Key(common、explorer、faucet、dex、indexer 等)。引入整包时所有 Key 已在一份 locale 中,无需按文件拆分引用;前端只使用带 .ui. 的 Key,按域混用即可,例如:

// 同一页面可混用 common、explorer、faucet 等(均为 .ui.* 前端 Key)
t('common.ui.submit')
t('explorer.ui.tx.detail')
t('faucet.ui.claim.title')

若希望按域按需加载以减小包体积,可在本仓库的 scripts/build.js 中按域产出多份 JSON(如 dist/common/zh-CN.jsondist/explorer/zh-CN.json),前端按需引用对应文件。


7. 后端接入(Key 模式推荐)

7.1 API 返回 Key(推荐,多后端通用)

各后端服务不依赖 NPM 包,仅在响应中返回 message_key(及可选 params),由前端或网关根据请求语言解析文案。

{
  "code": 10004,
  "message_key": "error.user.not_found",
  "params": { "userId": "123" }
}

7.2 多后端实现方式

  • 常量/枚举:从 i18n-repo 同步或手写 Key 常量,避免拼写错误。
  • CI 同步:可选脚本从 i18n-repo 生成各语言的 Key 列表或代码常量,供各后端仓库引用。

7.3 Go 示例

return Error("error.user.not_found")

8. Key 新增 / 修改流程(变更规范)

8.1 新增 Key

  1. 确定归属:前端用 → 在 keys/frontend/<domain>.json 添加;后端用 → 在 keys/backend/<domain>.json 添加(同一 Key 只能归属一端)。
  2. 在所有 locales/*.json 添加翻译。
  3. 提交 PR。
  4. CI 校验 Key(含前后端 Key 无交叉、keys 与 locales 一致)。

8.2 修改文案(不影响 Key)

  • 仅更新 locales/*.json
  • 发布 patch 版本

8.3 废弃 Key

  • 标记 deprecated
  • 两个版本后移除

9. CI 校验规则(防 Key 漏失)

校验内容

  • 各语言 Key 是否一致(zh-CN、en-US、ja-JP 等所有 locales 同 Key 集)
  • keys/frontend 与 keys/backend 的 Key 无交叉:同一 Key 只能出现在 frontend 或 backend 其一,避免归属不清
  • keys 并集与 locales 的 Key 一致:keys 中定义的 Key 须在 locales 中存在,locales 中的 Key 须在 keys 中有归属
  • 参数占位符是否一致(如 {name} 在各语言中一致)

validate-keys.js 行为

  • 收集 keys/frontend/*.jsonkeys/backend/*.json 中所有 Key
  • 校验无 Key 同时出现在 frontend 与 backend
  • 校验各 locale 文件 Key 一致
  • 校验 keys 并集与 locales Key 集一致

10. Code 长度与 Key 规模规范

推荐长度

| 项目 | 推荐 | | --------- | -------- | | Key 长度 | 20–60 字符 | | 单文件 Key 数 | < 1000 | | 命名层级 | 3–5 层 |


11. 冲突防护策略

命名空间隔离(域 + 消费端,看 Key 即知归属)

  • 前端 Key<domain>.ui.*(如 common.ui.、explorer.ui.),看 Key 即知是前端定义
  • 后端 Key<domain>.error.*<domain>.api.*(如 common.error.、explorer.error.),看 Key 即知是后端定义
common.ui.*     common.error.*
explorer.ui.*   explorer.error.*
faucet.ui.*     faucet.error.*
dex.ui.*        dex.error.*
indexer.ui.*    indexer.error.*

Key 归属(前后端文件分离,避免同文件冲突)

| 路径 | 维护方 | 说明 | | ---- | ------ | ---- | | keys/frontend/.json | 前端 | 仅前端展示用 Key(UI 文案、前端提示等);看路径即知归属前端 | | keys/backend/.json | 后端 | 仅后端返回用 Key(API 错误码文案、后端提示等);看路径即知归属后端 |

同一域(如 explorer)下:前端只改 keys/frontend/explorer.json,后端只改 keys/backend/explorer.json,互不编辑同一文件,避免冲突。同一 Key 只能出现在 frontend 或 backend 其一。

域 Ownership(业务归属)

| 域 | 说明 | | -- | ---- | | common | 通用 UI / 错误等 | | explorer | Explorer 相关 | | faucet | Faucet 相关 | | dex | DEX 相关 | | indexer | Indexer 相关 |


12. 发布与版本管理

版本规则(SemVer)

| 变更 | 版本 | | ------ | ----- | | 新增 Key | minor | | 修改文案 | patch | | 删除 Key | major |


发布流程

npm version minor
npm publish

CDN 同步:

https://cdn.company.com/i18n/v1.4.0/zh-CN.json

13. 多端消费与版本策略

13.1 多前端消费

| 策略 | 说明 | | ---- | ---- | | 统一包 | 所有前端依赖同一 NPM 包 @company/i18n-locales,按需使用各域 Key(common.、explorer.、faucet.* 等);一个前端可引用多个域,混用即可。 | | 版本钉钉 | 各前端在 package.json 中钉住版本(如 ^1.4.0),升级时统一升级或按需升级;新增 Key 为 minor,各端可滞后升级。 | | 按需加载(可选) | 若包体积敏感,可在 i18n-repo 的 build 中按域产出多份 JSON(如 common/zh-CN.jsonexplorer/zh-CN.json),前端按需引用多个域文件。 |

13.2 多后端消费

| 策略 | 说明 | | ---- | ---- | | 仅返回 Key | 推荐:API 只返回 message_key(及可选 params),由前端或网关根据语言解析;后端无需嵌入 NPM 包,仅维护 Key 常量或从 i18n-repo 同步。 | | Key 同步 | 通过 CI 或脚本从 i18n-repo 同步 Key 列表到各后端仓库(如生成 Go/Java 常量),保证 Key 存在且拼写一致。 | | 版本兼容 | 后端不依赖 NPM 版本;i18n-repo 删除/重命名 Key 时需走 major,并提前通知各后端下线旧 Key。 |

13.3 升级策略小结

  • 前端npm install @company/i18n-locales@<version>,建议统一跟随 minor,各端可分批升级。
  • 后端:以 Key 为契约,不强制跟版本;删除 Key 须发 major 并同步各服务。

14. 推荐团队协作流程

| 角色 | 职责 | | -- | ------ | | 产品 | 提供文案需求 | | 开发 | 添加 Key | | 翻译 | 补充语言 | | CI | 校验一致性 |


15. 最佳实践总结

  • i18n 独立仓库,单源多端消费
  • Key 唯一来源,多端通过 Key 前缀(应用/域) 分区,避免冲突
  • 多前端:同一 NPM 包 + 域前缀(common.、explorer.、faucet.、dex.、indexer.*),一个前端可引用多个域多后端:API 返回 message_key,前端/网关解析
  • CI 自动防漂移(Key 一致、占位符一致)
  • 语义化版本发布;多端可钉版本、分批升级