本文档涵盖了 Bun 的模块系统和加载基础设施,包括模块解析、加载机制以及导入/导出处理。模块系统负责将导入说明符解析为文件路径,加载和解析模块,以及管理模块注册表。
有关执行加载模块的 JavaScript 运行时环境的信息,请参阅 ZigGlobalObject and Event Loop。有关模块加载过程中使用的文件系统操作的详细信息,请参阅 Build System and Infrastructure。
Bun 的模块系统由几个相互关联的组件组成,它们协同工作以解析、加载和执行 JavaScript 和 TypeScript 模块。该系统通过统一的解析和加载管道处理 ES6 导入和 CommonJS require。
来源: src/bun.js/bindings/ZigGlobalObject.h191-195 src/resolver/resolver.zig478-558 src/bun.js/bindings/ZigGlobalObject.cpp1-300
模块解析流程将导入说明符转换为绝对文件路径。Bun 实现了一个兼容 Node.js 的解析器,并增加了对 TypeScript 和现代 JavaScript 的额外支持。
模块解析流程
src/resolver/resolver.zig478-558 中的 Resolver 结构体通过几个关键方法管理解析流程
resolve() - 解析的主要入口点resolveWithoutRemapping() - 处理相对路径解析loadNodeModule() - 解析包导入loadAsFile() - 尝试通过扩展名加载为文件loadAsDirectory() - 尝试通过索引文件加载为目录来源: src/resolver/resolver.zig478-2500 src/resolver/package_json.zig48-300 src/resolver/resolve_path.zig1-200
一旦模块被解析为文件路径,加载过程就会获取、解析和实例化模块。这涉及到与 JavaScriptCore 的模块加载器系统的集成。
模块加载器方法
ZigGlobalObject 实现了一些关键的模块加载器方法,这些方法与 JavaScriptCore 进行接口
moduleLoaderImportModule() - 启动模块导入 src/bun.js/bindings/ZigGlobalObject.h191moduleLoaderResolve() - 解析导入说明符 src/bun.js/bindings/ZigGlobalObject.h192moduleLoaderFetch() - 获取模块源代码 src/bun.js/bindings/ZigGlobalObject.h193moduleLoaderCreateImportMetaProperties() - 创建 import.meta 对象 src/bun.js/bindings/ZigGlobalObject.h194moduleLoaderEvaluate() - 评估模块代码 src/bun.js/bindings/ZigGlobalObject.h195来源: src/bun.js/bindings/ZigGlobalObject.h191-195 src/bun.js/bindings/ZigGlobalObject.cpp990-1200 src/bun.js/bindings/headers.h117-121
Bun 维护 ES 模块和 CommonJS 模块的独立注册表,以确保适当的隔离和缓存行为。
注册表访问方法
全局对象通过惰性初始化提供对模块注册表的访问
esmRegistryMap() - ES 模块注册表 src/bun.js/bindings/ZigGlobalObject.h263requireMap() - CommonJS 模块缓存 src/bun.js/bindings/ZigGlobalObject.h262这些注册表实现为 JSMap 对象,它们存储模块说明符与其加载表示之间的关系。
来源: src/bun.js/bindings/ZigGlobalObject.h262-263 src/bun.js/bindings/ZigGlobalObject.cpp1500-1600
模块系统与 Bun 的文件系统抽象深度集成,以高效加载模块并处理开发场景下的文件监视。
| 组件 | 目的 | 关键方法 |
|---|---|---|
文件系统 (FileSystem) | 主要的 FS 接口 | init(), openForPath(), readFile() |
目录条目 (DirEntry) | 目录缓存 | addEntry(), lookup() |
目录信息 (DirInfo) | 目录元数据 | getEntries(), packageJSON() |
条目 (Entry) | 文件元数据 | getFileDescriptor(), stat() |
文件系统操作
模块加载需要进行一些文件系统操作
来源: src/fs.zig36-200 src/fs.zig133-300 src/resolver/resolver.zig2000-2500
Bun 在 CommonJS 和 ES 模块之间提供了无缝的互操作性,允许两种模块系统共存和交互。
模块类型检测
解析器通过多种机制来确定模块类型
.mjs, .cjs, .js)package.json type 字段package.json 中的 exports 条件来源: src/resolver/package_json.zig48-100 src/bun.js/bindings/ZigGlobalObject.cpp1800-2000 src/resolver/resolver.zig1000-1200
Bun 为 ES 模块实现了 import.meta 对象,提供了对模块元数据和 Bun 特定 API 的访问。
标准属性
import.meta.url - 模块 URLimport.meta.resolve - 解析函数Bun 扩展
import.meta.dir - 模块目录import.meta.file - 模块文件路径import.meta.path - 解析后的文件路径import.meta.main - 主模块检查中的 moduleLoaderCreateImportMetaProperties() 方法src/bun.js/bindings/ZigGlobalObject.h194 处理每个模块的这些属性的创建。
来源: src/bun.js/bindings/ZigGlobalObject.h194 src/bun.js/bindings/ZigGlobalObject.cpp2200-2400