Rolldown 插件上下文 `this.getModuleInfo()` 详解:模块信息生命周期与最佳实践
Rolldown 插件上下文this.getModuleInfo()详解模块信息生命周期与最佳实践【免费下载链接】rolldownFast Rust bundler for JavaScript/TypeScript with Rollup-compatible API.项目地址: https://gitcode.com/GitHub_Trending/ro/rolldown构建期插件通过this.getModuleInfo(moduleId)获取指定模块的实时信息是 Rolldown 中实现依赖分析、元信息注入、入口判断等高级插件能力的核心 API。本篇指南以 Rolldown 仓库中 plugin-context-getmoduleinfo.md 为骨架结合 TypeScript 插件层与 Rust 内核实现系统讲解ModuleInfo各字段在构建各阶段的可用性、可变性规则以及正确的使用时机帮助你在编写插件时避开信息尚未就绪的常见陷阱。一、API 概览签名、返回值与数据来源1. 签名与基本用法在 Rolldown 的插件类型定义plugin-context.ts中getModuleInfo的类型为export type GetModuleInfo (moduleId: string) ModuleInfo | null;它接收一个模块 id即解析后的绝对文件路径返回该模块的ModuleInfo对象如果找不到对应模块则返回null因此调用方需要做好空值判断。ModuleInfo接口定义在 module-info.ts核心字段包括字段类型含义idstring模块 id解析后的绝对路径codestring \| null模块源码external 模块或尚未解析时为nullexportsstring[]模块导出的所有变量名isEntryboolean是否为用户或插件定义的入口点importersstring[]静态导入该模块的所有模块 iddynamicImportersstring[]动态导入import()该模块的所有模块 idimportedIdsstring[]该模块静态导入的模块 id 列表dynamicallyImportedIdsstring[]该模块动态导入的模块 id 列表metaobject可自由读写的模块元信息继承自ModuleOptionsmoduleSideEffectsboolean \| no-treeshake \| null模块副作用标记inputFormates \| cjs \| unknown模块格式探测结果实验性字段注意ModuleInfo#ast在 Rolldown 中标注为hidden Not supported访问会抛出 unsupported 错误见 transform-module-info.ts。2. JS 层与 Rust 内核的对接getModuleInfo在 JS 层经由 plugin-context-data.ts 中的getModuleInfo(id, context)实现它先调用 N-API 绑定层context.getModuleInfo(id)拿到内核数据再用transformModuleInfo与插件层的ModuleOptionsmeta、moduleSideEffects合并后返回。绑定层实现位于 binding_plugin_context.rspub fn get_module_info(self, module_id: String) - OptionBindingModuleInfo { self.inner.get_module_info(module_id).map(BindingModuleInfo::new) }Rust 侧真实的数据结构定义在 module_info.rspub struct ModuleInfo { pub code: OptionArcStr, pub id: ModuleId, pub is_entry: bool, pub importers: FxIndexSetModuleId, pub dynamic_importers: FxIndexSetModuleId, pub imported_ids: FxIndexSetModuleId, pub dynamically_imported_ids: FxIndexSetModuleId, pub exports: VecCompactStr, pub input_format: ExportsKind, }可以看到 JS 层ModuleInfo的importers、importedIds等列表在内核中使用FxIndexSet存储保证去重的同时保持插入顺序先发现的导入者先出现。理解这条链路有助于判断getModuleInfo返回的信息是构建过程中不断累积、动态变化的不同 hook 阶段看到的内容可能不同这正是下文要展开的核心。二、字段可用性时间线哪些信息可能不准构建是分阶段推进的模块先被扫描/解析再被发现依赖、被其他模块引用。因此getModuleInfo返回的对象在不同时机呈现的信息完整度不同。原文档明确提示在buildEnd之前该对象只代表当前可获得的模块信息可能是不准确的。逐项拆解如下。1.id自始至终不变模块 id 一旦确定就不会变化任何 hook 阶段读取都可靠可作为模块的稳定标识。2.code与exports解析完成后可用code源码和exports导出列表只有在模块被解析之后才可用也就是在moduleParsedhook 中或在等待this.load返回之后即await this.load({ id })之后。到达这一时点后两者不再变化。注意code对外部external模块或尚未解析的模块为null见 module-info.ts 中code: string | null的注释。3.isEntry一旦为true便不再变化但存在迟到的入口isEntry一旦为true就不会再变化但文档特别强调模块可能在解析完成后才成为入口途径有两种插件调用this.emitFile发射新的入口 chunk插件在resolveIdhook 解析入口时通过this.load检查了某个潜在入口点。因此在transformhook 中不建议依赖isEntry做决策。它只保证在buildEnd之后不再变化。仓库中与之呼应的文档 plugin-hooks-resolveid-isentry.md 专门讨论了resolveId中的isEntry语义可作为延伸阅读。4.importers与dynamicImporters随发现不断追加这两个数组从空数组开始随着新的导入者被发现而不断加入新条目。这意味着在扫描早期一个模块的importers可能为空即使它最终会被多个模块引用。它们同样在buildEnd之后不再变化。5.importedIds与dynamicallyImportedIds依赖解析完成后可用当模块被解析且其依赖已被解析后这两个字段才可用即在moduleParsedhook 中或等待this.load且传入resolveDependencies: true之后。此时它们不再变化。注意this.load的resolveDependencies参数在 Rolldown 的插件上下文实现中plugin-context.ts注释表明 resolveDependencies always true at rolldown即 Rolldown 侧load总是解析依赖返回的ModuleInfo通常已包含完整的importedIds。6.meta与moduleSideEffects唯一可写字段与只读的id、code、importers等不同meta和moduleSideEffects是可写的修改会在buildEnd触发前生效被构建流程拾取。约束如下meta对象本身不要整体覆盖info.meta {...}但可以随时修改其属性info.meta.foo bar来为模块存储元信息这种存到meta而不是插件闭包状态的做法有一个关键优势在使用了缓存的情况下例如 CLI watch 模式meta会随缓存持久化并在重建时恢复而插件内部的闭包状态做不到。JS 层的可写机制在 plugin-context-data.ts 的proxyModuleInfo中实现通过Object.defineProperty为moduleSideEffects定义了 setter写入时调用updateModuleOption把moduleSideEffects、meta、invalidate: true回传到模块选项表meta的修改则通过Object.assign(existing.meta, option.meta)合并进现有对象见updateModuleOption。三、字段状态汇总表把上面的分析整理成一张速查表便于在编写插件时快速对照字段何时可用/可靠之后是否变化可写性id始终不变只读codemoduleParsed/await this.load之后不再变化只读exportsmoduleParsed/await this.load之后不再变化只读isEntry一旦为true不再变但入口可能迟到buildEnd后稳定只读importers从空数组开始随发现追加buildEnd后稳定只读dynamicImporters从空数组开始随发现追加buildEnd后稳定只读importedIdsmoduleParsed/await this.load(resolveDependencies)之后不再变化只读dynamicallyImportedIds同上不再变化只读meta始终可用buildEnd前修改生效可随缓存持久化可写改属性勿整体覆盖moduleSideEffects始终可用buildEnd前修改生效可写核心口诀依赖/源码类字段要看解析时机引用类字段要看扫描进度meta与moduleSideEffects才是插件可以主动写入的通道。四、实战示例在各 hook 中正确使用1. 在moduleParsed中读取已解析模块的信息moduleParsed是读取code、exports、importedIds的安全时机export default { name: inspect-module, moduleParsed(moduleInfo) { console.log(模块 ${moduleInfo.id} 已解析); console.log(导出: ${moduleInfo.exports.join(, )}); console.log(静态依赖: ${moduleInfo.importedIds.join(, )}); console.log(动态依赖: ${moduleInfo.dynamicallyImportedIds.join(, )}); }, };2. 在buildEnd中读取最终稳定的模块图buildEnd之后所有字段含importers、dynamicImporters、isEntry都稳定下来是做全局分析的推荐时机export default { name: report-importers, buildEnd() { for (const id of this.getModuleIds()) { const info this.getModuleInfo(id); if (info) { console.log(模块 ${id}:); console.log( 被静态导入: ${info.importers.length} 次); console.log( 被动态导入: ${info.dynamicImporters.length} 次); console.log( 是否为入口: ${info.isEntry}); } } }, };getModuleIds()同样来自插件上下文plugin-context.ts返回可迭代的模块 id 集合与getModuleInfo配合即可遍历整个模块图。3. 在resolveId/transform中谨慎对待isEntry由于模块可能在解析之后才通过emitFile或load成为入口transform阶段读取到的isEntry可能为false但最终该模块仍是入口。如果需要确定入口身份请在buildEnd之后再下结论或在load/transform中仅把它当作目前已知是入口的弱信号。4. 利用meta存储跨 hook、跨重建的元信息export default { name: meta-writer, transform(code, id) { const info this.getModuleInfo(id); if (info) { // 只修改属性不整体覆盖 meta 对象 info.meta.version 1; info.meta.analyzed true; } return code; }, };由于meta会随缓存持久化在 watch 模式下模块重建后之前写入的meta数据依然可用这是相对插件闭包变量的显著优势。5. 在load/transform中调整moduleSideEffectsexport default { name: side-effects, load(id) { if (id.endsWith(.css)) { const info this.getModuleInfo(id); if (info) info.moduleSideEffects true; } }, };moduleSideEffects的写入会通过proxyModuleInfo的 setter 回传到内核影响摇树tree-shaking对模块副作用的判定。五、与其他插件 API 的关系与延伸阅读this.load加载并解析指定模块返回对应的ModuleInfo可传入resolveDependencies以同时解析依赖使importedIds/dynamicallyImportedIds立即可用详见 plugin-context-load.mdthis.emitFile发射新的 chunk/asset其中type: chunk的入口会走完整的构建管线并可能使模块在解析后成为入口影响isEntry详见 plugin-context-emitfile.mdthis.getModuleIds遍历当前模块图中所有模块 id与getModuleInfo组合实现全图分析resolveId中的isEntry语义plugin-hooks-resolveid-isentry.md插件上下文其他能力addWatchFile、resolve、warn、error等集中在 plugin-context.ts。六、常见误区小结在transform中把isEntry false当作最终结论——入口可能迟到应在buildEnd后判定在早期 hook 中读取importers并认为它完整——它从空数组开始逐步追加在load返回前读取code/exports——需要等待await this.load(...)或moduleParsed整体覆盖info.meta——应只修改其属性否则可能丢失其他插件写入的元信息忽略返回值为null的情况——传入不存在的模块 id 时getModuleInfo返回null直接解构会报错。掌握getModuleInfo的信息时间线就能在 Rolldown 构建管线的正确时机读取到准确、完整的模块信息写出既健壮又高效的构建插件。【免费下载链接】rolldownFast Rust bundler for JavaScript/TypeScript with Rollup-compatible API.项目地址: https://gitcode.com/GitHub_Trending/ro/rolldown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

IMX6Q IPU示例程序:从解压到编译运行的完整指南

IMX6Q IPU示例程序:从解压到编译运行的完整指南

简介:这是一份面向嵌入式开发者的 I.MX6Q 处理器 IPU 接口示例代码包,适用于嵌入式 Linux 环境下的多媒体处理与显示开发,重点解决图像处理单元使用中的 YUV422 与 YUV420 互转、YUV422 到 RGB888 色彩空间转换,以及分辨率缩放等常…

2026/11/1 16:37:15 阅读更多 →
用Python落地机器学习课程笔记、作业与实验的工程化方案

用Python落地机器学习课程笔记、作业与实验的工程化方案

简介:重庆大学机器学习课程配套笔记与实验代码,以吴恩达Coursera经典课程为主线,内容分为监督学习、高级学习算法和其他类型学习三大模块,覆盖分类、回归、神经网络、决策树、模型评估与选择、推荐系统等核心主题,对新…

2026/11/1 16:26:30 阅读更多 →
KUKA Sim Pro 3.1:面向工程师的离线编程与数字孪生工作台

KUKA Sim Pro 3.1:面向工程师的离线编程与数字孪生工作台

1. 为什么Sim Pro 3.1不是“另一个仿真软件”,而是库卡工程师的数字孪生工作台你打开Sim Pro 3.1,界面清爽得像刚擦过的示教器屏幕——没有弹窗广告、没有强制登录、没有云同步提示。它不叫“KUKA Sim Pro Cloud Edition”,也不标榜“AI驱动的…

2026/10/30 22:22:03 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/1 0:24:43 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/1 10:36:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/1 10:36:51 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/1 1:06:58 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/1 10:35:11 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/1 9:35:41 阅读更多 →

日新闻

周新闻

月新闻