dsh-plugin-dedupe: Add a plugin deduplication check for DSH profiles

前言

用 DSH 时,插件一般装在 profile 目录里,由 profile 的 package.json 统一管理。装得多了会出现一个问题:同一个插件可能被声明两次,比如一次来自 github:、一次来自本地 file:,包名相同、来源不同,结果 node_modules 里同名包多份并存,轻则占空间,重则让运行时加载到错误版本,排查起来很费时间。

dsh-plugin-dedupe 解决的就是这件事:在安装前扫描 profile,发现重复声明直接阻断安装。下面介绍它的功能、安装和使用方式。

这是什么

dsh-plugin-dedupe(DSH 插件去重守护)是 Jiaoyc224 维护的开源插件,MIT 许可证,当前版本 0.1.0。一句话定位:防止在 DSH profile 中重复安装同一插件。

它有两种工作方式:

1、作为 DSH 插件加载时,启动阶段自动扫描当前 profile 的 package.json 依赖和 node_modules 实际安装情况;
2、作为 pnpm install 的 preinstall 钩子,在安装前运行检查脚本,发现错误时返回非零退出码,阻断安装。

它在 package.json 中声明了 peerDependencies: @deepseek-ai/cordis ^4.0.1,且标记为 optional。

它检查什么

检测逻辑分两层:先解析 package.jsondependencies / devDependencies / optionalDependencies / peerDependencies,再扫描 node_modules 统计实际安装的包名。具体规则如下:

检测类型 行为 说明
同名依赖重复声明(不同来源) 错误 同一包名在 package.json 中出现多个不同来源,如 github + file
同名依赖多字段声明(同一来源) 警告 同一包在 dependencies/devDependencies 中声明且来源协议相同
node_modules 同名包多次 警告 同名包在 node_modules 中出现多次(不同版本/来源并存)
未声明但已安装的 dsh-* 插件 警告 可能是旧残留或手动复制进来的

只有「不同来源的重复声明」算错误,会阻断安装;其余情况降级为警告。实际的阻断输出大致是这样:

[dsh-plugin-dedupe] 扫描 profile: C:\Users\<your-user>\.dsh\profiles\web
❌ 检测到重复声明: "dsh-agent-teams" 在 package.json 中有多个来源:
   github:NanmiCoder/dsh-agent-teams
   file:E:/fake/dsh-agent-teams
[dsh-plugin-dedupe] 检测到 1 个重复插件错误,已阻断安装。

安装

在 DSH profile 目录下直接安装:

cd <your-dsh-profile-dir>  # 例如: C:\Users\<user>\.dsh\profiles\web
pnpm add github:Jiaoyc224/dsh-plugin-dedupe

或者使用 dsh plugin 命令:

dsh plugin --profile web add github:Jiaoyc224/dsh-plugin-dedupe

启用 preinstall 钩子

preinstall 钩子需要手动添加。编辑 profile 的 package.json,在 scripts 中加入:

{
  "scripts": {
    "preinstall": "node node_modules/dsh-plugin-dedupe/scripts/check-duplicates.mjs"
  }
}

这样每次运行 pnpm install 前,都会先执行去重检查,发现重复插件会返回非零退出码,阻断安装。

有一个首次安装的注意点:刚装完插件后,需要先运行一次 pnpm install 生成 node_modules/dsh-plugin-dedupe,其后的 pnpm install 才会触发 preinstall 钩子。这一步可以用 pnpm install --prefer-offline 避免死循环。

独立运行检查

不想挂钩子的话,检查脚本可以单独运行:

# 在 profile 根目录下
node node_modules/dsh-plugin-dedupe/scripts/check-duplicates.mjs

# 或指定 profile 目录
node node_modules/dsh-plugin-dedupe/scripts/check-duplicates.mjs --profile /path/to/profile

插件的 bin 字段也提供了 dsh-dedupe 命令,指向同一个检查脚本。

环境变量配置

插件支持两个环境变量:

环境变量 说明 默认值
DSH_DEDUPE_WARN_ORPHANS 设为 true 时也警告非插件类的未声明依赖 false
DSH_PROFILE_DIR 手动指定 profile 根目录 自动向上查找

适用场景与注意

适合的场景很明确:profile 里插件数量多、来源杂(npm、github、本地 file、link 混用),或者经常在本地调试插件、需要来回切换来源的 DSH / 智能体开发者。如果你只有一个 profile、只从单一来源装插件,这个插件的作用有限。

几点注意:

1、插件以当前 dsh 进程的权限运行,安装第三方插件前建议先检查其源码和许可证;
2、preinstall 钩子只对 pnpm install 生效,需要手动在 profile 的 package.json 中配置;
3、错误(阻断安装)和警告(仅提示)的边界见上文规则表,按需通过 DSH_DEDUPE_WARN_ORPHANS 调整未声明依赖的提醒力度。

结尾

dsh-plugin-dedupe 做的事情很小但很实际:把「插件重复安装」从事后排查变成安装前拦截。如果你在 DSH profile 管理上遇到过同名插件多来源并存的问题,值得一试。

  • 社区目录页:https://www.skillhub.cn/plugins/Jiaoyc224/dsh-plugin-dedupe
  • GitHub 仓库:https://github.com/Jiaoyc224/dsh-plugin-dedupe
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye