ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Deno入门到实战:核心特性、权限模型与本地文件API服务开发指南

Deno入门到实战:核心特性、权限模型与本地文件API服务开发指南 之前在业务迭代中切换到 Deno 做内部工具时最深的感受是Node.js 十余年积累下来的生态很丰富但工程体验里“权限边界模糊、依赖管理冗杂、TypeScript 配置成本高”这些问题一直没被根本性解决。Deno 的出现补上了这块短板尤其最近社区讨论热度回升连带 Deno Desktop 这类桌面端关键词也频繁出现在热搜里。本文就以 Deno 为对象从核心概念、环境搭建、特性拆解到一个可直接运行的本地文件 API 服务完整过一遍 Deno 的入门到落地流程最后再聊聊桌面应用方向的一些探索思路。1. Deno 是什么背景与核心概念1.1 从 Node.js 的缺憾说起Deno 是由 Node.js 的作者 Ryan Dahl 在 2018 年的一场演讲中正式对外公布的。这场演讲的标题叫 “10 Things I Regret About Node.js”翻译过来就是“我对 Node.js 的十个遗憾”。Ryan Dahl 认为 Node.js 在设计之初存在几个已经被历史证明的欠账模块系统复杂、npm 中心化仓库带来供应链管理压力、默认权限过大导致安全问题频发、包管理工具与运行时纠缠不清等等。于是他在 2020 年 5 月发布了 Deno 1.0。Deno 这个名字本来是 “de” 和 “no” 的组合暗示 “destroy Node”但官方更愿意把它解释为一种迭代和进化。它和 Node.js 一样基于 V8 引擎但内置了 Rust 编写的运行时层底层不再使用 npm 那样的中心化仓库作为唯一依赖来源而是直接支持通过 URL 引入模块。对普通开发者来说最直观的体验是装好 Deno 之后不需要再安装任何包管理器也不需要配置 Babel 或 ts-node写 TypeScript 直接运行即可。这背后其实是 Deno 把很多本该由开发者自行拼装的能力收拢成了运行时内置能力。1.2 Deno 与 Node.js 的区别对比很多新手容易把 Deno 理解成“另一个 Node.js”实际上两者在架构思路上已经有明显分化。下面这张对比表可以帮助你快速建立整体印象对比维度Node.jsDenoTypeScript 支持需要额外配置 ts-node 或编译流程原生内置开箱即用模块引入方式CommonJS / ESM依赖 node_modulesURL 导入、npm 包、JSR 包依赖安装npm install 生成 node_modules无需安装目录首次执行时缓存权限模型进程默认拥有全部系统权限默认无权限按需授予包管理npm registry 中心化去中心化 URL npm JSR工具链需要组合 eslint、prettier 等内置 fmt、lint、test、compile浏览器 API需要 polyfill原生支持 fetch、WebSocket 等这里最关键的一点是权限模型。Node.js 里一个fs.writeFile可以随意写磁盘文件任何一个第三方依赖只要被安装进 node_modules理论上就有能力访问你的文件系统、网络和环境变量。Deno 则把“安全”放到了第一位默认情况下脚本没有任何权限必须显式声明需要读取哪些目录、访问哪些网络地址、读写哪些环境变量。1.3 常见应用场景Deno 比较适合的场景大致可以分成三类第一类是后端 API 和中间层服务。Deno 内置的Deno.serve已经可以替代不少基于 Express 或 Koa 的轻量服务场景配合标准库提供的 HTTP 工具能快速写一个高可用的 REST 接口。第二类是命令行工具与自动化脚本。deno compile可以把 TypeScript 脚本编译成单个可执行文件在没有安装 Deno 的服务器上也能够运行非常适合给运维和测试同学分发工具。第三类是边缘计算和 Serverless。Deno 团队推出的 Deno Deploy 就是面向边缘节点的 JavaScript 运行时平台它在 V8 隔离、冷启动和全球部署上做了大量优化。不过需要注意的是国内访问 Deno Deploy 控制台等资源时网络条件可能会影响体验生产环境选型时要提前评估。2. 环境准备与版本说明2.1 安装 DenoDeno 的官方安装脚本托管在 deno.land 域名下。不同操作系统的安装方式如下。macOS 或 Linux 可以使用官方安装脚本curl -fsSL https://deno.land/install.sh | shWindows 用户可以在 PowerShell 里执行irm https://deno.land/install.ps1 | iex此外Windows 也支持通过包管理器安装winget install DenoLand.DenomacOS 用户还可以使用 Homebrewbrew install deno安装完成后脚本通常会提示你将 Deno 的可执行目录加入 PATH。macOS 和 Linux 默认安装位置是$HOME/.deno/binWindows 一般会写入当前用户目录下的.deno/bin。如果没有自动配置环境变量可以手动在 shell 配置文件中追加。2.2 验证安装与项目管理安装完成后打开终端执行deno --version如果输出类似于下面的信息说明安装成功deno 2.x.x (release, x86_64-apple-darwin) v8 13.x.x typescript 5.x.xdeno --version会同时显示 Deno、V8 和 TypeScript 的版本号这也能帮助你判断当前环境的 TypeScript 编译能力。Deno 从 1.0 到 2.x 经历了多个大版本迭代。1.x 时代主要补齐了权限、标准库和工具链2.x 时代最重要的变化是原生兼容 npm 包、支持 package.json 和 node_modules 目录这意味着大量的 Node.js 生态包可以直接在 Deno 中使用。本文示例以 Deno 2.x 环境为主但大部分 API 在 1.40 以上的版本也适用。如果你的环境版本较低建议升级到最新稳定版。2.3 IDE 支持在 VS Code 中搜索 Deno 扩展安装后需要在项目根目录创建.vscode/settings.json开启 Deno 支持{ deno.enable: true, deno.lint: true, deno.unstable: false }开启后VS Code 就能识别Deno.*全局命名空间和远端的 URL 导入并提供代码补全、类型提示和格式化支持。如果你使用 WebStorm 或 IntelliJ IDEA官方插件也已经提供类似能力。3. Deno 核心特性拆解3.1 原生 TypeScript 支持Deno 运行时内置了 TypeScript 编译器这意味着你不需要执行tsc编译步骤直接运行.ts文件即可。先来看一个最简单的例子。创建hello.ts// 文件路径hello.ts const greeting: string Hello, Deno!; console.log(greeting);然后执行deno run hello.ts输出Hello, Deno!Deno 在内部会自动把 TypeScript 编译成 JavaScript再交给 V8 执行。对开发者而言这个编译过程是透明的类型检查可以和运行分离。如果只想做类型检查而不执行代码可以使用deno check hello.ts注意Deno 对 TypeScript 配置是有限制的。因为官方希望不同项目的类型检查结果保持一致tsconfig.json中的部分选项会被忽略例如allowUnreachableCode、noUnusedLocals等。你需要使用 Deno 项目里的deno.json配置文件来声明允许的编译器选项后面会介绍。3.2 URL 导入与依赖管理Deno 最直观的差异是“模块不需要安装”。你可以直接通过 URL 导入一个远程模块import { copy } from jsr:std/fs/copy; await copy(./a.txt, ./b.txt); console.log(copy done);首次运行时Deno 会下载这个模块并缓存到本地。缓存目录在 Linux 和 macOS 默认为$HOME/.cache/denoWindows 默认为%LOCALAPPDATA%\deno也可以通过环境变量DENO_DIR修改。这种设计的好处是依赖来源清晰每个模块的版本直接在 URL 里体现坏处是如果依赖变更了锁文件管理就显得非常重要。Deno 会自动生成deno.lock锁文件它记录了所有远程模块的完整性哈希后续执行时如果发现内容变化会报错提示确保团队协作时依赖一致。3.3 安全权限模型权限模型是 Deno 区别于 Node.js 的核心设计。默认情况下以下代码在 Deno 中执行会直接拒绝// 文件路径read-flag.ts const content await Deno.readTextFile(/etc/hostname); console.log(content);运行deno run read-flag.ts会得到类似于下面的错误error: Uncaught PermissionDenied: Requires read access to /etc/hostname, run again with the --allow-read flag解决办法是显式授予读取权限deno run --allow-read/etc/hostname read-flag.tsDeno 支持的常用权限标志如下权限标志说明--allow-read允许读取文件系统可指定路径范围--allow-write允许写入文件系统可指定路径范围--allow-net允许网络访问可指定域名范围--allow-env允许读取环境变量可指定变量名范围--allow-run允许创建子进程--allow-ffi允许加载动态链接库--allow-all授予所有权限等于关闭安全限制建议在开发环境尽量使用最小化权限例如只授予当前项目目录的读写权限而不是直接使用--allow-all。权限粒度越小脚本被恶意依赖利用时造成的破坏就越有限。3.4 标准库、JSR 与 npm 兼容Deno 官方维护了一套标准库命名空间风格偏向 Web API代码风格也借鉴了 Go 标准库的设计。过去标准库发布在deno.land/std现在官方推荐的包仓库已经迁移到了 JSRjsr.io。JSR 是专门为 JavaScript 和 TypeScript 设计的现代包注册平台支持文档自动生成、语义化版本检查和跨运行时发布。在 Deno 2.x 中安装标准库模块可以这样做deno add std/assert这会自动在deno.json中生成 import 映射{ imports: { std/assert: jsr:std/assert^1.0.0 } }之后在代码里就可以直接导入import { assertEquals } from std/assert; assertEquals(1 1, 2);Deno 2.x 的另一个重要能力是兼容 npm 包。你可以这样使用 Express// 文件路径express-demo.ts import express from npm:express; const app express(); app.get(/, (_req, res) { res.send(Hello from Deno Express); }); app.listen(3000);运行deno run --allow-net --allow-read --allow-env express-demo.ts这个特性让团队可以把存量 Node.js 服务逐步迁移到 Deno而无需一次性重写所有依赖。3.5 deno.json 与任务管理deno.json是 Deno 项目的统一配置文件类似 Node.js 中的package.json加上tsconfig.json的合体。它负责管理任务、权限、依赖映射和编译选项。一个典型的配置如下{ name: demo-project, version: 0.1.0, tasks: { dev: deno run --allow-net --allow-read --watch main.ts, start: deno run --allow-net --allow-read main.ts, test: deno test --allow-read --allow-write --allow-env }, imports: { std/assert: jsr:std/assert } }配置好之后你不需要记住长串的权限参数直接执行deno task dev即可启动开发模式--watch会在文件变化时自动重启。这比在 package.json 里手动拼命令更清晰也能把权限控制在项目内统一管理。4. 完整实战用 Deno 开发本地文件 API 服务4.1 需求分析与项目结构这一节我们做一个非常贴近实际的小项目一个本地文件 API 服务。它能够读取指定目录下的文件名列表并通过 HTTP 接口返回 JSON 数据。这个场景很适合做日志查看工具、临时文件分享服务或内部管理后台的数据入口。功能需求拆解如下读取配置或环境变量指定的数据目录。提供GET /api/files接口返回目录下的文件列表。当目录不存在或读取失败时返回标准错误信息。支持单元测试验证核心函数。使用deno compile将服务打包成单个可执行文件。项目结构如下file-api/ ├── data/ │ ├── access.log │ └── app.log ├── file_service.ts ├── file_service_test.ts ├── main.ts └── deno.json4.2 初始化配置与依赖首先创建项目目录并进入mkdir file-api cd file-api创建deno.json声明任务和一个标准库依赖{ name: file-api, version: 0.1.0, tasks: { dev: deno run --allow-net --allow-read --allow-env --watch main.ts, start: deno run --allow-net --allow-read --allow-env main.ts, test: deno test --allow-read --allow-write --allow-env }, imports: { std/assert: jsr:std/assert } }然后执行下面的命令安装依赖并生成锁文件deno add std/assert该命令会自动把最新版本写入deno.json的应用配置中并生成deno.lock。4.3 编写核心文件服务代码文件服务模块负责读取目录并排序文件名这里把逻辑抽离出来方便测试复用。// 文件路径file_service.ts export interface FileEntry { name: string; isDirectory: boolean; } export async function listFileEntries(dir: string): PromiseFileEntry[] { const entries: FileEntry[] []; for await (const entry of Deno.readDir(dir)) { entries.push({ name: entry.name, isDirectory: entry.isDirectory, }); } // 目录排在前面同类型按名称排序 entries.sort((a, b) { if (a.isDirectory ! b.isDirectory) { return a.isDirectory ? -1 : 1; } return a.name.localeCompare(b.name); }); return entries; }Deno.readDir返回的是异步迭代器所以这里使用for await遍历。每一项都包含name、isDirectory、isFile、isSymlink等基础信息直接拿来做文件列表非常方便。4.4 编写 HTTP 接口接下来在main.ts中创建 HTTP 服务// 文件路径main.ts import { listFileEntries } from ./file_service.ts; const DATA_DIR Deno.env.get(DATA_DIR) || ./data; function jsonResponse(body: unknown, status 200): Response { return new Response(JSON.stringify(body), { status, headers: { Content-Type: application/json; charsetutf-8 }, }); } Deno.serve({ port: 8080 }, async (req) { const url new URL(req.url); if (url.pathname /api/files req.method GET) { try { const entries await listFileEntries(DATA_DIR); return jsonResponse({ code: 0, data: entries }); } catch (error) { return jsonResponse( { code: 1, message: (error as Error).message }, 500, ); } } return jsonResponse({ code: 404, message: Not Found }, 404); });代码里有几个值得注意的细节。Deno.env.get(DATA_DIR)用于读取环境变量默认值指向当前目录下的data目录。Deno.serve是 Deno 内置的高层 HTTP 服务 API它接收一个端口配置和一个请求处理函数返回的Response完全遵循浏览器中的 Web API 规范。这里不需要额外引入第三方 Web 框架但如果你需要中间件、路由分组、参数校验等高级能力官方推荐搭配oak或hono这类框架。4.5 运行验证先创建数据目录和测试文件mkdir data echo 2025-01-01 access log data/access.log echo 2025-01-01 app log data/app.log然后启动服务deno task start如果权限不足会报错说明deno.json里的任务里忘记加--allow-env。正确启动后在另一个终端执行curl http://localhost:8080/api/files预期返回{ code: 0, data: [ { name: access.log, isDirectory: false }, { name: app.log, isDirectory: false } ] }这里能看出权限模型的一个明显好处服务进程只拥有读取当前目录和访问网络的权限即使代码中有潜在漏洞攻击者也无法轻易写入文件或读取系统敏感信息。4.6 编写单元测试针对文件服务函数我们写一个单元测试。测试里使用Deno.makeTempDir创建临时目录这样不会污染真实数据目录。// 文件路径file_service_test.ts import { assertEquals } from std/assert; import { listFileEntries } from ./file_service.ts; Deno.test(listFileEntries 返回排序后的文件列表, async () { const tempDir await Deno.makeTempDir(); await Deno.writeTextFile(${tempDir}/b.log, b); await Deno.writeTextFile(${tempDir}/a.log, a); await Deno.mkdir(${tempDir}/sub); try { const entries await listFileEntries(tempDir); assertEquals(entries, [ { name: sub, isDirectory: true }, { name: a.log, isDirectory: false }, { name: b.log, isDirectory: false }, ]); } finally { await Deno.remove(tempDir, { recursive: true }); } });运行测试deno task testDeno 内置测试运行器会输出每个用例的通过情况。Deno.test是全局测试函数std/assert提供了assertEquals等断言函数整个过程不需要安装额外的测试框架。4.7 使用 deno compile 打包当服务在本地调试通过后可以把它编译成单个可执行文件。deno compile会把 V8、TypeScript 编译产物和你的业务代码打包在一起产物体积较大但胜在部署简单。deno compile --allow-net --allow-read --allow-env --output file-api server.ts如果你的入口文件是main.ts命令应写成deno compile --allow-net --allow-read --allow-env --output file-api main.ts编译完成后当前目录会生成file-api可执行文件Windows 下是file-api.exe。在目标机器上直接执行./file-api即使目标机器没有安装 Deno程序也可以正常运行。需要注意--allow-read在这里代表编译产物的默认权限范围如果业务要求更细粒度建议在启动时通过环境变量或配置再次收敛。5. 常见问题与排查思路5.1 权限拒绝 PermissionDenied这是新手遇到最多的报错。现象是运行脚本时提示Requires read access to ...、Requires write access to ...或Requires env access to ...。排查思路很简单看看脚本访问了哪些操作系统资源在启动命令中补上对应权限。如果是访问环境变量则加--allow-env如果是读取文件则加--allow-read如果是发起网络请求则加--allow-net。在真实项目中建议把权限参数固化到deno.json的tasks里而不是每次手敲这样团队成员无需记忆也能保证权限范围统一。5.2 远程依赖下载失败当你第一次执行包含远程导入的脚本时Deno 需要联网下载模块。如果公司网络策略严格或者访问海外 CDN 不稳定会看到下载超时错误。解决方案有三种检查网络与代理设置确保可以访问外网。使用deno cache 入口文件提前缓存依赖配合 CI 将缓存打入镜像。执行时添加--cached-only强制只使用本地缓存避免运行时意外下载。另外通过DENO_DIR环境变量可以指定缓存目录在容器化部署时建议把该目录挂载为持久化卷避免每次启动都重新下载。5.3 Node 项目导入受限在 Deno 2.x 中你可以使用npm:协议导入 npm 包或者直接将 package.json 中声明的依赖自动识别。但如果某个包依赖了 Node.js 原生模块且没有做兼容处理仍有运行失败的可能。遇到这种情况先确认包是否支持 ESM不支持的话需要找到合适的 ESM 包装版本。其次有些包需要读写 node_modules 目录运行时要加上--node-modules-dir选项并授予对应权限。这里的原则是能迁移到 Deno 原生生态就优先迁移确需兼容的场景再引入 npm 包。5.4 端口占用问题启动服务时如果提示Address already in use说明端口被占用。排查方式与其他语言一致lsof -i :8080找到占用进程并处理或者给服务换一个端口。在开发中建议把端口号放到环境变量中管理避免硬编码。5.5 类型检查报错有时候代码能运行但deno check报出类型错误。常见原因是引用了一个 Deno 默认禁用的 DOM 类型或者使用了与环境不匹配的 TypeScriptlib配置。在deno.json中可以通过compilerOptions指定lib{ compilerOptions: { lib: [dom, deno.ns] } }deno.ns表示 Deno 命名空间类型dom表示浏览器标准 API 类型。如果你只做后端服务通常保留deno.ns即可。6. 最佳实践与工程建议6.1 权限最小化Deno 的安全模型给出了很好的默认基线但很多人图省事直接使用--allow-all这等于放弃了 Deno 最重要的安全优势。建议为每个启动任务单独声明最小权限范围。例如文件读取接口只需要--allow-read./data就不要放开整个文件系统的写权限。当权限需求变得复杂时可以在启动入口处做一层配置收敛const dataDir Deno.env.get(DATA_DIR) || ./data; if (!dataDir.startsWith(./)) { throw new Error(DATA_DIR must be a relative path); }这样即使权限被放开业务代码也能通过路径校验限制访问范围。6.2 代码格式化与静态检查Deno 内置了两个工程化工具deno fmt和deno lint。它们能统一代码风格并检查常见问题。可以在deno.json中配置格式化和 lint 规则但更推荐的做法是直接使用默认规则避免团队内无休止的风格讨论。在 CI 流程中建议把以下命令作为必须通过的检查项deno fmt --check deno lint deno check main.ts deno test --allow-all这样既保证了代码风格统一也确保了基础测试覆盖。6.3 依赖锁定与升级deno.lock锁文件应该提交到版本库。它记录了依赖的完整性哈希能够防止模块被篡改或意外升级。升级依赖时使用deno update更新锁文件并提交而不是直接删掉锁文件。对于线上服务建议在构建镜像时执行一次deno cache --lockdeno.lock main.ts这一步会验证所有依赖都与锁文件一致任何一个不一致都会导致构建失败从源头避免“开发环境正常、生产环境报错”的问题。6.4 生产部署建议生产环境部署 Deno 服务有几种常见方式。最直接的是使用官方 Docker 镜像denoland/deno将编译产物或源码复制进容器。示例 Dockerfile 如下FROM denoland/deno:latest WORKDIR /app COPY . . RUN deno cache main.ts EXPOSE 8080 CMD [deno, run, --allow-net, --allow-read, --allow-env, main.ts]另一种方式是使用deno compile编译出单文件二进制再把二进制放进精简的运行时镜像中镜像体积通常更小启动速度也更快。两种方式各有优劣前者便于调试和热更新后者更便于分发和迁移。无论哪种方式都要遵守几条底线不在容器里以 root 运行服务不把敏感环境变量硬编码进镜像生产环境日志统一输出到 stdout由日志采集系统统一收集。6.5 日志与异常处理Deno 的运行时引擎原生支持console.log和console.error但生产环境更建议建立统一的结构化日志格式。可以把 JSON 作为日志输出格式方便日志平台解析。下面是一个简单的封装示例// 文件路径logger.ts export function log(level: string, message: string, data?: Recordstring, unknown) { console.log(JSON.stringify({ time: new Date().toISOString(), level, message, ...data, })); }在 HTTP 服务中建议为每个请求记录 method、path、status 和耗时这样排障时可以快速定位。7. Deno 在桌面应用方向的探索7.1 桌面端为什么关注 Deno“Deno Desktop” 并不是 Deno 官方推出的某个桌面框架而是社区对 Deno 桌面化方向的一系列探索。大家关注它主要是因为 Deno 的启动速度、安全模型和现代工具链让桌面工具的开发体验变得比 Electron Node 组合更简洁。在 Electron 方案里一个普通的桌面应用需要同时背负 Chromium 和 Node.js 两套运行时内存占用和安装包体积都很大。Deno 拥有更轻量的运行时加上权限模型天然适合做本地工具因此不少开发者尝试把 Deno 作为桌面应用的后端逻辑层。7.2 当前可行的几种方向目前比较务实的桌面化思路有三种。第一种是“本地 Web 服务 系统 WebView”。业务逻辑用 Deno 写一个本地 HTTP 服务UI 使用 React、Vue 或其他前端框架再通过系统自带的 WebView 加载本地页面。这样可以复用前端生态又能避开 Electron 的安装包体积问题但缺点是不同操作系统的 WebView 能力差异需要兼容。第二种是“命令行工具 终端 UI”。如果你的应用主要面向开发者或运维人员直接用 Deno 写 CLI 工具配合 ANSI 转义序列或者终端 UI 库一样能提供不错的交互体验。deno compile还可以把工具编译成单个可执行文件分发给同事时只需要一个文件。第三种是借助 Rust 桌面框架联动。Deno 的底层由 Rust 编写社区已经在探索将 Deno 嵌入到 Tauri 这套 Rust 桌面方案中前端继续使用 Web 技术后端逻辑由 Deno 承载。这类方案目前还处于演进阶段不同项目的成熟度差异较大选型时需要多做调研和原型验证。7.3 需要警惕的风险桌面应用比纯后端服务更依赖系统 API而 Deno 的 FFI 功能虽然强大但直接操作系统窗口和原生控件的能力仍不如 Node.js 生态成熟。如果你要做的应用依赖原生菜单、托盘图标、屏幕捕获等能力建议先确认目标平台上的 Deno FFI 或 WebView 能否覆盖这些需求。另一个风险是团队维护成本。Deno 桌面化方案目前没有统一的标准社区项目迭代速度很快项目 A 使用的封装方案可能三个月后就停止维护。因此选择桌面方向时核心业务逻辑尽量抽离成与 UI 无关的模块降低未来迁移框架的风险。8. 总结与学习路线8.1 本文核心收获通过上面的内容我们已经完整走了一遍 Deno 的入门到实战链路。你可以把以下几个要点作为这条链路里的关键节点Deno 是由 Node.js 作者发起的现代化运行时核心设计强调安全、TypeScript 原生支持和去中心化依赖。安装只需要一条命令deno --version可以快速验证环境。权限模型是 Deno 的立身之本日常开发要按需授予权限不要无脑--allow-all。deno.json统一管理任务、依赖映射和编译器选项是工程化的入口。Deno.serve足够完成轻量 HTTP API 服务复杂场景再引入 oak、hono 等框架。deno test、deno fmt、deno lint、deno compile组成了一套完整的开发到交付工具链。Deno Desktop 方向仍处于社区探索阶段适合轻量工具不适合强依赖原生系统能力的桌面应用。8.2 后续学习路线如果你是从 Node.js 转过来下一步可以重点研究 Deno 2.x 对 npm 包的兼容机制试着把一个 Express 小服务迁移到 Deno 上感受 node_modules 和权限模型的差异。如果你是一个 TypeScript 新手建议先熟悉 TypeScript 的基础语法再阅读 Deno 官方手册中关于权限和标准库的章节。再往后可以学习 Fresh 框架了解 Deno 全栈开发方式理解 Islands 架构是怎么在前端交互和后端渲染之间做取舍的。如果对边缘计算感兴趣Deno Deploy 是一个值得研究的部署平台。建议你动手把本文的 local file-api 项目跑起来然后尝试在它的基础上加一个新的接口比如支持按文件后缀过滤、支持从环境变量读取监听端口、或者把文件列表结果写入缓存。每一步改动都会让你对 Deno 的权限控制、模块组织和测试方式建立更直观的感知。
返回列表