本文档涵盖了 Deno 的 NPM 包集成系统,该系统允许在 Deno 的运行时中运行 Node.js 包和 CommonJS 模块。这包括 require() 的实现、模块解析算法、CommonJS 分析以及缓存机制,使 Deno 能够无缝地与 NPM 生态系统协同工作。
有关 Node.js API polyfills 和内置模块实现的信息,请参阅 Node.js API Polyfills。有关兼容性测试框架,请参阅 兼容性测试。
Deno 中的 NPM 集成通过一个多层系统运行,该系统将 JavaScript 的 require() 调用桥接到基于 Rust 的模块解析和加载逻辑。
来源:ext/node/ops/require.rs1-777 cli/node.rs1-221 cli/cache/module_info.rs1-442
NPM 集成通过一套全面的操作来实现与 Node.js 兼容的模块解析,这些操作处理 require() 算法的各个方面。
| 操作 | 目的 | 核心功能 |
|---|---|---|
op_require_node_module_paths | 生成模块搜索路径 | 实现 Node.js 模块路径解析算法 |
op_require_resolve_lookup_paths | 确定相对导入的查找路径 | 处理 ./ 和 ../ 路径解析 |
op_require_resolve_exports | 解析 package.json 导出 | 支持现代 package.json exports 字段 |
op_require_package_imports_resolve | 处理 package.json imports | 解析 package.json imports 字段映射 |
op_require_resolve_deno_dir | 解析 npm 包文件夹 | 定位 Deno 的 npm 缓存目录中的包 |
来源:ext/node/ops/require.rs178-219 ext/node/ops/require.rs262-289 ext/node/ops/require.rs312-351 ext/node/ops/require.rs581-648
Deno 的 NPM 集成包含复杂的 CommonJS 分析,用于区分 CommonJS 和 ESM 模块,这对于正确处理 NPM 包至关重要。
来源:cli/node.rs84-167 cli/node.rs51-60 cli/node.rs170-220
CliCjsAnalysis 枚举代表了三种可能的分析结果
Esm: 模块被确定为 ECMAScript 模块EsmAnalysis(ModuleExportsAndReExports): ESM,包含详细的导入/导出分析Cjs(ModuleExportsAndReExports): CommonJS 模块,包含导出分析NPM 集成包含复杂的缓存机制,以提高重复加载和分析模块时的性能。
来源:cli/cache/module_info.rs48-74 cli/node.rs62-67
缓存系统使用多个维度来生成缓存键
| 缓存类型 | 关键组件 | 目的 |
|---|---|---|
| ModuleInfoCache | specifier + media_type + source_hash | 缓存已解析的模块信息 |
| NodeAnalysisCache | specifier + source_hash | 缓存 CJS/ESM 分析结果 |
| ParsedSourceCache | specifier | 缓存 AST 解析结果 |
来源:cli/cache/module_info.rs85-106 cli/node.rs91-96
NPM 集成通过在文件系统操作之前进行仔细的权限检查来遵守 Deno 的权限系统。
来源:ext/node/ops/require.rs40-51 ext/node/ops/worker_threads.rs18-29
以下操作包含权限验证
op_require_stat - 在 stat 操作前检查读取权限op_require_real_path - 在路径规范化之前验证权限op_require_read_file - 在访问文件内容之前确保读取权限op_require_try_self_parent_path - 检查父目录访问权限op_require_package_imports_resolve - 验证引用文件的权限来源: ext/node/ops/require.rs358-384 ext/node/ops/require.rs386-403 ext/node/ops/require.rs546-567 ext/node/ops/require.rs690-730
NPM 集成通过 RequireError 和 RequireErrorKind 类型提供了全面的错误处理,这些类型涵盖了模块解析和加载过程中的各种失败场景。
| 错误类型 | 描述 | JavaScript 类 |
|---|---|---|
UrlParse | 模块说明符中的 URL 无效 | 继承自 url::ParseError |
权限 | 文件访问权限被拒绝 | 继承自权限系统 |
PackageExportsResolve | Package.json exports 解析失败 | 一般错误 |
PackageJsonLoad | 加载 package.json 失败 | 一般错误 |
FilePathConversion | URL 转换为文件路径失败 | 一般错误 |
ReadModule | 文件读取操作失败 | 继承的错误 |