前端 Node.js 包管理器-pnpm 作者:马育民 • 2026-05-08 08:09 • 阅读:10005 # 介绍 **pnpm (Performant NPM)** 是由 Zoltan Kochan 开发的高性能 Node.js 包管理器,核心解决 npm/yarn 磁盘冗余、安装缓慢、依赖管理松散等痛点,兼具**极致磁盘利用率、超快安装速度、严格依赖隔离**三大核心优势。 官网:https://pnpm.io/zh/ # 原理 ### 1. 全局单一存储 所有版本的包仅在全局仓库(默认 `~/.pnpm-store`)存储**唯一副本**,通过文件内容哈希值(hash)寻址,而非文件名/版本号。 - 例:10个项目依赖 `lodash@4.17.21`,pnpm 仅存1份,npm/yarn 存10份。 ### 2. 硬链接(Hard Link) 项目安装依赖时,不复制文件,仅创建指向全局存储的**硬链接**(几乎不占磁盘空间)。 ### 3. 符号链接(Symlink) 构建项目 `node_modules` 时,通过符号链接组织依赖关系,形成**非扁平化**结构,严格遵循依赖声明。 - 根 `node_modules` 仅包含 `package.json` 显式声明的依赖(符号链接); - 子依赖嵌套在 `.pnpm` 目录下,避免“幽灵依赖”(未声明却可引用)。 # 优势(对比 npm/yarn) ### 1. 磁盘空间利用率极高 - npm/yarn:每个项目完整复制依赖树,多项目冗余严重; - pnpm:全局共享存储,硬链接复用文件,**大型项目可节省70%+磁盘空间**。 ### 2. 安装速度快(2倍+) - 并行解析、下载、链接依赖; - 增量更新:仅下载全局仓库缺失的包; - 无文件复制开销,仅创建链接。 ### 3. 严格依赖隔离(无幽灵依赖) - 仅能访问 `package.json` 声明的依赖,子依赖不可直接引用; - 避免因依赖提升(npm 扁平化)导致的版本冲突和隐式依赖问题。 ### 4. 原生支持 Monorepo 内置 `pnpm-workspace.yaml`,无需额外配置(如 lerna),轻松管理多包仓库: - 统一版本管理、依赖共享; - 支持按包过滤命令(`--filter`)、递归执行脚本(`-r`)。 ### 5. 安全性高 - 依赖不可随意访问,降低恶意包风险; - 支持依赖校验、完整性检查。 # 与 npm/Yarn 对比 | 特性 | pnpm | npm | Yarn Classic | Yarn Berry (PnP) | | :--- | :--- | :--- | :--- | :--- | | **磁盘占用** | 极低(硬链接共享) | 高(全复制) | 高(全复制) | 极低(ZIP 存储) | | **安装速度** | 最快(并行+链接) | 慢(串行+复制) | 中(并行+复制) | 快(无 node_modules) | | **幽灵依赖** | 无(严格隔离) | 有(扁平化) | 有(扁平化) | 无(PnP 严格) | | **Monorepo** | 原生支持 | 需第三方(lerna) | 需第三方(lerna) | 原生支持 | | **兼容性** | 兼容 npm 生态 | 标准 | 兼容 | 部分不兼容 | # 适用场景 - **大型项目/多项目**:磁盘节省和速度优势显著; - **Monorepo 架构**:内置工作空间,简化多包管理; - **CI/CD 环境**:快速安装,减少构建时间; - **依赖复杂项目**:严格依赖隔离,避免版本冲突。 # node_modules 结构解析 以项目依赖 `react@18.2.0` 为例: ``` project/ ├── node_modules/ │ └── react -> .pnpm/react@18.2.0/node_modules/react # 符号链接 ├── .pnpm/ │ └── react@18.2.0/ │ └── node_modules/ │ ├── react/ # 硬链接到全局存储 │ └── loose-envify/ # react 的子依赖(硬链接) ├── package.json └── pnpm-lock.yaml ``` - **无扁平化**:子依赖不提升到根 `node_modules`; - **严格隔离**:仅声明依赖可见,避免幽灵依赖。 # 注意事项 1. **Node.js 版本**:pnpm 11+ 要求 Node.js 22+; 2. **Windows 权限**:需开启开发者模式或管理员权限(创建符号链接); 3. **迁移成本**:从 npm 迁移需删除 `node_modules` 和 `package-lock.json`,执行 `pnpm install`; 4. **生态兼容**:极少数旧包可能依赖 npm 扁平化结构,需适配。 # Windows默认安装目录 Windows 官方脚本默认装在: ``` C:\Users\你的用户名\AppData\Local\pnpm\ ``` 可执行文件 `pnpm.exe` 在: ``` C:\Users\你的用户名\AppData\Local\pnpm\bin\ ``` 环境变量默认会自动加这个 `bin` 目录到系统 Path。 --- ### 五大默认存储目录 打开 PowerShell 执行 `pnpm config list` 可查看,默认: ##### 1. 内容寻址仓库(store 包仓库) ``` C:\Users\你的用户名\.pnpm-store\ ``` ##### 2. 全局依赖安装目录 global-dir 全局装的包位置: ``` C:\Users\你的用户名\AppData\Local\pnpm\global ``` ##### 3. 全局二进制目录 global-bin-dir 全局包的 cmd 脚本、软链接: ``` C:\Users\你的用户名\AppData\Local\pnpm\bin ``` ##### 4. 缓存目录 cache-dir ``` C:\Users\你的用户名\.pnpm\cache ``` ##### 5. 状态目录 state-dir ``` C:\Users\你的用户名\.pnpm\state ``` # 安装-windows ### 直接安装 打开 PowerShell 执行下面命令: ``` iwr https://get.pnpm.io/install.ps1 -useb | iex ``` 下面使用国内网址下载,更稳定: ``` iwr https://registry.npmmirror.com/-/web/detail/pnpm/files/install.ps1 -useb | iex ``` ### 自定义安装(推荐) 使用官方网址安装 pnpm,下载 **可能失败**(可用npm通过国内网址下载,成功率高) ``` # 只需要改这里!你的 pnpm 根目录 $PNPM_ROOT = "D:\devtools\pnpm" # 自动创建所有文件夹 mkdir $PNPM_ROOT -ea 0 mkdir "$PNPM_ROOT\bin" -ea 0 mkdir "$PNPM_ROOT\store" -ea 0 mkdir "$PNPM_ROOT\global" -ea 0 mkdir "$PNPM_ROOT\cache" -ea 0 mkdir "$PNPM_ROOT\state" -ea 0 # 设置 PNPM_HOME,让安装程序装到你指定的目录 $env:PNPM_HOME = "$PNPM_ROOT\bin" # 官方网址在国外,可能导致下载失败 iwr https://get.pnpm.io/install.ps1 -useb | iex # ✅ 关键:用变量统一配置所有目录 pnpm config set store-dir "$PNPM_ROOT\store" pnpm config set global-dir "$PNPM_ROOT\global" pnpm config set global-bin-dir "$PNPM_ROOT\bin" pnpm config set cache-dir "$PNPM_ROOT\cache" pnpm config set state-dir "$PNPM_ROOT\state" # 配置国内镜像源 pnpm config set registry https://registry.npmmirror.com/ ``` ##### 解释 - 使用官方网址安装 pnpm,下载 **可能失败**(可用npm通过国内网址下载,成功率高) - `pnpm.exe` 会直接装到 `D:\devtools\pnpm\bin`,不会跑到 `C` 盘 - 配置国内镜像源 # 安装-macOS/Linux ### 直接安装 在控制台执行下面命令: ``` curl -fsSL https://get.pnpm.io/install.sh | sh - ``` # 安装-通过npm安装 已经安装node,可通过下面方式安装 ```bash npm install -g pnpm ``` ### 自定义安装 ``` # 定义 pnpm 根目录 $PNPM_ROOT = "D:\devtools\pnpm" # 创建目录,已存在不报错 mkdir $PNPM_ROOT -ea 0 mkdir "$PNPM_ROOT\bin" -ea 0 mkdir "$PNPM_ROOT\store" -ea 0 mkdir "$PNPM_ROOT\global" -ea 0 mkdir "$PNPM_ROOT\cache" -ea 0 mkdir "$PNPM_ROOT\state" -ea 0 # 设置 PNPM_HOME $env:PNPM_HOME = "$PNPM_ROOT\bin" # 国内镜像安装 pnpm npm config set registry https://registry.npmmirror.com npm install -g pnpm --prefix "$PNPM_ROOT" # 配置 pnpm 所有目录 pnpm config set store-dir "$PNPM_ROOT\store" pnpm config set global-dir "$PNPM_ROOT\global" pnpm config set global-bin-dir "$PNPM_ROOT\bin" pnpm config set cache-dir "$PNPM_ROOT\cache" pnpm config set state-dir "$PNPM_ROOT\state" # 配置包下载国内镜像 pnpm config set registry https://registry.npmmirror.com/ ``` ##### 解释 - 国内镜像安装 pnpm,下载更稳定 - `pnpm.exe` 会直接装到 `D:\devtools\pnpm\bin`,不会跑到 `C` 盘 - 配置国内镜像源 # 验证是否安装成功 ``` pnpm -v ``` 输出版本号,如下: ``` 7.9.0 ``` # 查看命令 ### 查看所有默认路径 ```powershell pnpm config list ``` ### 单独查看仓库存储路径 ``` pnpm store path ``` # 设置镜像源(加速国内下载) ```bash pnpm config set registry https://registry.npmmirror.com/ ``` # 常用命令 ### 项目初始化 ```bash pnpm init # 生成 package.json ``` ### 根据文件安装依赖 根据 `package.json + pnpm-lock.yaml` 安装所有依赖 ```bash pnpm install ``` ### 安装生产依赖 安装vue3、elementplus(以及图标)、axios的最新稳定版: ``` pnpm add vue@3 element-plus @element-plus/icons-vue axios ``` ### 安装指定版本 ``` pnpm add vue-router@5 ``` ### 安装最新版本 ``` pnpm add vue-router@latest ``` **提示:**`@latest` 可省略 ### 安装开发依赖 ``` pnpm add -D typescript vite ``` 如不需要写 `import` 的开发依赖: ``` pnpm add -D unplugin-auto-import unplugin-vue-components ``` ### 全局安装 安装一次,整个电脑所有项目、所有文件夹都能用,一般 **【命令行工具】** 才需要全局安装 ``` pnpm add -g @vue/cli ``` ### 更新依赖 ``` pnpm update lodash@^4.17 ``` ### 卸载依赖 ``` pnpm remove lodash ``` ### 查看依赖树 ``` pnpm list ``` ### 检查依赖来源 ``` pnpm why react ``` # 开发模式运行 ```bash # 运行 package.json 脚本 pnpm run dev ``` 简写: ``` pnpm dev ``` ### 传递参数 ``` pnpm dev -- --port 3000 ``` # 生产构建 ``` pnpm run build ``` 简写: ``` pnpm build ``` ### 4. Monorepo 操作 ```bash # 1. 根目录创建 pnpm-workspace.yaml packages: - 'packages/*' - 'apps/*' # 2. 按包过滤运行脚本 pnpm --filter=@app/client dev # 3. 递归执行所有包的 build 脚本 pnpm -r run build # 4. 查看工作空间依赖 pnpm ls -r ``` # 总结 pnpm 是现代前端工程化的**基础设施级工具**,以**硬链接+CAS**为核心,解决传统包管理器的核心痛点,兼具**高效、安全、现代**特性,已成为大型项目和 Monorepo 架构的首选包管理器。 原文出处:http://www.malaoshi.top/show_1GW3Gxg3jZuC.html