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

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.jsDeno 解决方案
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 应用。