本文档介绍了 Deno 如何从本地文件、远程 URL、npm 包等各种来源加载和解析模块。它涵盖了模块解析、加载策略以及依赖处理中的关键组件。
有关启动模块加载的 CLI 架构信息,请参阅 CLI 架构。
Deno 中的模块解析是指将模块说明符(如文件路径、URL 或裸说明符)转换为可获取和执行的完全限定 URL 的过程。此过程遵循基于模块上下文和类型的明确定义的规则集。
来源:cli/resolver.rs53-124 cli/graph_util.rs96-121
Deno 根据正在导入的模块类型采用多种解析策略。
本地文件导入是相对于导入模块或作为绝对路径进行解析的。
// Examples
import "./foo.ts"; // Relative to current file
import "/absolute/foo.ts"; // Absolute path from filesystem root
import "../utils/bar.ts"; // Relative to parent directory
可以使用完整的 URL 导入远程模块
import "https://deno.land/std/http/server.ts";
远程模块在下载后会被获取、缓存,并与本地模块的处理方式相同。
导入映射提供了一种将裸说明符重新映射到不同 URL 的方法。它们在 JSON 文件中定义,并通过 `--import-map` 标志引用,或在 Deno 配置文件中进行引用。
导入映射在解析过程中用于将裸说明符转换为实际 URL。
来源:cli/args/mod.rs542-550 cli/factory.rs187-232
为了兼容 Node.js,Deno 支持
// Example of Node.js style imports
import fs from "node:fs";
import express from "npm:express";
来源:cli/node.rs20-29 ext/node/ops/require.rs40-52
解析后,模块会通过一系列步骤进行加载
来源:cli/module_loader.rs145-252 runtime/worker.rs297-313
Deno 构建所有模块依赖关系的图以
模块图是通过从入口点模块开始,递归解析和分析所有导入来构建的。
执行前,Deno 会验证模块图以确保
来源:cli/graph_util.rs92-124 cli/module_loader.rs166-205
Deno 通过缓存模块来提高性能
缓存用于解析模块和存储编译后的输出。
来源:cli/cache.rs
Deno 通过 `npm:` 说明符前缀支持 npm 包。解析过程会
// Examples
import express from "npm:express";
import { parse } from "npm:yaml@2.2.1";
import chalk from "npm:chalk/index.js";
来源:cli/worker.rs380-425 cli/npm/mod.rs46-56
Deno 对 TypeScript 模块有特殊处理
来源:cli/module_loader.rs231-248
Deno 支持 JSR 注册表(JavaScript Registry)的包
// Example of JSR imports
import { assertEquals } from "jsr:@std/assert@0.218.0";
Deno 中的 Web Workers 拥有自己的模块加载上下文
来源:runtime/web_worker.rs412-594
Deno 支持各种模块类型
| 模块类型 | 文件扩展名 | 处理方式 |
|---|---|---|
| JavaScript | .js, .mjs | 直接执行 |
| TypeScript | .ts, .mts | 转译为 JS 后执行 |
| JSX/TSX | .jsx, .tsx | 转译为 JS 后执行 |
| JSON | .json | 解析为 ES 模块并公开 |
| WebAssembly | .wasm | 实例化为 WebAssembly.Module |
Deno 支持锁定文件(deno.lock)以确保确定性的模块解析
模块解析和加载错误会通过详细的错误消息进行处理
来源:cli/graph_util.rs126-237 cli/module_loader.rs254-266
Deno 的模块加载和解析系统通过结合基于浏览器的 ESM 加载和 Node.js 兼容性功能,提供了一种安全、高效的方式来处理各种来源的依赖项。Deno 创造了一种现代开发体验,同时在需要时保持向后兼容性。