DSH plugin 报 ERR_REQUIRE_ESM 与 dsh-tools 重复实例:构建与模块解析的修复
DSH plugin 报 ERR_REQUIRE_ESM 是插件被编译成 CommonJS 却依赖 ESM-only 的包,报 reading 'prepare' of undefined 是 @deepseek-ai/dsh-tools 被装出多份实例、符号查找冲突。 前者改 ESM 构建、后者统一依赖提升;都装不活就先回 DSH Plugin Hub 换已发布版。
DSH plugin 两段报错逐字解读:ESM 加载冲突与 prepare 未定义
ERR_REQUIRE_ESM 是模块格式冲突(CJS require 了 ESM-only 包),reading 'prepare' of undefined 是重复实例冲突(工具包被装了两份)。 两段报错(来源):
ERR_REQUIRE_ESM——加载插件时 Node 抛错:CommonJS 代码 require 了一个只提供 ESM 导出的包;触发时机是插件构建产物是 CJS、却依赖了 ESM-only 的包(典型如@deepseek-ai/dsh-tools);reading 'prepare' of undefined——插件运行时在undefined上读prepare属性;触发时机是@deepseek-ai/dsh-tools存在两份实例,内部 symbol-key 查找失效,工具调度崩溃;- 判断:前者是构建格式问题,后者是依赖实例问题——都是插件侧缺陷,用户改不了源码,但可以换发布版。
DSH plugin 报错根因:构建格式不对 + dsh-tools 多实例
两条根因:一是插件构建产物模块格式不对(CJS 装 ESM-only 依赖必炸),二是 dsh-tools 被多实例加载(peer 依赖没单一化)。 展开说:
- 模块格式不匹配:插件必须构建成 ESM(
"type": "module")——dshbase 明确这条规范(来源);Node 的 ESM 规则是 ESM-only 包只能被 ESM 代码加载(来源),编译成 CJS 就报ERR_REQUIRE_ESM; - 多实例冲突:插件的 peer 依赖拉进了第二份
@deepseek-ai/dsh-tools,两个实例用各自的 symbol-key 做内部查找,工具调度时互相找不到(来源); - 修复权在作者:构建配置和 peer 范围都写在插件包里,用户侧只能通过重装触发依赖提升,或换发布版。
解决 DSH plugin 构建报错:改 ESM 构建 → 统一依赖提升 → 重装验证
作者侧改构建与依赖声明;用户侧重装触发 dedupe、或直接换 Hub 发布版。 步骤:
- 改 ESM 构建(作者侧)——插件
package.json声明模块类型:构建产物输出 ESM 格式(json{ "type": "module" }import/export,而非module.exports);用 tsup/rollup 时把 format 设为'esm',重新构建并发布(来源); - 统一依赖提升(用户侧)——先查 profile 里 dsh-tools 是不是只有一份:
输出大于 1 说明装了两份——卸载相关插件后重装,让 pnpm 把 peer 依赖提升为单实例;bash
dsh plugin --profile web list grep -c '"@deepseek-ai/dsh-tools"' ~/.dsh/profiles/web/package.json - 重装验证——
dsh plugin --profile web remove <包名>后重新add,重启宿主,不再报ERR_REQUIRE_ESM或reading 'prepare' of undefined即修复; - 换已发布版(兜底)——反复装不活就回「设置 → 插件市场」(DSH Plugin Hub)换通过校验的发布版——构建问题是 git 分发常见坑,Hub 版已过校验,装完重启验证。
DSH plugin 修复后怎么验证?依赖单份检查与宿主加载测试
修完别只看安装命令退出码——用 pnpm why 查依赖树里 dsh-tools 是否只剩一份、用启动日志确认两个报错消失、插件能力真的出现才算修好。 按顺序执行:
-
查依赖树确认 dsh-tools 只剩一份——在插件所在工作区执行:
bashpnpm why @deepseek-ai/dsh-tools输出里只出现一条依赖链(如
dependencies: <插件名> > @deepseek-ai/dsh-tools)即去重成功;出现两条及以上说明仍是多份,回上节第 2 步重装提升。 -
复核 profile 声明只有一次:
bashgrep -c '"@deepseek-ai/dsh-tools"' ~/.dsh/profiles/web/package.json输出
1即单份;输出大于1则继续处理多实例。 -
检查插件构建格式(作者侧自验)——确认插件
package.json声明了 ESM:bashgrep '"type"' <插件目录>/package.json输出
"type": "module"即格式正确;没有该行说明仍是 CommonJS,回上节第 1 步。 -
重启宿主看启动日志:
bashdsh web启动过程不再出现
ERR_REQUIRE_ESM或reading 'prepare' of undefined,日志正常进入 Web 服务监听,即两个报错已消失。 -
触发一次插件能力——在 Web UI 里调用该插件提供的工具/命令,正常响应说明插件真正加载进宿主;仍报错就按
without inject等新报错回对应章节。
注意事项:DSH plugin 构建报错改 ESM 构建
ERR_REQUIRE_ESM是格式问题,升级 Node 只能缓解部分场景,根治要插件改 ESM 构建。reading 'prepare' of undefined先查依赖树里 dsh-tools 是否多份,重装触发 dedupe。- 两类都是插件缺陷,用户侧别去改宿主配置硬绕。
- git 分发缺构建产物/格式不对的插件,优先走 Hub 已发布版。
- 其他安装报错可参考安装报错排查。

常见问题
DSH plugin 报 ERR_REQUIRE_ESM 是 CommonJS 代码 require 了一个只提供 ESM 导出的包——插件被编译成 CommonJS,却依赖了 ESM-only 的包(如 @deepseek-ai/dsh-tools)。插件必须构建成 ESM:package.json 加 "type": "module",构建产物输出 ESM 格式(来源)。
DSH plugin 报 reading 'prepare' of undefined 是 dsh-tools 被装出两份实例:插件的 peer 依赖把第二份 @deepseek-ai/dsh-tools 拉进了依赖树,两个实例用各自的 symbol-key 做内部查找,工具调度时就崩。让 @deepseek-ai/dsh-tools 只作为单一共享依赖(peer 或只 bundled 一次),或请作者修 peer 版本范围(来源)。
DSH plugin 改 ESM 构建:package.json 加 "type": "module",确保构建产物输出 ESM 格式(import/export 而非 module.exports);用 tsup/rollup 等打包器时指定 format: 'esm',重新构建发布后重装插件(来源)。
DSH plugin 统一 dsh-tools 依赖:检查 profile 的依赖树里 @deepseek-ai/dsh-tools 只有一份:卸载相关插件后重装,让 pnpm 把 peer 依赖提升为单实例;还不行就反馈作者收紧 peer 版本范围。插件装不活时,先回 DSH Plugin Hub 换已通过校验的发布版更快。
相关术语
- ERR_REQUIRE_ESM
- ERR_REQUIRE_ESM 是 Node.js 在 CommonJS 代码用 require 加载一个仅提供 ESM 导出的模块时抛出的错误,表示模块格式不匹配。— Node.js 官方文档
- ESM(ECMAScript Modules)
- ESM 是 JavaScript 的官方模块系统(import/export),通过 package.json 的 "type": "module" 声明;Node 要求 ESM-only 包必须被 ESM 代码加载。— Node.js 官方文档
- CommonJS
- CommonJS 是 Node.js 的经典模块系统(require/module.exports),与 ESM 互不通用;插件被编译成 CommonJS 就无法加载 ESM-only 的依赖。— Node.js 官方文档
- peer 依赖(peer dependency)
- peer 依赖声明插件期望宿主提供某个共享包(如 @deepseek-ai/dsh-tools),要求只存在单一实例;peer 版本范围过宽会拉进第二份实例,导致符号查找冲突。— dshbase 常见问题排错
来源
- dshbase 常见问题排错(插件类报错)· dshbase
- Node.js 官方文档(ESM 模块系统)· Node.js
- DeepSeek Harness 插件发布文档(插件构建与包格式规范)· deepseek-ai