Repository navigation
Replies: 2 comments 1 reply
|
两处缺陷我都复核了,在最新代码上仍未修,而且我能在本机把崩溃文案逐字复现。但有一条关键事实要更正 —— 它要是不改,维护者一句"原生 Node 也解析不到"就能把报告挡回去。 1. 两处缺陷的位置缺陷 A —— 尾随斜杠绕过内置判定( export function barePackageName(request: string): string | undefined {
if (!request || request[0] === '.' || request[0] === '/' || request[0] === '\\'
|| request[0] === '#' || request.includes(':') || isBuiltin(request)) return
const first = request.indexOf('/')
if (request[0] !== '@') return first < 0 ? request : request.slice(0, first)
缺陷 B —— 三处
与你引的 V8 文案同一族 ⇒ 崩溃点确认就是这三行。 两处不是彼此独立,而是缺陷 A 是缺陷 B 的唯一可达触发器: 2. ⭐ 必须更正的一条:原生 Node 不把
|
|
感谢这条帖子的完整分析,也感谢 #8674 的探针复现。我不是来重复报 bug 的:我是 这个问题从 9 月到现在至少已有 10 条同源报告(#7031、#7377、#7903、#8250、#8674、#8986、#9318、#10387……),散在讨论区里,单独看每条都不完整。我把能减少你们决策成本的部分集中在这里,不做优先级上的要求。
1. 最新版本仍复现(隔离环境,2 分钟可跑)环境:Windows 11 / 内置 Node 24.21.0 / npm 安装 node node_modules/@deepseek-ai/dsh/lib/bin.js --profile clean --from-default-profile web --dump-config
node node_modules/@deepseek-ai/dsh/lib/bin.js plugin --profile clean add dsh-mqtt-tools@0.3.12 --save-exact
node node_modules/@deepseek-ai/dsh/lib/bin.js clean --no-open --port 53995
# 另开终端
curl http://127.0.0.1:53995/dsh-mqtt-tools/api/state返回: "library": { "mqtt": false, "aedes": false,
"error": "createRequire.resolve.paths is not a function or its return value is not iterable" }
触发链: 2. 根因补充(与 #9318 / PerryLink 的复核一致)
单独加 3. 补丁:把 Node 实际收到的 request 原样交给
|
| 文件 | 位置 | 传参 |
|---|---|---|
resolver.ts |
nativePackageDir L276 |
name |
resolver.ts |
routeScoped L591(当前唯一触发点) |
request |
resolver.ts |
routeLinked CJS 分支 L644 |
request |
profile-resolution/service.ts |
packageDirFromParent L143 |
name |
compatibility-preflight.ts |
manifestOf L38 |
bare |
同时删掉 5 处 as string[]:@types/node 里 resolve.paths(request): string[] | null,这个断言把 null 藏过了 tsc;删掉后编译器会直接标出全部调用点。worker 侧不用单独改:worker-bootstrap.ts 只是 import { installRuntimeInterception } from './resolver.ts',构建时同步。
git apply --stat:3 files changed, 17 insertions(+), 8 deletions(-)。完整 dsh-app-boot-fix.patch 见本楼附件。
如果你们想先要最小版:只改 routeScoped 一处 + helper,就是单个文件、十几行(helper 约 9 行 + 站点 1 行替换),也能消除当前所有已知触发(routeLinked 的 CJS 分支只在 entries 命中时才可达,nativePackageDir/packageDirFromParent/manifestOf 那三处是同型隐患)。另外据 #9318,dsh-plugin-package-inventory-deepseek 里也有同型调用(lib/index.js:47、lib/types/index.js:49),本补丁未覆盖,可以按需要一并处理。
4. 验证(改的是构建产物,不只是源码)
在隔离安装的 0.2.2-alpha.2 上,对 dsh-app-boot/lib/index.js(202809→203117B,1 个 helper 定义 + 5 个站点)与 lib/worker/profile-resolution-bootstrap.js(37385→37719B,4 处)打等价补丁:
| 场景 | state.library |
|---|---|
| pristine 运行时 + 全新 profile + 一步安装 | {"mqtt":false,"aedes":false,"error":"createRequire.resolve.paths is not a function or its return value is not iterable"} |
| patched 运行时 + 同一 profile 重启 | {"mqtt":true,"aedes":true,"error":null} |
| patched 运行时 + 另一个全新 profile + 一步安装 | {"mqtt":true,"aedes":true,"error":null} |
端到端也通过:broker 绑 127.0.0.1:18833 → client connect → subscribe probe/# → broker publish → broker.stats {connections:1, published:3, system:2}。
5. 想确认两件事
- 这个方向是否符合你们对
routeScoped语义的预期?另一种等价修法是“先对 request 去掉尾斜杠再判isBuiltin,内置名一律交还原生解析”(profile 解析器两处缺陷导致所有带依赖的第三方插件无法加载 #9318 提议的 A),对process/也成立;我选 B 是因为它保留路由能力、对任意 request 与 Node 行为一致。如果你们更倾向 A,我可以按 A 重做。 - 是否需要我补上游测试?建议三条:
nodeLookupPaths(parent,'process') === []而'process/'非空;fixture profile 里放node_modules/process后routePath('process/', …)返回native+ packageDir 且不抛;e2e 用含require('process/')的 CJS 依赖。
我知道 CONTRIBUTING 说目前不接受外部 PR,所以先把补丁放在讨论区。如果需要,我可以按你们格式提供最小补丁或只提供测试;也乐意在你们决定方案后配合调整。
—— dsh-mqtt-tools 作者
dsh-app-boot-fix.patch
Uh oh!
There was an error while loading. Please reload this page.
[Bug] profile 解析器两处缺陷导致所有带依赖的第三方插件无法加载
环境
0.2.0-rc.2(dsh --version)44.0.0,Windows 11 (10.0.26200),win-x64desktop(~/.dsh/profiles/desktop)dsh-minecraft@0.12.4(npm,dsh.bundle.patch类型)dsh plugin allow-version授予精确版本豁免问题概述
任何安装了自己依赖的第三方 profile 插件,在 import 自身依赖时都会崩溃。
插件本身没有问题 —— 同一份代码在纯 Node 下(
ELECTRON_RUN_AS_NODE=1)用import()直接加载并连接 Minecraft 服务器,完全正常。问题出在
0.2.0-rc.2新增的 profile 模块解析层。它注册了 ESM/CJS 两条 loader hook,把 profile 内的裸导入改道到内存路由,
而该路由在两处偏离了 Node 原生行为,且都触发了异常。
Bug 1:
resolve.paths()缺少?? []兜底位置
dsh/node_modules/@deepseek-ai/dsh-app-boot/lib/worker/profile-resolution-bootstrap.jsnativePackageDir()第 136 行附近routeScoped()第 311、364 行附近dsh/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js(同一份解析器的另一处副本)第 1249、1424、1477、2021、3265 行附近dsh/node_modules/@deepseek-ai/dsh-plugin-package-inventory-deepseek/lib/index.js第 47 行附近dsh/node_modules/@deepseek-ai/dsh-plugin-package-inventory-deepseek/lib/types/index.js第 49 行附近代码
报错
(V8 对
for...of报错时会省略调用参数,所以文案里看不到(parent)/(name)。我用同样的表达式形式在本机复现,拿到的文案逐字一致,确认崩溃点就是上面这行。)
佐证:作者自己在别处都做了兜底
也就是说
resolve.paths在该运行时下确实可能返回null,但 profile 解析器里的调用点漏掉了兜底。
Bug 2:
barePackageName()把"尾随斜杠的内置模块"误判为普通包位置
dsh/node_modules/@deepseek-ai/dsh-app-boot/lib/worker/profile-resolution-bootstrap.js第 53 行附近dsh/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js第 1166 行附近代码
问题
isBuiltin()require('process')truerequire('process/')falsereadable-stream@4.8.0的lib/internal/shims/process.js里写的是require('process/')(作者注释说明是为了绕开某些 polyfill,见 readable-stream #539)。由于
isBuiltin('process/')为false,barePackageName返回"process",该请求被送进路由;合成解析器又找不到
'process/':复现步骤
dsh-minecraft),依赖会被 pnpm 以 hoisted 方式装进
<profile>/node_modulesawait import('<它的依赖>')的工具建议修法
影响面
dependencies的第三方 profile 插件都会踩到这大概也是问题没被更早发现的原因
resolve.paths缺少兜底这一点,从仓库里既有?? []又有遗漏来看,可能值得整体排查一遍同类调用点
我已做的验证
在本地对
app.asar做了原地字节级补丁(未重新打包,因为该 asar 含 1497 个unpacked 文件,含 LibreOffice 与 koffi 原生模块),改动仅 12 处、文件大小不变、
node --check通过、全盘差异仅落在目标文件内。打完后插件完全正常:成功连接 Minecraft 1.20.4 服务器、读取世界状态、砍树、合成工作台与木镐、挖掘圆石。
附:如何从崩溃现场确认 Bug 1 的崩溃点
在
profile-resolution-bootstrap.js里用?? []兜底后,报错从createRequire.resolve.paths is not a function...变成
Cannot find module 'process/'—— 即 Bug 2。两者是独立缺陷。All reactions