DSH 核心升级与插件冲突排查排障记录
一次从”老版本跑不起来”到”极简环境彻底清净”的完整复盘。五个报错看着各不相干,最后都指向同一条主线:核心太旧、环境太乱、插件太多。
一、背景:一个旧环境,两个隐藏的雷
这次升级之前的机器,状态是这样的:
- Node 用 fnm 管理,停在 v22.23.4;
- DSH 全局装的是
0.1.2-alpha.1; - 系统里还留着一个指向 macOS 桌面版 App 的
dsh软链接(/usr/local/bin/dsh)。
表面看着能用,实际埋了两个雷:一个是核心版本太旧,一个是终端里敲 dsh 执行的其实不是你装的那个新版。
触发问题的导火索很普通:想用 npx 跑最新版,或者想加载个第三方插件,结果模块丢失、版本冲突一起冒出来。
目标就一个:把 DSH 本体从 0.1.2-alpha.1 升到 0.2.2-rc.1,Node 升到 v24.22.2,把僵尸配置清干净,让 Web 端能稳定起来。
二、五个报错,一条主线
1. 模块缺失:failed to import loader entry ... missed the module table
原因:正在跑的 DSH 核心还是 0.1.2-alpha.1,而插件依赖的新模块(比如 @deepseek-ai/dsh-client-store)是更晚的版本才引入的。核心里压根没有这张模块表,插件自然 import 不到。
解决:根子上的办法只有一个——升级 DSH 核心。但这一升,就牵出了后面一连串环境问题。
2. 环境混乱:EBADENGINE 和指向桌面版的幽灵路径
原因有两个:
- 全局旧 DSH 跑在 Node 22 下,新版 DSH 要求更高的 Node 引擎,引擎对不上,报
EBADENGINE; - 终端里敲
dsh,系统实际执行的是/usr/local/bin/dsh(还指着旧的桌面版 App),而不是 npm 全局装的新版——你以为升级了,其实一直在跑旧的。
解决:
- 用
fnm install 24把 Node 升上去; - 找到新版的真实路径(
~/.local/share/fnm/node-versions/v24.22.2/installation/bin/dsh); - 强制覆盖旧软链接:
sudo ln -sf <新版真实路径> /usr/local/bin/dsh。
3. 依赖被拦:ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION / ERR_PNPM_IGNORED_BUILDS
原因:pnpm v11 以后默认开了供应链安全保护。它不装”发布不足 24 小时”的包,也不许未经许可就跑底层原生编译脚本(比如 node-pty、cloudflared)。
解决:
- 安装/修复依赖时,强制绕过发布时间限制,加
--config.minimum-release-age=0; - 放行原生编译脚本:编辑
~/.dsh/profiles/web/pnpm-workspace.yaml,加allowBuilds:列表;或者 npm 全局安装时追加--allow-scripts=...参数。
4. 配置里的”幽灵包”(Zombie Bundles)
原因:反复用 npx 启动、或者网络波动中断,导致插件的依赖被删了,但 package.json 的 dsh.profile.bundles 或者 cordis.patch.yml 里还留着加载指令。启动时按配置去找包,找不到,直接崩。
解决:用社区脚本 dsh-fix-duplicate-loader-id 把重复的 insert 转成幂等的 id patch;或者直接手动编辑 cordis.patch.yml,删掉报错的那个包名。
5. 第三方全家桶冲突:duplicate loader entry id: dsh-market
原因:装了一堆第三方 UI 全家桶(比如 @linxin666/dsh-web-all)和实验性功能包,它们内部的依赖互相打架,或者调了已经废弃的旧版 API。
解决:做减法。 把引发崩溃的插件(比如 dsh-agents、pua、mnemon 还有第三方任务板)逐个或整体卸载:
1 | dsh plugin --profile web remove <包名> |
每卸载一个就立刻 dsh web 测一次,直到能正常起来为止。
三、从零到可用的完整步骤
第一步:升级 Node 环境(fnm)
1 | fnm install 24 |
第二步:启用 pnpm,升级 DSH 核心
1 | corepack enable pnpm |
第三步:修正系统软链接
1 | # 强制覆盖指向旧 App 的软链接 |
第四步:修复 profile 依赖、清理僵尸插件
1 | # 安装 profile 依赖(绕过发布冷却期) |
四、几条踩出来的经验
放弃
npx,统一用全局命令。npx会生成一堆临时缓存(~/.npm/_npx),还特别容易和常驻的 Web Server 撞端口、混版本。统一npm install -g,省心。警惕第三方”全家桶”。
dsh-web-all这种聚合包装着省事,但只要里面某个子依赖和新版 DSH 不兼容,整个 DSH 就起不来。按需单独装单项插件,别图省事。认识 DSH 的”双配置文件”。
package.json里的dsh.profile.bundles控制装哪些包,cordis.patch.yml控制插件树怎么插入。卸载插件时,两处都要清干净,只清一处就是埋雷。PNPM 的供应链策略要会绕。 开发调试阶段,只要来源可信,记得加
--config.minimum-release-age=0,否则刚发布的新版本插件永远装不上。善用排障工具。
dsh-fix-duplicate-loader-id能救命,遇到 loader 冲突先拿它--dry-run体检一遍。
五、最终能用的极简环境
- Node:v24.22.2(fnm)
- DSH 核心:v0.2.2-rc.1(npm 全局)
- pnpm:Corepack 代理
- 启动命令:
dsh web
小注:如果之后终端偶尔还报”任务板拿不到 session”,
Ctrl+C停掉服务,执行dsh plugin --profile web remove @linxin666/dsh-client-ui-task-board --config.minimum-release-age=0就彻底清净了。
折腾归折腾,这一路的坑其实很有代表性:核心版本、Node 引擎、软链接、依赖缓存、插件配置,任何一个环节错位,都能让一个本来能用的东西说崩就崩。把它们串起来看,排查思路反而清晰了——先确认你跑的到底是不是你以为的那个版本,再做减法。
