中文EN

dsh-plugin-chinese

ui已测通过npmMIT

给只提供英文简介的已安装 DSH 插件自动补上中文简介,启动时以及每次插件变动后各跑一次,插件名称一律不改。原本已导出语言包的插件刷新页面即生效,原本没有语言包导出的也会自动补上:内存注入层即时生效,写入磁盘的语言包需重启一次。

下载量 / Downloads
895
依赖体积 / node_modules
0.69 MB
测试时间 / Tested
2026-11-07
DSH 版本 / Version
0.2.2-rc.1

安装

dsh plugin --profile web add dsh-plugin-chinese

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

README

dsh-plugin-chinese · 插件汉化

自动给每个已安装的 DSH 插件补上中文功能简介。

插件名一律保持原样 —— 只写 description,不写 title。DSH 在缺少 title 时会回落到 package.json 的 name,所以列表里显示的名字永远是包名或作者自带的中文名,方便按名字找插件。

安装

npm install dsh-plugin-chinese

装好后在 profile 的 cordis.patch.yml 里插一行,让它随宿主加载:

- insert:
    - id: auto-i18n
      name: 'dsh-plugin-chinese'

重启 DSH 生效,之后新装插件自动补中文简介。

为什么需要它

DSH 读取插件显示信息的链路是:

插件页 → 宿主 readPluginMeta(specifier)
       → 读 <pkg>/locale/en.json
       → 扫同目录所有 *.json 当语言包
       → 前端按当前界面语言取对应字段

只有当包里存在 locale/zh.json、且 package.json 的 exports 暴露 ./locale/*.json 时,中文简介才会显示。大量插件作者只写了英文 description,于是插件页长期是英文。

本插件自动补这两样东西。

翻译来源(两级回退)

1. 作者原稿优先 —— 包里若已有 zh-CN.json / zh_CN.json 这类作者写的中文,直接采用,不再送机翻(避免把作者的好译文翻坏)。

2. 宿主 translator 服务 —— DSH 自带的 ctx.get('translator');本机实测它走 Bing 匿名通道,不需要 API key。

拿不到 translator 时不会乱写:该插件会被记为 翻译服务不可用 跳过,等下次巡检再试。

译文落地前会过一遍术语表(GLOSSARY),修正机翻常译错的专有名词。

触发时机

时机 · 说明

启动后 4 秒 · 装完重启即自动补一遍

每 30 分钟 · 定时巡检(intervalMinutes 可调)

插件变动后 1.5 秒 · 监听 plugin-manager/changed,新装或升级后立刻补

新装插件自动生效,不需要手工跑脚本。

本插件用三条腿走路:写磁盘语言包(长期、对所有入口都成立),加一层内存注入(立刻生效、不等重启)。

三条腿

一、内存注入(立刻生效)

宿主把插件元信息从磁盘读出来后,会在内存里缓存。只写文件的话,界面要等下次重读才变。

所以插件在启动几秒后,给返回插件元信息的四个函数各包一层,把 zh 字段补进 meta 里:

服务 · 方法 · 作用

pluginPackages · metaOf · 元信息的真正源头

pluginManager · listBundles · 「已安装」分组的 bundle 列表(含内嵌 rows)

pluginManager · listPlugins · Loader 条目列表(右侧启用开关所在)

pluginInventory · list · 插件清单 Remote 网关

前端 resolveText() 从 { en, zh } 里自然取到中文。不碰 DOM、不改别人的文件、不需要重启。

这一层读中文直接读磁盘文件(readdir + readFile),完全不走 Node 模块解析器 —— 这正是它能绕开 exports 解析缓存的原因:重启后会显示成什么样,它现在就显示成什么样,两者永远一致。

补在「真身」上,不是补在代理上

DSH 的插件服务放在 Cordis 容器里,ctx.get() 拿到的是 getTraceable() 包出来的 Proxy:对它赋值只会落到「当前 context 的 shadow 副本」上,而宿主网关调用服务时是用另一个 context 重新 get 的(api-gateway 里 receiverContext.extend(...).get(service)),看到的是另一份 shadow —— 补丁就白打了。

所以这里先用 Symbol.for('cordis.original') 把 Proxy 剥回真身,再补到真身和它的原型上。

自检看的是结果,不是次数

判断「注入有没有真的生效」,不能只看包装函数被调了几次:计数为 0 既可能是没人调用,也可能是计数写在了别的实例上。插件每 60 秒自己做一次探针 —— 真的调一遍 listBundles,数返回结果里有几条 meta.description.zh,把「皮挂上了」和「拿到的是中文」分开报告。

二、写磁盘语言包(长期生效)

同时把译文写进 <pkg>/locale/zh.json,这样即使哪天本插件被卸掉,中文简介仍然在。

三、插件详情页的 README(1.4.0 起)

插件列表只显示一句话简介;点进插件详情,读的是它仓库里的 README.md,默认仍是英文。

插件市场(dsh-m)是用 GET /dshm 这个 HTTP 接口把 README 取回来再渲染的。本插件启动时把这条路由的处理函数包一层:请求返回后,如果正文里有 readme 字段,就先翻成中文再交给前端。

  • 只翻正文,代码块、行内代码、链接地址、HTML 标签一律原样保留(先替换成占位符再翻,翻完还原);
  • 长文按 2500 字切块,块间停 500ms,避免被限流;单篇最多翻 24000 字,超出部分保持英文;
  • 译文按 包名 + 原文哈希 缓存在 $DSH_HOME/auto-i18n/readme-cache.json,同一个版本第二次打开就是秒开;
  • 拿不到 translator 时原样返回英文,不会把页面弄坏。

第一次打开某个插件的详情页会等几秒(一篇 8000 字的 README 约 4 秒),之后走缓存。

生效条件

Node 会缓存 package.json 的 exports,因此分三种情况:

包的状态 · 写入磁盘后

已声明 ./locale/*.json 导出,只是缺文件 · 刷新页面即生效

完全没有 exports 字段(旧式解析) · 刷新页面即生效

有 exports 但没有 locale 映射,被自动补上 · 磁盘语言包需重启一次;内存注入层已即时生效

第三种情况会列在 report.json 的 restartNeeded 里。

配置

字段 · 默认 · 说明

enabled · true · 关掉后不再扫描与翻译

intervalMinutes · 30 · 定时扫描间隔(分钟)

gapMs · 1200 · 翻译请求间隔(毫秒),避免被限流

状态文件

都在 $DSH_HOME/auto-i18n/:

  • cache.json —— 原文 → 译文缓存,避免重复请求
  • report.json —— 最近一次扫描明细(scanned / translated / skipped / failed / restartNeeded)
  • auto-i18n.log —— 出错或有大变动时记一行

安全约束

  • 绝不写 title,插件名永不被改;注入层也不会凭空造 title.zh
  • 已有的 zh 一律不覆盖(作者的稿子、别家插件的成果都不动)
  • 写入用「先写临时文件再 rename」,断开 pnpm 硬链接,不污染 pnpm store
  • 只在 locale/ / locales/ 下动手,不改包的其它文件
  • 原文已是中文的包直接跳过
  • 插件被禁用/卸载时包装函数全部还原(dispose())

开发

node test.mjs          # 磁盘翻译那条路:26 项断言
node test-inject.mjs   # 内存注入那条路:33 项断言

test.mjs 在临时目录造假插件包,覆盖:有导出缺文件 / 有 exports 缺映射 / 已有中文 / 有原版中文名 / 无 exports / 原文即中文,断言「不写 title」「保留原版名」「exports 该补才补」「幂等」。

test-inject.mjs 用假 service 覆盖四条通路,断言「只补 zh、不覆盖已有 zh」「纯字符串 meta 转对象要留住 en」「bundle 内嵌 rows 也投影」「幂等不套两层」「dispose 后完全还原」。

已知限制

  • 升级插件会覆盖本插件写入的 locale/zh.json,但下次巡检会自动重新补上。
  • 若插件作者后续自己加了中文简介,本插件会识别并跳过,不会覆盖。

License

MIT

更新日志

1.4.0

  • 新增:插件详情页的 README 也翻成中文(拦截插件市场的 /dshm 路由,代码块与链接原样保留,译文落盘缓存)。
  • 修:上一版自检定时器里有一处未声明变量,在严格模式下会把宿主进程带崩,已修正并补了兜底。
  • 1.3.0 — 修掉一个会把宿主带崩的低级错误(自检定时器引用未声明变量,严格模式下抛 ReferenceError 导致宿主进程退出);给自检与挂载定时器都加了异常兜底,此后插件出错只会写日志,不再影响宿主。同时修正 profile 目录的解析方式(支持 file: 方式安装的插件),并让术语表覆盖更多机翻腔。
  • 1.2.2 — 加图标与安装前后对比示意图。
  • 1.2.1 — 补 repository / homepage / bugs 字段,插件市场的下载数从此能统计到。
  • 1.2.0 — 增加内存注入层:不必重启,刷新插件页即可看到中文。

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:7,最后更新 2026-11-05

链接

GitHub · Homepage · npm

同类插件