# Node.js
本章介绍现代 Node.js 工程环境的搭建:如何管理 Node 版本、如何选对包管理器,以及日常开发中真正高频的实用 CLI 工具。
选型建议(2026):新项目优先使用 Node.js 当前 LTS(v20 / v22),包管理器优先 pnpm,并用 Corepack 锁定团队一致的版本。下文会说明原因。
# 版本管理
同一台机器上往往需要在多个 Node 版本间切换(老项目锁定 v16,新项目用 v22)。不要手动安装/卸载,用版本管理器。
# fnm(推荐)
fnm (opens new window) 用 Rust 编写,跨平台、启动极快,是当前最推荐的选择。它能读取项目根目录的 .nvmrc / .node-version 自动切换版本。
# macOS / Linux
curl -fsSL https://fnm.vercel.app/install | bash
# Windows (推荐 winget)
winget install Schniz.fnm
# 安装并使用某个版本
fnm install 22
fnm use 22
fnm default 22
# 进入项目目录自动切换(需在 shell 配置中开启 --use-on-cd)
echo "22" > .node-version
# Volta(团队协作友好)
Volta (opens new window) 的特点是把工具版本写进 package.json,团队成员 clone 后会自动使用一致的 Node / 包管理器版本,无需任何手动切换。
volta install node@22
volta pin node@22 pnpm@9 # 版本会写入 package.json 的 "volta" 字段
# nvm
nvm (opens new window)(macOS / Linux)与 nvm-windows (opens new window)(Windows)是更早期、流行度很高的方案,许多老团队仍在使用。
nvm ls # 查看已安装版本
nvm install 22 # 安装指定版本
nvm use 22 # 切换版本
nvm alias default 22 # 设为默认
说明:早期文档里「手动下载 zip、改文件夹名、塞进 nvm 目录」的做法已不再推荐——现代版本管理器都能自动下载安装,国内网络慢时配置镜像即可(见下文 nrm / 镜像源)。
# 包管理器
# pnpm(推荐)
pnpm (opens new window) 通过全局内容寻址存储 + 硬链接,节省大量磁盘空间、安装更快,且默认严格的依赖隔离能避免「幽灵依赖」问题,是当前中大型项目和 Monorepo 的首选。
corepack enable # 推荐用 Corepack 启用(见下)
pnpm install
pnpm add react # 添加依赖
pnpm add -D vite # 添加开发依赖
pnpm dlx create-vite app # 类似 npx,临时执行包
# Corepack:锁定团队包管理器版本
Corepack (opens new window) 是 Node.js 内置的工具,配合 package.json 中的 packageManager 字段,确保所有人用同一个包管理器版本,杜绝「我这能装、你那报错」。
{
"packageManager": "pnpm@9.12.0"
}
corepack enable # 之后 pnpm / yarn 命令会自动匹配上面声明的版本
# 镜像源管理(nrm)
国内网络下切换 registry 能显著提速。nrm (opens new window) 可在多个源之间快速切换:
pnpm add -g nrm
nrm ls # 列出可用源
nrm use taobao # 切换到淘宝镜像(https://registry.npmmirror.com/)
nrm add <name> <url>
也可以直接配置(无需额外工具):
npm config set registry https://registry.npmmirror.com/
pnpm config set registry https://registry.npmmirror.com/
# 实用 CLI 工具
# npx / pnpm dlx —— 临时执行包
无需全局安装即可调用包,常用于脚手架与一次性脚本:
npx create-vite@latest my-app # 临时下载并执行,用完即弃
pnpm dlx degit user/repo my-app # pnpm 等价用法
npx jest # 直接调用本地 node_modules 中的二进制
# degit —— 只下载仓库内容(无 git 历史)
degit (opens new window) 用于快速拉取某个仓库(或其子目录)作为模板,不携带 .git 历史,比 git clone 更快更干净,是 dclone 一类工具的现代替代。
npx degit sveltejs/template my-app
npx degit user/repo/subdir my-app # 只拉取子目录
# 本地静态服务器
托管当前目录为静态资源服务,调试构建产物时非常方便:
npx serve . # 现代、零配置(推荐)
npx http-server . -p 8080
# tsx —— 直接运行 TS / ESM 脚本
tsx (opens new window) 基于 esbuild,可以免编译直接运行 TypeScript 与 ESM 脚本,写工具脚本时极其顺手(替代过去 ts-node 的大量场景)。
npx tsx script.ts
npx tsx watch script.ts # 文件变更自动重跑
# 命令行参数解析
写 CLI 工具时,用现代库解析参数与子命令:
pnpm add yargs # 功能完整,适合复杂 CLI
pnpm add commander
pnpm add cac # 轻量、API 简洁
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
const argv = yargs(hideBin(process.argv))
.option("port", { alias: "p", type: "number", default: 3000 })
.parse();
# cloc —— 代码量统计
快速统计某目录下各语言代码行数:
npx cloc --exclude-dir=node_modules,dist . --exclude-ext=json,html
# util.promisify —— callback 转 Promise
util.promisify 可将「最后一个参数是 callback、callback 首参为 error」的 Node API 包装为 Promise,便于在 async/await 中使用。注意:很多核心模块已直接提供 Promise 版(如 node:fs/promises),优先使用原生 Promise API。
import { promisify } from "node:util";
import { exec } from "node:child_process";
const execAsync = promisify(exec);
const { stdout } = await execAsync("pnpm i -g serve");
# 用 npm/pnpm link 调试本地模块
当你开发一个尚未发布的包,或想在本地改动并验证某个开源库(如 Vue / React)的源码时,link 能把全局软链接指向本地包,免去反复 publish。
# 在被调试的包目录
cd my-lib
pnpm link --global # 创建全局软链接(npm 用 npm link)
# 在使用该包的项目目录
pnpm link --global my-lib # 让本项目的依赖指向本地 my-lib
现代替代方案:在 Monorepo(pnpm workspace / Turborepo)中,包之间通过
workspace:*协议直接互相引用,通常无需手动 link,更适合多包协作的项目。