Deno 运行时入门与架构解析:从安装、第一个 Web 服务到 V8 + Rust + Tokio 分层设计

📅 发布时间:2026/9/7 7:00:20
Deno 运行时入门与架构解析:从安装、第一个 Web 服务到 V8 + Rust + Tokio 分层设计 Deno 运行时入门与架构解析从安装、第一个 Web 服务到 V8 Rust Tokio 分层设计【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/denoDeno 是一个以安全默认值和良好开发者体验为核心的 JavaScript、TypeScript 与 WebAssembly 运行时构建在 V8、Rust 和 Tokio 之上。本文以仓库根目录 README 为主线覆盖安装、第一个Deno.serve服务、权限模型等实战内容并结合 doc/architecture.md 等仓库文档与源码解释deno run --allow-net server.ts背后逐层工作的实现原理。一、Deno 是什么README 对 Deno 的定义非常直接它是一个 JavaScript、TypeScript 和 WebAssembly 运行时/ˈdiːnoʊ/读作 “dee-no”特性上强调两点安全默认值secure defaults程序默认不能读取文件、访问网络、执行子进程必须显式通过--allow-*参数或运行时权限询问授予能力基于三大技术栈V8JavaScript 引擎、Rust系统语言、Tokio异步运行时。当前仓库的版本号为2.9.6记录在 cli/lib/version.txt。二、安装 DenoREADME 给出了五种官方安装途径覆盖 macOS、Linux 与 Windows。以下命令均可直接复制运行ShellMac、Linuxcurl -fsSL https://deno.land/install.sh | shPowerShellWindowsirm https://deno.land/install.ps1 | iexHomebrewMacbrew install denoChocolateyWindowschoco install denoWinGetWindowswinget install --idDenoLand.DenoScoopWindowsscoop install main/denoREADME 同时说明以上只是部分途径完整安装方式列表见 Deno 官方文档。若希望从源码构建安装则参考贡献指南.github/CONTRIBUTING.md 中的 “Building from source” 一节。构建所需的前提是理解本仓库的工作区结构——根 Cargo.toml 定义了一个包含cli、runtime、数十个ext/*与libs/*成员的 Cargo workspace这正是下文分层架构在工程上的对应物。三、你的第一个 Deno 程序用Deno.serve写一个 Web 服务README 指出Deno 最典型的用途是构建 Web 服务器。完整步骤如下创建文件server.tsDeno.serve((_req: Request) { return new Response(Hello, world!); });然后运行deno run --allow-net server.ts启动后本地 Web 服务默认监听http://localhost:8000访问该地址即可看到Hello, world!。3.1 为什么需要--allow-net这里的权限参数不是装饰而是 Deno 安全模型的入口--allow-net授予程序打开网络监听/连接的许可。不带该参数运行同一文件时Deno.serve会在权限检查处报错而不是默认放行。该 flag 的解析逻辑在 cli/args/flags.rs 中可以看到--allow-net支持精确到地址的白名单形式如--allow-net8000、--allow-net127.0.0.1:8000源码中会将其拼接为--allow-netallowlist参数。权限的实际执行发生在 Rust 侧的 op 边界。doc/architecture.md 明确指出“权限在 Rust 中、在 op 边界处检查绝不在 JavaScript 中检查”且“未授予的能力会让该 op 在执行任何工作之前就报错”。对应的权限模型代码位于 runtime/permissions/ 目录。3.2Deno.serve的默认端口 8000 从哪里来Deno.serve的实现位于 ext/http/00_serve.ts。其中函数入口serve(arg1, arg2)支持两种签名直接传 handler 函数或传{ handler, port, hostname, ... }选项对象见 ext/http/00_serve.tsREADME 中省略 port 时服务落在 8000 端口对应源码中的默认值port: options.port ?? 8000见 ext/http/00_serve.ts。也就是说README 示例中的http://localhost:8000并非文档随口写的地址而是Deno.serve内置的默认监听端口。四、架构总览README 背后的五层堆叠README 本身是面向用户的最小文档而 doc/architecture.md 给出了运行时本身的分层设计这是理解“deno run一条命令如何工作”的关键。原文档中的层叠结构如下自顶向下每层只依赖其下的层----------------------------------------------------------- | cli/ the deno binary: subcommands, tooling | ----------------------------------------------------------- | runtime/ deno_runtime: assembles the JS runtime | ----------------------------------------------------------- | ext/* extensions: native capabilities for JS | ----------------------------------------------------------- | libs/* deno_core supporting crates (V8 bridge) | ----------------------------------------------------------- | V8 Tokio JavaScript engine and async runtime | -----------------------------------------------------------4.1 CLI 层cli/用户直接触碰的一切denocrate 拥有 flag 解析、所有子命令run、test、fmt、lint、compile、bundle、install、publish等、包管理工具、LSP以及把模块解析与运行时连接起来的 module loader。关键入口文件文件职责cli/main.rs进程入口与命令路由cli/args/flags.rs完整的clapflag 与子命令定义新增 flag 或子命令从这里开始cli/tools/tool/每个子命令一个模块简单命令如 cli/tools/fmt.rs复杂命令如cli/tools/test/目录cli/module_loader.rs解析并加载模块把 resolver 与 module graph 桥接到运行时架构文档强调 CLI 层是“刻意沉重”的它引入 TypeScript 类型检查、npm 与 JSR 解析、lockfile、bundler 等能力而更低的层不允许反向依赖它。4.2 运行时层runtime/deno_runtimecrate这一层把deno_core加上一组精选的 extensions 组装成一个可工作的 JavaScript 运行时是希望嵌入“Deno 运行时”而非“Deno CLI”的外部项目使用的部分。关键文件runtime/worker.rs —— 构造主 workerisolate、op 集合、bootstrap 序列runtime/web_worker.rs —— Web Worker 变体runtime/permissions/ —— 权限模型门控所有敏感 opread、write、net、env、run、ffi、sys。4.3 扩展层ext/*平台能力的真正所在ext/下每个目录都是一个自包含的 extension一个 Rust crate定义ops可从 JS 调用的原生函数外加在其上暴露高层 API 的 JavaScript 模块。Web 平台能力ext/web、ext/fetch、ext/crypto、ext/webgpu等、系统访问ext/fs、ext/net、ext/process等、Deno 独有特性ext/kv、ext/cron、ext/ffi、ext/napi以及 Node 兼容层ext/node/ 承载大部分node:*内建模块另有ext/node_crypto、ext/node_sqlite都分布在这里。一个 extension 的典型形态是三步Rust 侧用#[op2]函数完成特权操作需要时附带权限检查00_*.js/01_*.js等编号 JS 模块构建公开 API通过Deno.core.ops调用这些 op——例如本文第三节的Deno.serve就位于 ext/http/00_serve.ts同层的原生 op 定义在 ext/http/lib.rs在 runtime/worker.rs以及 CLI 的 snapshot 构建中注册该 extension使其成为组装后运行时的一部分。架构文档还给出了一条明确的扩展守则新增原生功能时应在对应的ext/name/crate 中添加 op而不是伸手去改 runtime 或 CLI。4.4 核心层libs/*Rust 与 V8 之间的桥libs/保存deno_core及支撑 crate拥有 op 基础设施、module loader trait、snapshot 机制、JsRuntime 事件循环以及serde_v8序列化层。值得注意的成员libs/core/ ——deno_core本身JsRuntime、op 注册、module map、inspector 集成libs/ops/ —— 生成 Rust/V8 胶合代码的#[op2]过程宏libs/serde_v8/ —— Rust 类型与 V8 值之间接近零拷贝的序列化libs/resolver/、libs/npm/、libs/npm_installer/、libs/lockfile/、libs/config/ 等 —— CLI 组合使用的模块解析与包管理积木。这些 crate 刻意不含任何 CLI 关注点以便独立单测并被其他工具复用。4.5 横切概念Ops、Extensions、Workers、Resources、Permissions架构文档归纳了五个贯穿全栈的概念Ops是 JavaScript 触及原生代码的唯一途径。同步 op 立即返回异步 op 返回一个在未来事件循环上解决的 futureExtensions把 op 与其 JavaScript 打包在一起是运行时组合的基本单元Workers是隔离的 JS 执行上下文主 worker 与 Web Worker各自拥有独立的 V8 isolateResources是被管理的句柄打开的文件、socket、reader由deno_core跟踪以整型 id 跨 Rust/JS 边界传递Permissions在 Rust 侧的 op 边界强制执行未授予的能力会让 op 在任何工作发生前就报错。五、定位你的改动架构文档中的速查表doc/architecture.md 末尾给出了一张“我要做 X应该从哪开始”的表对理解各模块职责边界非常有用需求起始位置添加或修改 CLI flag / 子命令cli/args/flags.rs、cli/tools/给 JS 增加原生能力ext/name/op JS修改运行时的组装方式runtime/worker.rs触碰 Rust/V8 桥或 op 宏libs/core、libs/ops修改模块 / npm / JSR 解析libs/resolver、libs/npm、CLI更细粒度的目录地图见 doc/codebase-map.md各层的测试方式见 doc/testing.md此外 doc/ci.md 解释了 CI 工作流如何生成、以及纯文档改动仅触碰doc/的 PR为何只需跑lint任务。六、延伸阅读资源README 列出的官方资源与本文相互印证Deno Docs运行时、部署等的官方指南与参考文档Deno Standard Librarystd官方维护的通用工具库JSR面向现代 JavaScript/TypeScript 的开源包注册表其解析逻辑在仓库中对应cli/jsr.js与libs/resolver等模块贡献指南见 .github/CONTRIBUTING.md涵盖从源码构建的完整步骤。七、小结从仓库视角看README 中“安装 → 写server.ts→deno run --allow-net server.ts→ 访问localhost:8000”这条最短路径实际上穿过了整条技术栈cli/args/flags.rs解析出--allow-netcli/的 module loader 拉取并解析server.tsruntime/worker.rs组装 isolate 与 op 集合ext/http提供Deno.serve默认端口 8000libs/core与libs/ops承担 Rust/V8 桥接而 net 权限在 op 边界完成裁决。理解这条调用链也就理解了 Deno“安全默认 分层可复用”这两大设计目标的工程落地方式。【免费下载链接】denoA modern runtime for JavaScript and TypeScript.项目地址: https://gitcode.com/GitHub_Trending/de/deno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考