[Bug] ResolutionRouter 劫持 require.resolve 时丢失 .paths,导致插件加载期调用即崩 #7911
mdktelmdktel
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
环境
0.1.7-rc.2(npm,next标签)现象
任何 DSH profile 插件,只要在模块加载期(顶层语句,不是
apply()里)调用createRequire(...).resolve.paths(name),导入就会失败:而这个失败没有任何堆栈——启动日志里只有上面那两行,排查成本极高。
根因
@deepseek-ai/dsh-app-boot的ResolutionRouter会把Module._resolveFilename换成
wrappedFilename,对走 profile 层的请求改用ResolutionRouter.routeScoped自己解析。但劫持后的
require.resolve只是普通函数,没有把原生require.resolve.paths一起搬过去。于是routeScoped里这一行抛异常:实际错误:
注意
routeScoped是从wrappedFilename(Module._resolveFilename的替身)进来的,也就是说它把当前被劫持的 require 当成了原生 CJS require 来用。只有在模块加载期
触发解析的插件才会踩到;
apply()之后触发的解析路径不同,所以不是所有插件都炸。最小复现
请求是
"whale_craft",来自.../node_modules/whale_craft/index.js—— 即插件自己包的 baseUrl,命中的就是
routeScoped这条路径(同 profile 里
dsh-meme、dshmarket等不做这种调用的插件一切正常)。插件侧触发代码(whale_craft
src/core.mjs,模块顶层执行):影响
apply()从未执行,工具一个都没注册,全部dsh.bundle.patch声明的能力都不出现;用户只看到「装了没用」。
failed to import),几乎无法自助定位。建议修法
劫持
resolve时把.paths一并转发(保留原生行为):或在
routeScoped里改用不被劫持的解析入口(Module._resolveLookupPaths/import.meta.resolve等),别相信resolve.paths一定在。失败信息要能落地:
failed to import至少带上原始异常的 message(现在只有把插件包进 wrapper 才能抓到,见下)。这条对社区插件生态的价值可能比第 1 条还大。
附:抓错用的 wrapper(供参考)
把插件入口临时换成:
才拿到上面那段完整栈。直接看
manager.log只有一行failed to import。All reactions