1、nodejs 包管理工具
- fnm / nvm:Node 运行时版本管理器 → 管理
node/npm本身版本 - npm / pnpm / yarn / cnpm:包管理器 → 管理项目
package.json的 JS 依赖包 - npx / pnpm dlx / yarn dlx:临时执行包的工具
| 工具 | 类型 | 锁文件 | 幽灵依赖 | 核心特性 | 推荐场景 |
|---|---|---|---|---|---|
| npm | 官方包管理器 | package-lock.json | ✅存在 | Node 自带,兼容性最好 | 老项目维护,简单小项目 |
| yarn(v1) | 包管理器 | yarn.lock | ✅存在 | 早期并行下载 | 存量老项目,新项目不推荐 |
| yarn(berry) | 包管理器 | yarn.lock | ❌无 | PnP 无 node_modules,monorepo 强 | 熟悉 Yarn 生态的团队 |
| pnpm | 现代包管理器 | pnpm-lock.yaml | ❌无 | 硬链接存储,速度快省磁盘,workspace 强 | ✅新项目、monorepo 首选 |
| cnpm | npm 封装工具 | cnpm-lock.yaml | ✅存在 | npm + 淘宝镜像 | ❌新项目尽量不要用 |
| npx | 包执行器 | - | - | 临时执行包,无需全局安装 | 脚手架、一次性工具 |
关键注意事项:
- 不要混用包管理器:一个项目只能用 npm / yarn / pnpm 其中一种,lock 文件互不兼容,混用会出现依赖错乱
- cnpm ≠ pnpm:cnpm 只是 npm 换源,pnpm 是完全独立实现
- npx 不能用来安装包,只是运行;
pnpm dlx/yarn dlx等价 npx - 国内加速:优先改 registry,不要依赖 cnpm
- 是由有幽灵依赖:npm、yarn classic 有;pnpm、yarn berry 默认没有
npm
官网:https://www.npmjs.com/
教程:https://www.runoob.com/nodejs/nodejs-npm.html
常用命令 npm CLI:https://docs.npmjs.com/cli/v9npm 官方文档:https://docs.npmjs.com/cli/v6/commands/npm-install/
npm(Node Package Manager),Node.js官方原生包管理器,安装 Node 自带,最早的 Node 包管理工具。npm 之于 Node.js 就像 pip 之于 Python。npm 原理
- npm v2:嵌套 node_modules,包重复拷贝,容易目录过深。
- npm v3+:扁平依赖,依赖尽量提升到根 node_modules;冲突时才嵌套。
- 存在幽灵依赖:代码可以引入
package.json没声明的包(来自间接依赖)。 - 锁文件:
package-lock.json,锁定依赖版本,保证环境一致性。
优缺点
- 优点:自带、生态完全兼容、官方维护
- 缺点:安装速度一般,磁盘占用高,幽灵依赖问题
常用命令
npm -v npm install # 安装 package.json 全部依赖 npm install axios # 生产依赖 npm install -D vite # devDependencies 开发依赖 npm uninstall axios npm run dev # 执行 scripts npm config set registry https://registry.npmmirror.com # 设置国内镜像npx
npx不是包管理器,而是 npm 自带的包执行器(npm ≥5.2),不负责安装包到项目 / 全局,核心逻辑:
- 优先执行项目本地
node_modules/.bin的命令,执行本地命令安装工具 - 本地不存在 → 临时下载包到缓存、执行,执行完自动清理
- 可以指定包版本,避免全局包版本污染
# 示例:临时拉取 create-vite 创建项目,不用全局安装 create-vite npx create-vite@latest my-vue-project # 执行项目本地eslint npx eslint src优缺点
- 优点:一次性脚手架、临时工具,避免全局包污染
- 缺点:每次远程拉包会有网络开销;可以指定版本
npx 重要参数
# --no-install:禁止自动下载。本地找不到包直接报错(安全模式) npx --no-install eslint src # --package:手动指定依赖包(当命令名和包名不一致时) npx --package=typescript tsc --version快速选型记忆
- 一次性脚手架 →
npx xxx/pnpm dlx xxx - 调用项目本地工具 →
npx xxx - 测试某个包不同版本 →
npx package@version - 不信任第三方包 → 加上
--no-install
场景 1:运行脚手架(最常用)
一次性创建项目,不需要全局安装脚手架工具,用完不留垃圾。
# 创建 vite 项目 npx create-vite@latest my-vue-app # 创建 React 项目 npx create-react-app my-react-app # 创建 next 项目 npx create-next-app@latest my-next-app # 创建 TS 项目模板 npx create-typescript-app优势:不用npm install -g create-vite,避免全局脚手架版本老旧、版本冲突。
场景 2:执行项目本地已安装的工具。项目依赖已经装在node_modules,但你不想在package.json#scripts写脚本,直接手动调用。
# 执行本地 eslint 检查文件 npx eslint src/**/*.ts # 本地 prettier 格式化 npx prettier --write src # 本地 typescript 类型检查 npx tsc --noEmit原理:npm run xxx本质内部也是去node_modules/.bin找命令;npx可以临时手动调用。
场景 3:临时运行某个工具,测试不同版本。在不改动全局、不改动项目依赖的前提下,跑任意版本工具。
# 临时用 node 18 执行一段代码(@指定版本) npx node@18 -e "console.log('hello')" # 临时看指定版本 vue-cli 帮助 npx @vue/cli@5 --help # 临时打开一个静态文件服务器 npx serve@latest非常适合:快速验证某个包新版本行为,不想安装到全局。
场景 4:执行 npm 作用域包(@xxx/yyy)。作用域包(组织包)直接用 npx 调用:
npx @antfu/ni npx @nestjs/cli new my-nest场景 5:一次性小工具,临时执行。各种轻量 cli 工具,临时跑一次:
# 打开 JSON 格式化工具 npx json-server db.json # 图片压缩工具 npx squoosh-cli # 查看包大小 npx package-size react场景 6:绕过全局包冲突(非常实用)。假设你电脑全局装了create-vite@4,但现在想临时用 create-vite@5创建项目,会覆盖你全局的 create-vite,用完就丢。
# 强制拉取 v5,不影响全局版本 npx create-vite@5 my-projectpnpm (推荐)
官网:https://pnpm.io/zh/
Docs:https://pnpm.io/zh/motivation
安装:https://pnpm.io/zh/installation
pnpm 全称 performant npm,意思为 高性能的 npm。pnpm 由 npm/yarn 衍生而来,解决了 npm / yarn 内部潜在的 bug,极大的优化了性能,扩展了使用场景。被誉为 最先进的包管理工具,是当前社区首选,国内的 Vue / Vite 团队很多都切换到 pnpm。pnpm 核心是全局内容寻址存储 + 硬链接 / 符号链接。pnpm 原理:所有包版本全局只存一份(store 目录),多个项目复用同一个包;项目 node_modules 通过硬链接指向全局 store。
- 严格依赖,杜绝幽灵依赖,只能导入 package.json 显式声明的包
- 安装速度最快,磁盘占用最低
- 原生强力 monorepo workspace,现在大厂 monorepo 首选
- 锁文件:pnpm 的锁文件是 pnpm-lock.yaml,不能和 package-lock.json / yarn.lock 混用,重点:一个项目只能选一种包管理器。
- 优缺点:优点:速度快、省磁盘、无幽灵依赖、workspace 好用、兼容 npm 包。缺点:极个别工具对 pnpm 的 node_modules 链接模式有兼容问题
pnpm 安装包的时候,同样有本地(项目级)和全局之分,但是底层实现和 npm 差异很大
- npm / yarn:全局包安装到 Node 安装目录下的
node_modules - pnpm 全局存储目录是
store,所有包版本全局只存一份物理文件,按文件哈希存储。 查看 store 路径:pnpm store path
macOS/Linux:~/.local/share/pnpm/store
Windows:%LOCALAPPDATA%\pnpm\store
当多个项目安装同一个版本的 react@18,磁盘只保存一份。项目 node_modules 通过硬链接指向 store 的真实文件,硬链接几乎不占用额外磁盘空间。
硬链接:文件副本指针,指向磁盘真实数据;多个硬链接共享同一份文件。
符号链接(软链接):类似快捷方式,指向路径;用于 node_modules 根目录暴露直接依赖。
node_modules 目录结构(关键,解决幽灵依赖)
node_modules ├── .pnpm/ # 虚拟存储,存放所有包(直接依赖+间接依赖)硬链接 │ ├── react@18.2.0 │ └── lodash@4.17.21 ├── react -> .pnpm/react@18.2.0/node_modules/react # 符号链接(软链接)- 根目录 node_modules只有你 package.json 显式声明的直接依赖(符号链接)
- 间接依赖全部放在
.pnpm内部,不会提升到顶层 - 幽灵依赖消失:代码不能
import没有写在 package.json 的间接依赖,不会出现 npm/yarn classic 那种隐性依赖、升级突然炸掉的问题。npm/yarn classic 扁平化会提升依赖,可以偷偷引入没声明的子依赖,就是幽灵依赖。
| 操作 | npm | pnpm |
|---|---|---|
| 本地安装 | npm install axios | pnpm add axios |
| 本地开发依赖 | npm install -D typescript | pnpm add -D typescript |
| 全局安装 | npm install -g xxx | pnpm add -g xxx |
| 全局包列表 | npm list -g --depth=0 | pnpm list -g --depth 0 |
| 执行本地 CLI | npx xxx | pnpm exec xxx |
| 分类 | 安装命令 | 写入 package.json | 生效范围 | 生产安装 (--prod) 是否保留 | 典型例子 |
|---|---|---|---|---|---|
| 本地生产依赖 | pnpm add xxx | ✅ dependencies | 当前项目 | ✅ 安装 | vue, react, axios |
| 本地开发依赖(开发包) | pnpm add -D xxx | ✅ devDependencies | 当前项目 | ❌ 跳过 | vite, eslint, ts |
| 全局包 | pnpm add -g xxx | ❌ 不写入 | 整台机器所有目录 | —(不属于项目) | @nestjs/cli |
本地包(生产 + 开发)
- 绑定项目。你把项目丢给别人,
package.json记录了所有本地包,执行 install 就能完整复现环境。开发包是本地包的一种。
生产依赖:项目跑起来必须有。
开发依赖:只是帮你构建、检查代码,打包完就没用了 - 全局包。绑定电脑。只在你本机生效,不跟项目走。全局包主要是提供终端命令,不能直接在项目代码里 import(代码 import 优先读取项目 node_modules,不会读取全局包)。
最佳实践规则
- 业务代码里 import 用到的库 → 全部是本地生产依赖
- 仅构建、校验、测试工具,代码不 import → 全部是本地开发依赖(-D)
- 需要在任意目录敲 CLI 命令,且不属于项目本身 → 全局;优先用
pnpm dlx代替全局安装,减少全局污染 - 永远不要把业务库(vue/react)全局安装
设置国内镜像(必做,加速下载)
# 设置 registry pnpm config set registry https://registry.npmmirror.com # 查看当前源 pnpm config get registrypnmp 帮助
pnmp -h 用法: pnpm [选项] <命令> 命令: access 管理包在仓库上的访问权限与可见性 init 初始化 package.json recursive 在所有子目录项目中并发执行命令 [别名: multi, m] add 添加包依赖 install 安装包 [别名: i] install-test 执行 pnpm install,紧接着执行 pnpm test。参数和 pnpm install 完全一致 [别名: it] update 根据指定版本范围,将包更新到最新版本 [别名: up, upgrade] outdated 检查已安装包与 GitHub Actions 依赖是否存在新版本 audit 检查已安装包的已知安全漏洞 change 记录变更意图:标记本次改动影响哪些包、每个包的版本升级类型,以及将写入更新日志的摘要 version 应用已记录的变更意图(pnpm version -r) lane 管理分轨发布通道 bugs 在默认浏览器打开包的 bug 跟踪地址 [别名: issues] list 列出已安装的包 [别名: ls] ll 以详细格式列出已安装包 [别名: la] licenses 检查已安装包的许可证信息 [别名: licences] why 查看依赖该包的上游包(查询这个包是谁引入的) view 查看远程仓库上包的信息 [别名: info, show, v] sbom 生成软件物料清单(SBOM) whoami 显示当前登录到 pnpm 仓库的用户名 deprecate 将仓库上某个包版本标记为废弃 undeprecate 取消包版本的废弃标记,仅对已标记废弃的版本生效 unpublish 从仓库移除指定包 star 收藏一个包 unstar 取消包收藏 stars 列出指定用户收藏的所有包 dist-tag 管理包的发布标签 [别名: dist-tags] ping 测试与配置的镜像仓库连通性 doctor 对当前 pnpm 安装环境做诊断检查 search 在仓库搜索包 [别名: s, se, find] rebuild 重新编译包 [别名: rb] pack 生成包的 tar 压缩包 publish 将包发布到仓库 stage 预打包待发布包,把二次验证(2FA)延迟到后续操作 remove 从 node_modules 和 package.json 删除包 [别名: uninstall, rm, un, uni] patch 准备对第三方包打补丁 patch-commit 根据目录改动生成补丁文件 patch-remove 删除已存在的补丁文件 peers 检查未满足或缺失的对等依赖(peerDependencies)问题 set-script 在 package.json 中设置脚本 [别名: ss] test 执行 package.json 里定义的 test 脚本 run 执行 package.json 中定义的脚本 pipeline 以 CI 的方式执行命名的工作流任务:冻结锁文件安装、基于基线筛选变更包、按依赖拓扑执行任务并缓存结果,失败不终止 exec 在当前项目环境中执行 shell 命令 dlx 在临时环境中运行包 create 使用 create-* 脚手架模板新建项目 completion 输出 shell 自动补全脚本 start 执行 package.json scripts.start 里的命令 stop 执行 package.json scripts.stop 脚本(如有定义) restart 重启项目:依次执行 stop、restart、start 脚本以及对应的前置/后置脚本 find-hash 根据文件哈希,列出包含该文件的包 runtime 管理运行时 [别名: rt] env 管理 Node.js 版本。已废弃,推荐使用 pnpm runtime shim 为未全局安装的包创建上下文感知的命令垫片,由项目决定使用哪个版本 bin 打印 pnpm 存放可执行脚本的目录 clean 安全删除当前项目(或所有工作区子项目)的 node_modules,不会跟随 NTFS 链接进入目标目录。如果 package.json 存在 clean 脚本,则内置命令会被覆盖 purge clean 的别名:行为一致;区别是当 package.json 存在 purge 脚本时,会覆盖内置命令 ci 先 clean,再执行带锁文件冻结模式的 install [别名: clean-install, ic, install-clean] root 打印 node_modules 的实际目录路径 prefix 打印当前包所在根目录 config 管理 pnpm 配置文件 [别名: c] get 获取指定配置项的值,是 pnpm config get 的简写 set 设置指定配置项的值,是 pnpm config set 的简写 pkg 管理 package.json 文件 pack-app 将 CommonJS 入口文件打包为多平台独立可执行程序 store 管理包全局存储目录 cache 查看与管理元数据缓存 cat-file 根据索引文件里存储的哈希,打印文件内容 cat-index 打印全局存储中指定包的索引文件 ignored-builds 打印被禁止执行构建脚本的包列表 approve-builds 允许依赖包在安装阶段执行构建脚本 link 将本地包链接为项目依赖 [别名: ln] import 从外部锁文件生成 pnpm-lock.yaml dedupe 在锁文件中对依赖做去重优化 deploy 从工作区发布部署包 prune 移除多余无用的依赖包 fetch 根据锁文件把包下载到虚拟存储目录 unlink 取消本地包链接,重新安装线上版本 [别名: dislink] docs 在浏览器打开包的文档主页 [别名: home] repo 在浏览器打开包的代码仓库地址 self-update 更新 pnpm 到最新版本(或指定版本) setup 初始化配置 pnpm login 登录 npm 镜像仓库 [别名: adduser] team 管理组织团队与团队成员 owner 管理包的所有者 [别名: owners] logout 退出 npm 镜像仓库登录 with 单次调用使用指定版本 pnpm(或当前版本),忽略项目 packageManager 和 devEngines.packageManager 配置 edit pnpm 未实现该命令,请直接使用 npm CLI profile pnpm 未实现该命令,请直接使用 npm CLI token pnpm 未实现该命令,请直接使用 npm CLI xmas pnpm 未实现该命令,请直接使用 npm CLI help 打印本帮助信息,或指定子命令的帮助文档 选项: -v, --version 打印 pnpm 版本号 --color[=<COLOR>] 强制开启彩色输出 -y, --yes 所有交互提示自动选择 yes -C, --dir <DIR> 设置工作目录。可放在子命令前后任意位置,和其他全局配置参数一样 [默认值: .] --store-dir <DIR> 创建包全局存储的目录。相对路径基于工作区根目录解析;非工作区场景基于 --dir 目录解析 --state-dir <DIR> pnpm 存放本机持久化状态文件的目录 --npmrc-auth-file <NPMRC_AUTH_FILE> 指定 .npmrc 认证文件路径,覆盖默认 ~/.npmrc [别名: --userconfig] --registry <REGISTRY> 解析和下载包的仓库基础地址。全局通用配置参数,可作用于所有命令,多层配置会合并;部分自带 --registry 参数的命令也会读取该配置 --https-proxy <HTTPS_PROXY> HTTPS 仓库与压缩包请求的代理地址 --http-proxy <HTTP_PROXY> HTTP 仓库与压缩包请求的代理地址 --no-proxy <NO_PROXY> 不使用代理访问的主机列表 -r, --recursive 在工作区的所有项目执行命令,而不仅仅是 --dir 指定的项目 --reporter <REPORTER> 输出日志格式 [默认值: default] [可选值: default, append-only, ndjson, silent] --loglevel <LOGLEVEL> 设置日志输出级别。等同于 pnpm 全局 --loglevel 参数:silent 会强制使用静默输出,覆盖 --reporter;其他级别限制默认日志输出 [可选值: silent, error, warn, info, debug] -F, --filter <FILTER> 筛选工作区中需要执行命令的项目。可多次使用叠加筛选条件。支持名称匹配(@scope/*)、路径(./pkg)、依赖查询(foo...)、排除(!bar)、目录({dir})、变更基线查询([since]) --filter-prod <FILTER_PROD> 类似 --filter,但筛选时只追踪生产依赖 -w, --workspace-root 在工作区根项目执行命令 --fail-if-no-match --filter / --filter-prod 没有匹配任何项目时,退出码置为1 --include-workspace-root recursive 递归命令也会包含根项目;run / exec / add / test 默认不会包含根项目 --no-include-workspace-root 递归命令排除根项目,覆盖 includeWorkspaceRoot: true 配置 --test-pattern <TEST_PATTERN> 匹配测试文件的 glob 规则,用于 --filter 的 [since] 判断哪些改动算作测试变更 --changed-files-ignore-pattern <CHANGED_FILES_IGNORE_PATTERN> glob 规则,忽略 --filter [since] 检测变更时不需要关注的文件 --sort 工作区项目按依赖拓扑顺序执行 --no-sort 不做拓扑排序,按工作区定义顺序执行 --reverse 逆序处理工作区项目 --workspace-concurrency <WORKSPACE_CONCURRENCY> 工作区项目最大并行执行数量 --parallel 在所有选中项目并发执行脚本,忽略依赖拓扑顺序 --stream 实时输出每个子项目日志,每行附带项目前缀 --aggregate-output 等待脚本执行完毕后一次性输出全部日志块 --use-stderr 将日志输出定向到 stderr,把 stdout 留给命令本身输出结果 --ignore-workspace 忽略上层 pnpm-workspace.yaml,当作独立单项目运行 --workspace-packages <WORKSPACE_PACKAGES> glob 规则,用于选定工作区项目,覆盖 pnpm-workspace.yaml 的 packages 配置,可多次配置 -h, --help 打印帮助文档(使用 --help 查看更详细内容)核心命令清单(和 npm 几乎对齐)
npm install -g pnpm # 安装 pnpm pnpm -v # 查看版本 pnpm install # 安装项目全部依赖(读取 package.json) pnpm add axios # 添加生产依赖(等价 npm install xxx) pnpm add -D vite # 添加开发依赖(devDependencies) pnpm add vue@3.4 # 添加指定版本 pnpm remove axios # 卸载包 pnpm run dev # 执行 package.json scripts,等价 npm run dev pnpm dev # 简写,脚本只有一个词时可以省略 run pnpm test pnpm start pnpm stop pnpm restart pnpm exec <cmd> # 在当前项目node_modules上下文执行shell命令 # pnpm dlx = npx pnpm dlx create-vite@latest my-app # 临时执行包(等价 npx!重点) pnpm ls # 查看已安装依赖树 pnpm prune # 清理未使用依赖 pnpm update # 更新包 pnpm update vue@latest # 1. 初始化项目 pnpm init # 2. 添加依赖 pnpm add axios pnpm add -D vite # 3. monorepo场景:只给 packages/utils 添加依赖 pnpm -F utils add lodash # 4. CI安装 pnpm ci # 5. 查看是谁引入lodash pnpm why lodash # 6. 临时运行脚手架 pnpm dlx create-vite| 命令 | 别名 | 说明 |
|---|---|---|
pnpm init | - | 生成 package.json |
pnpm install | pnpm i | 安装项目所有依赖 |
pnpm add <pkg> | - | 添加依赖(默认 dependencies)pnpm add -D→ devDependencies |
pnpm remove <pkg> | rm / un / uninstall | 删除包,同时移除 package.json 声明 |
pnpm update | up / upgrade | 更新包版本 |
pnpm list | ls | 列出已安装包pnpm ll/la:详细长格式 |
pnpm outdated | - | 检查哪些包有新版本 |
pnpm audit | - | 安全漏洞扫描 |
pnpm prune | - | 删除多余、未被引用的包 |
pnpm rebuild | rb | 重新编译原生模块(node-gyp 类) |
pnpm dlx | - | 临时下载并执行包,不安装到本地 / 全局(替代 npx) |
pnpm create | - | 直接调用 create-xxx 脚手架(pnpm create vite) |
CI 专用:
pnpm ci(等价 clean + install,lockfile 严格冻结,不改动锁文件,生产 CI 推荐),别名ic / clean-install
cnpm
不是独立包管理器!只是 npm 的一层封装脚本,阿里早期开发。本质 =npm+ 自动切换淘宝镜像源,用来加速国内下载。旧地址registry.npm.taobao.org废弃,新镜像:https://registry.npmmirror.com
# 全局安装 cnpm npm install -g cnpm --registry=https://registry.npmmirror.com cnpm install注意事项:
- cnpm 默认生成
cnpm-lock.yaml,不会更新 package-lock.json,团队协作版本不一致风险大 - 底层仍然调用 npm,没有 pnpm/yarn 的性能优化
- 不推荐新项目使用 cnpm!推荐做法:直接修改 npm / pnpm / yarn 的 registry 镜像源,不用装 cnpm。
- 优缺点:优点:一键切换国内源。缺点:锁文件不一致,无性能提升,属于过时方案
yarn
Yarn(Yet Another Resource Negotiator)是 Meta(Facebook)推出,当初为了解决早期 npm 的稳定性、锁文件问题;分两个版本:Yarn Classic(v1)/Yarn Berry(v2+),Yarn Berry 也叫 Yarn Modern,支持 PnP(Plug'n'Play),不再使用 node_modules。
Yarn Berry (v2 / v3 / v4)
- 默认PnP 模式:不生成 node_modules,通过 zip 直接读取包,节省大量磁盘
- 可开启 node_modules 兼容模式;锁文件
yarn.lock - 严格依赖,无幽灵依赖;monorepo 能力很强
- 注意:Yarn 和 npm lock 文件不能混用。
优缺点
- 优点:v1 历史稳定;Berry PnP 省磁盘,monorepo 强大
- 缺点:v1 已逐步淡出;PnP 模式对部分老工具、插件兼容性坑多;现在新项目优先 pnpm
2、nodejs 版本管理工具
fnm vs nvm(node version manager)
| 对比维度 | fnm | nvm |
|---|---|---|
| 语言 | Rust 二进制 | Shell 脚本 |
| 终端启动速度 | ⚡极快 | 慢,每次启动执行脚本 |
| Windows 支持 | ✅原生支持 | ❌原版不支持,要用 nvm-windows |
| 自动切换 | ✅内置--use-on-cd | 需要额外插件 |
| 文件兼容 | .node-version/.nvmrc | .nvmrc |
| 推荐人群 | Windows / Mac / Linux,追求终端速度 | 老 Linux 项目,习惯 nvm |
nvm (Node Version Manager)
nvm 是 Node Version Manager 的简称,是 Node.js 版本管理工具,专门解决多项目 Node 版本冲突问题。类似 conda 管理 python 环境。
核心作用
- 一台 Mac 同时安装多个 Node.js(Node14/16/18/20/22 共存)
- 一键切换当前终端使用的 Node 版本
- 每个 Node 环境独立隔离,npm 全局包互不干扰
- 避免系统自带 Node /brew 安装 Node 带来的权限报错、版本锁定问题
和直接 brew install node 的区别
- brew:同一时间只能存在一个 Node,多项目版本冲突无解
- nvm:多版本自由切换,前端开发标准方案
安装步骤(Mac zsh)
前置依赖:xcode-select --install
一键安装 nvm:curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
写入 zsh 配置(关键,否则重启终端 nvm 失效)
echo 'export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> ~/.zshrc # 生效配置 source ~/.zshrc # 验证是否安装成功 nvm --version输出版本号即代表正常。
查看本地已安装的 Node
命令:nvm ls
输出说明:
-> v20.16.0:当前终端正在使用的版本default -> lts/* (-> v20.16.0):全局默认版本- 带
*= 默认
查看可安装的 Node 版本
查看所有线上版本:nvm ls-remote
只看长期稳定版 LTS(开发推荐):nvm ls-remote --lts
安装 Node.js
安装最新 LTS 稳定版(日常首选):nvm install --lts
安装指定大版本:
nvm install 20 # 安装 Node20
nvm install 18 # 安装 Node18精确指定小版本:nvm install 16.20.0
切换 Node 版本
临时切换(仅当前终端窗口有效,重启失效)
nvm use 18
nvm use lts
设置全局默认版本(新开终端自动加载)
nvm alias default 20 # 将 Node20 设为默认
nvm alias default lts # 将最新LTS设为默认
查看当前正在使用的版本
nvm current
node -v
npm -v
卸载不需要的 Node 版本
nvm uninstall 16 # 卸载 Node16
注意:不能卸载当前正在 use 的版本,需先切换到其他版本再删。
全局包迁移。每个 Node 版本的 npm 全局包是隔离的,比如 pnpm、yarn、typescript 不会跨版本共用。全局包迁移 可以实现 不同 Node 共享工具。
nvm reinstall-packages 18 # 把当前版本全局包复制到 Node18
npm i -g pnpm yarn typescript vite @vue/cli # 推荐全局 (任意 Node 安装一次即可迁移)
项目自动匹配 Node 版本。无需手动 nvm use。
- 1)项目根目录创建
.nvmrc文件。指定本项目使用 Node20:echo "20" > .nvmrc - 2)进入项目目录自动切换:nvm use
常用命令
# 基础信息 nvm --version # 查看nvm版本 nvm current # 当前node版本 nvm ls # 本地已装node列表 nvm ls-remote --lts # 线上所有LTS版本 # 安装卸载 nvm install --lts # 安装最新稳定版 nvm install 18.18.2 # 安装指定版本 nvm uninstall 16 # 删除版本 # 版本切换 nvm use 18 # 临时切换 nvm alias default 20 # 设置全局默认 # 包迁移 nvm reinstall-packages 18 # 复制全局依赖到其他版本nvm install 8.0.0 # 安装指定精确版本号 nvm use 8.0 # 切换使用 8.0 系列下最新的小版本(8.0.x 最高版) nvm run 6.10.3 app.js # 用 node 6.10.3 直接运行 app.js nvm exec 4.8.3 node app.js # 临时把环境PATH指向4.8.3,执行 node app.js nvm alias default 8.1.0 # 设置终端默认 node 版本为 8.1.0 nvm alias default node # 设置终端默认始终为本地已安装的最新 node 正式版 nvm install node # 安装当前最新的 Node 正式版 nvm use node # 切换使用本地已装的最新 Node 正式版 nvm install --lts # 安装最新长期支持稳定版(LTS) nvm use --lts # 切换使用本地已装的最新 LTS 稳定版 nvm set-colors cgYmW # 自定义 nvm 命令行文字配色:青、绿、粗黄、品红、白切换 node 后全局命令找不到?
- 各 Node 环境隔离,执行
nvm reinstall-packages 目标版本迁移工具。
之前用 brew 装过 node,和 nvm 冲突
- 先卸载 brew 的 node:
brew uninstall --ignore-dependencies node
brew autoremove
windows 中 nvm
C:\>nvm -h Usage: nvm <command> [flags] Node Version Manager for Windows v2.0.0 (Community Edition). Flags: -h, --help Show context-sensitive help. -v, --version Display the version of nvm. Commands: install (i,add) Install one or more Node.js versions. uninstall (rm,un) Uninstall one or more Node.js versions. use Switch the default Node.js version. pin Pin project Node.js version (ex: write .nvmrc). list (ls) List the installed/available Node.js versions. alias Manage Node.js version aliases. default Show the default version. env Display nvm environment details. cache View and manage the nvm cache. config (cfg) View and manage the nvm configuration. on Manage Node.js with nvm. off Stop managing Node.js with nvm. Run "nvm <command> --help" for more information on a command. Additional help available at https://docs.nvm-windows.comfnm (Fast Node Manager)
Fnm (Fast Node Manager) 是一个快速而简单的 Node.js 版本管理工具,使用 Rust 编写。跨平台支持(macOS、Windows、Linux)。对标 nvm(node version manager),主打更快启动、切换速度。github:https://github.com/Schniz/fnm
核心特点
- Rust 单二进制文件,没有 shell 脚本,终端启动极快,远快于 bash 版 nvm稀土掘金
- 全平台支持:macOS / Linux / Windows(PowerShell / CMD),原生支持 Windows,这点比原版 nvm 强很多
- 支持自动版本切换:进入项目目录,读取
.node-version/.nvmrc,自动切 Node 版本 - 兼容 nvm 的配置文件,迁移成本低
- 支持国内镜像加速下载 Node
性能对比:nvm 每次打开 shell 都会加载脚本,拖慢终端;fnm 采用懒加载,打开终端几乎无感。
安装 fnm
macOS
# brew(推荐) brew install fnm # 脚本安装 curl -fsSL https://fnm.vercel.app/install | bashLinux
curl -fsSL https://fnm.vercel.app/install | bashWindows(PowerShell)
# winget 推荐 winget install Schniz.fnm # 脚本 iwr -useb https://fnm.vercel.app/install | iex配置 shell(关键!不配置无法自动生效)
安装后必须在 shell 配置文件写入环境加载:
- zsh(macOS 默认)
~/.zshrc:eval "$(fnm env --use-on-cd)" - bash
~/.bashrc:eval "$(fnm env --use-on-cd)" - PowerShell
$PROFILE:fnm env --use-on-cd | Out-String | Invoke-Expression
--use-on-cd:开启进入目录自动切换 Node 版本(最常用)
重启终端,验证:fnm --version
常用命令
# 查看已安装 Node 版本 fnm list # 查看远程可安装版本 fnm list-remote # 安装最新 LTS fnm install --lts # 安装指定大版本/精确版本 fnm install 20 fnm install 20.14.0 # 切换到某个版本(当前shell生效) fnm use 20 # 设置全局默认 Node 版本(新开终端默认用这个) fnm default 20 # 查看当前正在使用的 node fnm current # 删除本地某个 node 版本 fnm uninstall 18 # 创建别名 fnm alias lts20 20.14.0项目自动切换 Node
在项目根新建
.node-version文件,写入:20.14.0之后
cd进入该目录,fnm 自动执行fnm use,切换对应 Node。
设置国内镜像(加速 Node 下载)
# 环境变量,写入shell配置 export FNM_NODE_DIST_MIRROR=https://npmmirror.com/mirrors/node