5月27日 20:12
Deno 如何处理模块导入和依赖管理?
核心答案
Deno 采用 URL 直接导入模块,没有 package.json 和 node_modules,依赖管理通过 Import Maps、deps.ts 文件或 deno.json 的 imports 字段集中管理,模块全局缓存于本地。
导入方式
Deno 支持 URL 导入、相对路径导入和 Import Maps 别名导入三种方式:
typescript// URL 直接导入(指定版本) import { serve } from "https://deno.land/std@0.208.0/http/server.ts"; // 相对路径导入(必须带扩展名) import { utils } from "./utils.ts"; // 通过 Import Maps 使用别名 import { Application } from "oak";
Import Maps 在 deno.json 中配置,可将 URL 映射为简短别名,是目前推荐的做法。
依赖管理方案
早期 Deno 推荐 deps.ts 模式——将所有远程依赖集中到一个文件重新导出,应用代码只从 deps.ts 导入。现在更推荐使用 deno.json 的 imports 字段,本质上是标准 Import Maps:
json{ "imports": { "oak": "jsr:@oak/oak@^12.6.1", "std/": "https://deno.land/std@0.208.0/" } }
JSR(jsr.io)是 Deno 推出的现代包注册表,支持 TypeScript 原生发布,配合 deno add jsr:@oak/oak 直接安装依赖。
与 Node.js 的关键区别
- 无 node_modules:模块下载后全局缓存,不污染项目目录
- 无 package.json:用 deno.json 或 deps.ts 替代
- 必须带扩展名:本地导入必须写
.ts,与浏览器行为一致 - 权限控制:导入远程模块需要
--allow-net,运行时受沙箱约束
版本锁定
deno.lock 文件记录依赖的精确版本和完整性哈希,类似 npm 的 package-lock.json。CI 环境中用 deno install --frozen 确保依赖不可变。
追问:URL 导入有什么安全隐患?如何规避?
URL 导入指向的代码可能被篡改(供应链攻击)。规避方式:始终锁定版本号、使用 lock 文件校验哈希、优先从 JSR 等可信注册表安装、配置 DENO_AUTH_TOKENS 访问私有仓库。