极简工具箱

免费在线工具 · 本地计算 · 无需上传

Node.js 环境管理:nvm、npm 与依赖装错版本

在 A 项目能跑、B 项目报 `SyntaxError`,切个 Node 版本就好了;`npm install` 后代码行为变了,因为 lock 文件没提交。

广告位(百度联盟)

一、用 nvm 管版本

nvm install 20
nvm use 20
nvm alias default 20
nvm ls

装 nvm 后,每个 shell 可以切换不同 Node 版本。项目里放一个 .nvmrc:

20.11.1

进入目录执行 nvm use 就自动切换(可配合 shell hook)。

为什么需要:不同项目依赖不同 Node 大版本,全局只能装一个,切版本比改代码省事。

二、package.json 的两类依赖

{
  "dependencies": { "express": "^4.19.2" },
  "devDependencies": { "typescript": "^5.4.0" },
  "engines": { "node": ">=18" }
}

装错位置很常见:把 typescript 放 dependencies,生产镜像就白装了几十 MB。

三、版本号前缀的含义

写法允许升级到
1.2.3精确版本
^1.2.31.x.x(不改主版本)
~1.2.31.2.x(不改次版本)
>=1.2.3任意更高版本

默认 npm install 会写 ^,所以协作时每个人装到的版本可能不同——这就是 lock 文件存在的意义。

四、lock 文件必须提交

package-lock.json(npm)、pnpm-lock.yaml、yarn.lock 锁定整棵依赖树的精确版本。提交后:

安装命令的区别:

npm install         # 可能更新 lock 文件
npm ci              # 严格按 lock 安装,不改 lock(CI 用这个)
pnpm install --frozen-lockfile

npm ci 会先删掉 node_modules 再装,速度更快、结果更确定,是 CI 的标准做法。

五、npm、pnpm、yarn 怎么选

特点
npm自带,生态最广,v7+ 也支持 workspace
pnpm硬链接共享存储,安装快、磁盘占用小,依赖隔离更严格
yarn早期以速度和 lock 著称,现在优势不明显

新项目推荐 pnpm:装得快、node_modules 体积小很多(同样的依赖,npm 可能 500MB,pnpm 只要 100MB 出头)。但要注意某些老工具对 pnpm 的符号链接结构不兼容。

不要在一个项目里混用多个包管理器,会生成两套 lock 文件,依赖树互相打架。

六、NODE_ENV 的作用

NODE_ENV=production npm start

很多库(Express、React)会根据它切换行为:开发模式保留调试信息、详细报错;生产模式做压缩和优化。忘记设置会导致:

在 Dockerfile 里显式 ENV NODE_ENV=production,不要依赖运行时环境。

七、node_modules 为什么那么大

应对:用 pnpm、生产安装加 --omit=dev、打包时用 bundler 把依赖打进产物。

八、常见报错

报错原因
Cannot find module依赖没装、路径错、大小写不一致(Linux 区分大小写)
ERR_OSSL_EVP_UNSUPPORTEDNode 17+ 与老 webpack 的 OpenSSL 兼容问题
EACCES全局安装权限问题,别用 sudo,改用 nvm
Unsupported engineNode 版本不满足 engines 要求
ERESOLVE unable to resolve dependency tree依赖冲突,用 --legacy-peer-deps 临时绕过并排查
listen EADDRINUSE端口被占用,换端口或结束进程

内存溢出(JavaScript heap out of memory)时设置 NODE_OPTIONS=--max-old-space-size=4096。

小结

用 nvm 管版本并写 .nvmrc;运行依赖和构建依赖分开;lock 文件必须提交,CI 用 npm ci;新项目试 pnpm;生产显式设 NODE_ENV=production。

本文相关工具(本地计算,无需上传)

更多使用教程