首页
/ Deno 代码库地图:逐目录导航与优先阅读的关键文件导读

Deno 代码库地图:逐目录导航与优先阅读的关键文件导读

2026-09-05 15:10:37作者:劳婵绚Shirley

本篇基于仓库内 codebase-map.md 编写,带你逐目录走读 Deno 的仓库布局:从 cli/ 的二进制入口、runtime/ 的运行时组装、ext/ 的原生能力扩展,到 libs/deno_core 基座与 tests/tools/ 的支撑体系,并给出"开始任何改动前应先读哪几个文件"的精确路径清单。读完后,你可以快速定位任何功能落在哪个 crate,知道按什么顺序建立心智模型。

这份地图在文档体系中的位置

Deno 仓库的 doc/ 目录 存放"面向人类和 AI Agent"的长文稳定文档:CLAUDE.md 是根目录下的短操作手册(怎么构建、哪条命令跑哪组测试、格式化与 lint 规则、git 工作流),而 doc/ 下的文档是它的长篇配套——讲架构的"为什么"和"东西都在哪里"。其中:

  • architecture.md 讲分层设计(CLI 层 → runtime 层 → 扩展层 → core 层),建议先读;
  • codebase-map.md 就是本篇的主体:逐目录地图 + 优先理解的文件清单;
  • testing.md 讲测试分类(spec、unit、unit_node、node compat、WPT)以及每组测试用什么命令跑。

分层概览(引自 architecture.md):cli/ 依赖 runtime/runtime/ 依赖 ext/*ext/* 依赖 libs/*,底层是 V8 + Tokio。每层只依赖其下的层,这保证了下层可以在 deno 二进制之外被复用和独立测试。

顶层目录一览

codebase-map.md 给出的顶层目录表如下,本篇后续各节逐一展开:

目录 内容
cli/ deno 二进制:子命令、工具链、LSP、模块加载器
runtime/ deno_runtime crate:组装 JS 运行时与 workers
ext/ 扩展(extensions)——暴露给 JavaScript 的原生能力
libs/ deno_core 及配套的解析/打包 crates
tests/ 全部测试套件(详见 testing.md
tools/ 开发脚本:format.jslint.js、CI 辅助、发布
third_party/ Vendored 依赖与测试夹具(文档中列出)
coverage/ 覆盖率输出目录(文档中列出)

需要说明的是:在当前仓库快照的根目录下,third_party/coverage/ 两个目录并不存在(前者通常是子模块内容,后者是覆盖率运行产物),实际可见的顶层目录为 cli/runtime/ext/libs/tests/tools/ 以及根级文件 CLAUDE.mdCargo.tomlx 等。阅读地图时以此为准。

开始之前先读这 5 个文件

文档明确列出了理解全库前最值得一读的文件,结合源码核实如下:

  1. cli/main.rs —— 入口与命令路由。 实际内容极简,只有一行 deno::main();文件头注释解释了为何同时存在 lib.rsmain.rs:为了能在 CI 中不构建二进制就跑测试。真正的路由逻辑在 cli/lib.rsdeno::main() 中。
  2. cli/args/flags.rs —— 全部 CLI 标志与子命令定义。 该文件超过千行,基于 clap(并经 libs/cli_parserdeno_cli_parser 抽象),deno 支持的每一个 flag、每个子命令都在这里定义——新增 flag 或子命令从这里开始。
  3. runtime/worker.rs —— worker/运行时如何初始化。 它构造主 worker:V8 isolate、op 集合以及 bootstrap 序列,是"扩展如何被组装进运行时"的注册中心。
  4. runtime/permissions/ —— 门控所有敏感 op 的权限系统。 目录内含 broker.rsprompter.rs 等模块;权限在 Rust 的 op 边界检查,绝不在 JavaScript 层检查。
  5. cli/module_loader.rs —— 模块加载与解析。 配合 cli/graph_util.rs 完成模块图的构建与加载,把 resolver、模块图与运行时桥接起来。

cli/ 内部:用户直接触碰的一切

cli/ 是"用户可见的一切":flag 解析、子命令、包管理、LSP、模块加载器都归它管。文档给出的内部结构:

  • cli/args/ —— flag 解析(flags.rs)与解析后的配置。该目录还有 flags_net.rs(网络相关 flag)与 mod.rs
  • cli/tools/ —— 一个子命令一个模块。文档举了两类范例:简单命令看 cli/tools/fmt.rs;复杂命令看 cli/tools/test/ 目录。其他值得注意的工具包括 compile.rs(独立二进制编译)、bundle/(打包)、lint/pm/(包管理)、installer/jupyter/publish/repl/serve.rs
  • cli/lsp/ —— 语言服务器(language server),含 analysis.rscompletions.rssemantic_tokens.rs 等完整 LSP 能力模块。
  • cli/module_loader.rscli/graph_util.rs —— 模块图构建与加载,连接解析器与运行时。

architecture.md 特别强调:CLI 层被有意做得"很重"——它拉入了 TypeScript 类型检查、npm 与 JSR 解析、lockfile 和打包器;下层 crate 绝不能反向依赖它

ext/ 内部:扩展是原生能力的单元

每个 ext/<name>/ 子目录就是一个自包含的扩展:一个 Rust crate 定义 ops(JS 可调用的原生函数),再配一组 JavaScript 在其上构建高层 API。当前快照下 ext/ 实际包含:webfetchurlcryptoconsolewebidlwebsocketwebgpucanvasimagebroadcast_channelwebstoragefsnetioosprocesssignalstlskvcroncacheffinapibundletelemetrynodenode_cryptonode_sqlite 等。文档按用途分组为:

  • Web 平台webfetchurlcryptoconsolewebidlwebsocketwebgpucanvasimagebroadcast_channelwebstorage
  • 系统访问fsnetioosprocesssignalstls
  • Deno 专有 APIkvcroncacheffinapibundletelemetry
  • Node 兼容node(绝大多数 node:* 内建模块)、node_cryptonode_sqlite

一个扩展的惯用布局(可用真实源码印证):

  1. Rust 侧用 #[op2] 宏定义特权操作。例如 ext/fs/ops.rs 中大量 #[op2] 标注的文件系统 op;#[op2] 宏本体由 libs/ops 提供,它自动生成 Rust/V8 之间的胶水代码。
  2. JS 侧用数字前缀命名的模块文件(00_*.js01_*.js、…),前缀控制加载顺序,通过 Deno.core.ops 调用 op 构建公共 API。例如 ext/fs/30_fs.jsext/web/00_url.jsext/net/01_net.js
  3. runtime/worker.rs(以及 CLI 的 snapshot)中注册该扩展,使其成为组装后运行时的一部分。

文档给出的实操规则很直接:添加原生功能时,把 op 加到对应 ext/<name>/ crate 中,不要越过扩展层去动 runtime 或 CLI。

libs/ 内部:deno_core 基座与解析/打包积木

libs/ 存放 deno_core 以及从原独立 deno_core 仓库合并进来的配套 crate,是 Rust 与 V8 之间的桥:op 基础设施、模块加载 trait、快照机制、JsRuntime 事件循环、serde_v8 序列化层。文档分三组:

这些 crate 被刻意保持"无 CLI 关注点",以便隔离单元测试、被其他工具复用。

tests/ 内部:五套测试体系各管一层

codebase-map.md 对测试目录的划分(每条均可在仓库中验证存在):

  • tests/specs/ —— 主力集成测试:一个目录一个测试,内含 __test__.jsonc 描述若干步骤,每个步骤是一次 deno 调用并断言其输出;期望值语言支持 [WILDCARD][WILDLINE][UNORDERED_START]/[UNORDERED_END][# 注释] 等匹配语法,schema 即 tests/specs/schema.json
  • tests/unit/ —— 运行时 API 的 JS/TS 单元测试(*_test.ts 命名),需在 cargo test harness 下运行,不能直接用 deno test 跑。
  • tests/unit_node/ —— 面向 node:* 兼容层的单元测试。
  • tests/node_compat/ —— Node.js 官方测试套件在 Deno 上运行,度量兼容度;运行集合由 tests/node_compat/config.jsonc 控制。
  • tests/wpt/ —— Web Platform Tests,校验 Web 标准符合性。
  • tests/testdata/ —— 跨套件共享的测试夹具。

各套件对应命令详见 testing.md./x test-spec./x test-unitcargo test unit_node:: 等)。

tools/ 内部:开发脚本与根目录 x 助手

tools/ 全部用 Deno 自身运行,文档列出的核心脚本:

仓库根目录的 x 脚本包装常用构建/测试命令,它实际转发到 tools/x.ts;运行 ./x --help 可查看完整命令列表(test-spectest-unittest-compattest-napi 等)。

修改入口速查:想改什么,去哪里开始

codebase-map.md 的目录地图与 architecture.md 的"Where to make a change" 表合并,得到一张动手速查表:

你想…… 起点
增改 CLI flag / 子命令 cli/args/flags.rscli/tools/
给 JS 添加原生能力 ext/<name>/(op + JS)
修改运行时组装方式 runtime/worker.rs
触碰 Rust/V8 桥或 op 宏 libs/corelibs/ops
改模块/npm/JSR 解析 libs/resolverlibs/npm、CLI

对应的工作流在 CLAUDE.md 中有完整描述:新增子命令要动 flags.rs + cli/tools/<cmd>.rs + 在 cli/main.rs/lib.rs 路由处接线,并在 tests/specs/<cmd>/ 补 spec 测试;新增扩展则要在 ext/<name>/ 写 op 与 JS 后更新 runtime/worker.rs 的注册。

小结

Deno 的仓库布局是"分层地图":cli/ 管用户界面与命令,runtime/ 管运行时组装与权限门控,ext/ 是"op + 数字前缀 JS 文件"的标准扩展单元,libs/ 提供可复用的 deno_core 与解析/打包积木,tests/tools/ 分别保障五层测试体系与开发效率。按"5 个优先文件"(cli/main.rscli/args/flags.rsruntime/worker.rsruntime/permissions/cli/module_loader.rs)建立第一遍心智模型,再用本地图按需下钻,是阅读或贡献这份代码库最省时的路径。

登录后查看全文
热门项目推荐
相关项目推荐