强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Deno 入门教程 / 第 16 章:npm 兼容性

第 16 章:npm 兼容性

16.1 Deno 2.0 的 npm 兼容性

Deno 2.0 实现了对 npm 生态系统的高度兼容,可以无缝使用绝大多数 npm 包。

npm: 协议

// 直接使用 npm 包
import express from "npm:express@4.18";
import lodash from "npm:lodash-es@4.17";
import chalk from "npm:chalk@5";

// 使用子路径
import { map } from "npm:lodash-es@4.17/map";

package.json 支持

// package.json
{
  "name": "my-deno-app",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.18",
    "lodash-es": "^4.17"
  },
  "devDependencies": {
    "@types/express": "^4.17"
  }
}

Deno 会自动读取 package.json 并解析依赖。

node_modules 目录

# 使用 npm 安装(如果需要 node_modules)
deno install

# 不创建 node_modules(推荐方式)
# 直接使用 npm: 协议导入

16.2 Node.js API 兼容

Deno 2.0 提供了对 Node.js 核心 API 的广泛兼容:

兼容的 Node.js 模块

模块 支持状态 说明
node:fs ✅ 完整 文件系统操作
node:fs/promises ✅ 完整 异步文件操作
node:path ✅ 完整 路径处理
node:http ✅ 完整 HTTP 模块
node:https ✅ 完整 HTTPS 模块
node:crypto ✅ 完整 加密模块
node:os ✅ 完整 操作系统信息
node:url ✅ 完整 URL 处理
node:stream ✅ 完整 流操作
node:events ✅ 完整 事件系统
node:child_process ✅ 完整 子进程
node:worker_threads ✅ 完整 Worker 线程
node:buffer ✅ 完整 Buffer 操作
node:dns ✅ 完整 DNS 查询
node:net ✅ 完整 TCP 网络
node:tls ✅ 完整 TLS 加密
node:zlib ✅ 完整 压缩解压

使用 Node.js API

// 使用 node:fs
import fs from "node:fs";
import fsPromises from "node:fs/promises";

// 同步读取
const content = fs.readFileSync("./file.txt", "utf-8");

// 异步读取
const data = await fsPromises.readFile("./file.txt", "utf-8");

// 使用 node:path
import path from "node:path";
console.log(path.join("/home", "user", "file.txt"));
console.log(path.extname("file.txt"));

// 使用 node:os
import os from "node:os";
console.log("CPU 核心数:", os.cpus().length);
console.log("总内存:", os.totalmem());
console.log("可用内存:", os.freemem());

// 使用 node:crypto
import crypto from "node:crypto";
const hash = crypto.createHash("sha256").update("hello").digest("hex");
console.log(hash);

16.3 从 Node.js 迁移

迁移策略

策略 说明 适用场景
全新项目 从零开始用 Deno 新项目
渐进迁移 逐步替换模块 中型项目
混合运行 Deno + Node.js 共存 大型项目
编译迁移 一次性转换 小型项目

迁移清单

1. [ ] 检查依赖兼容性(npm 包在 Deno 中是否工作)
2. [ ] 替换 require() 为 import
3. [ ] 替换 __dirname 和 __filename
4. [ ] 替换 node: 开头的模块导入
5. [ ] 更新 package.json 或创建 deno.json
6. [ ] 运行 deno check 检查类型
7. [ ] 运行 deno test 确保测试通过
8. [ ] 更新构建和部署脚本

替换 __dirname

// Node.js 方式
const __dirname = path.dirname(new URL(import.meta.url).pathname);

// Deno 更简洁的方式
import { dirname } from "jsr:@std/path";
const __dirname = dirname(import.meta.url);

// 或者直接使用 URL
const currentDir = new URL(".", import.meta.url).pathname;

16.4 混合使用

deno.json 中配置 npm

{
  "nodeModulesDir": "auto",
  "tasks": {
    "dev": "deno run --watch --allow-all src/main.ts",
    "test": "deno test --allow-all"
  },
  "imports": {
    "express": "npm:express@^4.18",
    "lodash": "npm:lodash-es@^4.17"
  }
}

使用 npm workspaces

{
  "workspaces": [
    "packages/*"
  ]
}

16.5 常见迁移问题

问题 Node.js Deno 解决方案
require() require("module") import x from "module"
__dirname 全局变量 import.meta.url
process.env 全局对象 Deno.env.get()
Buffer 全局对象 import { Buffer } from "node:buffer"
console 全局对象 相同,直接使用
setTimeout 全局函数 相同,直接使用
global 全局对象 globalThis

16.6 本章小结

要点 说明
npm: 协议 直接导入 npm 包
Node.js API 高度兼容 node:* 模块
package.json 可选使用
迁移策略 渐进迁移最稳妥
兼容性 Deno 2.0 兼容绝大多数 npm 包

📖 扩展阅读


下一章第 17 章:Docker 容器化 → 学习 Docker 部署 Deno 应用。