一文了解npm、yarn、pnpm和npx
2025-5-18
| 2025-5-19
字数 4272阅读时长 11 分钟
type
status
date
slug
summary
tags
category
icon
password
🔧
对于编程初学者来说,Node.js 生态系统中的包管理工具可能会令人困惑。不同的工具各有特点和适用场景,让我们深入了解它们的区别和用途。
 
以下是npm、Yarn、pnpm 和 npx 的详细对比解释,涵盖它们的核心功能、差异和适用场景:

1.区别与联系

1.1. npm (Node Package Manager)

  • 定位:Node.js 的默认包管理器,随 Node.js 自动安装。
  • 核心功能
    • 安装、卸载、更新依赖包(npm install/uninstall/update)。
    • 管理项目依赖(dependencies/devDependencies)。
    • 运行脚本(npm run)。
    • 发布包到 npm 仓库(npm publish)。
  • 特点
    • 嵌套依赖结构:依赖以递归方式嵌套安装,可能导致重复依赖和较慢的安装速度。
    • 全局缓存:下载的包会缓存在本地,减少重复下载。
    • 版本锁定:通过 package-lock.json 锁定依赖版本。
  • 缺点
    • 依赖冗余和磁盘占用高。
    • 早期版本安装速度较慢(后续版本有优化)。

1.2. Yarn

  • 定位:由 Facebook 开发,旨在解决 npm 的早期性能问题。
  • 核心功能
    • 与 npm 功能类似(安装、脚本运行、发布等)。
    • 新增命令如 yarn add/remove/upgrade
  • 特点
    • 扁平化依赖:通过 yarn.lock 文件锁定版本,减少依赖重复。
    • 并行安装:显著提升安装速度(尤其是早期版本)。
    • 离线模式:优先使用本地缓存。
    • 工作区(Workspaces):支持多包项目管理。
  • 缺点
    • 扁平化依赖可能导致依赖冲突(“幽灵依赖”问题)。
    • Yarn 2+ 的 Plug'n'Play(PnP)模式改变传统依赖结构,学习成本高。

1.3. pnpm (Performance npm)

  • 定位:注重磁盘效率和性能的包管理器。
  • 核心功能
    • 兼容 npm/Yarn 的大部分命令(pnpm install/add/run)。
  • 特点
    • 硬链接 + 符号链接
      • 所有依赖集中存储在全局存储(~/.pnpm-store),通过硬链接引用,大幅减少磁盘占用。
      • 依赖通过符号链接映射到 node_modules,避免“幽灵依赖”。
    • 严格依赖结构node_modules 中只包含显式声明的依赖,结构更清晰。
    • 高性能:安装速度通常快于 npm/Yarn。
  • 缺点
    • 某些工具链可能不兼容其独特的 node_modules 结构。
    • 需要适应其依赖隔离设计。

1.4. npx (Node Package Executor)

  • 定位:用于临时执行 npm 包中的命令,无需全局安装。
  • 核心功能
    • 运行本地或远程的包(如 npx create-react-app)。
    • 自动下载并执行包,执行后清理。
  • 特点
    • 避免全局安装:适合一次性工具(如脚手架)。
    • 灵活调用:可指定包版本(npx package@version)。
  • 与 npm/Yarn/pnpm 的关系
    • npm 5.2+ 内置 npx,Yarn 通过 yarn dlx 提供类似功能,pnpm 通过 pnpm dlx 支持。

1.5. 对比总结

特性
npm
Yarn
pnpm
npx
安装速度
中等(新版有优化)
快(并行安装)
极快(硬链接)
不适用
磁盘效率
低(嵌套依赖)
中等(扁平化)
高(全局存储 + 硬链接)
临时使用
依赖管理
package-lock.json
yarn.lock
pnpm-lock.yaml
依赖隔离
弱(可能重复)
中等(扁平化冲突)
强(符号链接隔离)
不适用
多包管理
Workspaces
Workspaces
不适用
执行临时命令
通过 npx
通过 yarn dlx
通过 pnpm dlx
核心功能
典型使用场景
Node.js 默认工具
需要快速安装的大型项目
注重磁盘效率和依赖隔离
运行脚手架或一次性命令

1.6. 如何选择?

  • 兼容性优先:使用 npm(尤其对旧项目或工具链)。
  • 平衡性能与生态:选择 Yarn(尤其是 Yarn 1.x)。
  • 极致性能与磁盘效率:选择 pnpm(适合现代项目)。
  • 临时执行命令:npx 或对应的 dlx 命令。
现代工具链(如 Vite、TurboRepo)已普遍支持这些工具,可根据团队需求灵活选择。
 

2. NPM详细介绍

npm(Node Package Manager)是 Node.js 的默认包管理器,也是 JavaScript 生态系统中最重要的工具之一。它用于管理项目的依赖关系、运行脚本、发布包等。以下是对 npm 的全面解析:

2.1. npm是什么?

  • 定义:npm是一个包管理器,用于安装、管理和共享JavaScript代码(称为“包”或“模块”)。
  • 功能
    • 安装第三方库(如 lodashreact)。
    • 管理项目依赖(dependenciesdevDependencies)。
    • 运行自定义脚本(如 npm startnpm test)。
    • 发布自己的包到 npm 仓库(npm publish)。
 

2.2. npm的核心概念

(1) package.json

  • 作用:项目的配置文件,定义元数据(名称、版本、依赖等)。
  • 生成方式
    • 关键字段

      (2) 依赖管理

      依赖类型
      安装方式
      用途
      dependencies
      npm install lodash
      生产环境必需的包
      devDependencies
      npm install eslint --save-dev
      开发环境专用(测试、构建工具)
      peerDependencies
      npm install react --save-peer
      插件依赖的主库(如 webpack 插件)
      optionalDependencies
      npm install fsevents --save-optional
      可选依赖(安装失败不影响运行)

      (3) node_modules

      • 作用:存储所有安装的依赖包。
      • 特点
        • npm 3+ 采用扁平化结构(减少重复依赖)。
        • 早期版本使用嵌套结构(易导致依赖冗余)。

      (4) package-lock.json

      • 作用:锁定依赖版本,确保不同环境安装相同的依赖树。
      • 生成方式:自动生成(npm install 时创建)。
      • 示例

        2.3. npm常用命令

        (1) 安装依赖

        命令
        作用
        npm install
        安装所有依赖(根据 package.json
        npm install lodash
        安装指定包(默认添加到 dependencies
        npm install eslint --save-dev
        安装开发依赖
        npm install -g nodemon
        全局安装(用于命令行工具)

        (2) 卸载依赖

        命令
        作用
        npm uninstall lodash
        卸载包
        npm uninstall eslint --save-dev
        卸载开发依赖

        (3) 更新依赖

        命令
        作用
        npm update
        更新所有依赖
        npm update lodash
        更新指定包
        npm outdated
        检查过时的包

        (4) 运行脚本

        命令
        作用
        npm start
        运行 package.json 中的 start 脚本
        npm test
        运行测试脚本
        npm run build
        运行自定义脚本(如 build

        (5) 发布包

        命令
        作用
        npm login
        登录 npm 账号
        npm publish
        发布包到 npm 仓库
        npm version patch
        更新版本号(patch/minor/major

        2.4. npm的工作流

        (1) 初始化项目

        (2) 安装依赖

        (3) 运行项目

        (4) 发布包


        2.5. npm的优缺点

        ✅ 优点

        1. Node.js 默认支持:无需额外安装。
        1. 庞大的生态系统:超过 200 万个包(截至 2023 年)。
        1. 版本控制package-lock.json 确保依赖一致性。
        1. 脚本管理:方便定义和运行自定义任务。

        ❌ 缺点

        1. 依赖嵌套问题(早期版本):node_modules 可能非常庞大。
        1. 安装速度较慢(相比 Yarn/pnpm)。
        1. 全局依赖冲突:多个项目可能依赖不同版本的全局包。
         

        2.6. 最佳实践

        1. 使用 npm ci 代替 npm install(在 CI/CD 环境中确保一致性)。
        1. 定期更新依赖
          1. 避免全局安装:尽量使用 npx 运行工具(如 npx create-react-app)。
          1. 利用 .npmrc 配置:自定义 registry 或代理。
           

          3. YARN详细介绍

          Yarn 是一个由Facebook、Google、Exponent和Tilde共同开发的JavaScript包管理工具,旨在解决npm早期版本中的性能和安全问题。它兼容npm生态系统,但提供了更快的安装速度、更稳定的依赖管理和更好的安全性。

          3.1. Yarn是什么?

          核心特点

          • 快速:并行下载依赖,显著提升安装速度。
          • 可靠:使用 yarn.lock 文件确保依赖版本一致性。
          • 安全:依赖包完整性校验(checksum 验证)。
          • 离线模式:支持从缓存安装,减少网络请求。
          • 工作区(Workspaces):支持多包项目管理(Monorepo)。

          Yarn 1 vs Yarn 2+

          版本
          特点
          Yarn 1 (Classic)
          兼容 npm,使用 node_modules
          Yarn 2+ (Berry)
          引入 Plug'n'Play(PnP),取消 node_modules

          3.2. Yarn的核心概念

          (1) yarn.lock 文件

          • 作用:锁定所有依赖的精确版本,确保不同环境安装相同的依赖树。
          • 对比 npm
            • npm 使用 package-lock.json,Yarn 使用 yarn.lock
            • yarn.lock 采用扁平化结构,减少依赖冲突。

          (2) 依赖解析策略

          • 扁平化依赖(Yarn 1)
            • 将依赖提升到顶层 node_modules,减少重复安装。
            • 可能引发“幽灵依赖”(Phantom Dependencies)问题(即未声明的依赖被误用)。
          • Plug'n'Play(Yarn 2+)
            • 完全移除 node_modules,依赖直接存储在 .yarn/cache
            • 通过 .pnp.cjs 文件解析依赖,提升速度和磁盘效率。

          (3) 缓存机制

          • 全局缓存:下载的包存储在 ~/.yarn/cache,后续安装直接复用。
          • 离线模式yarn install --offline 强制使用缓存。

          (4) 工作区(Workspaces)

          • 用途:管理多个相互依赖的包(Monorepo 场景)。
          • 配置package.json):
            • 命令
               

              3.2. Yarn常用命令

              (1) 初始化项目

              命令
              作用
              yarn init
              创建 package.json
              yarn init -y
              快速初始化(默认配置)

              (2) 安装依赖

              命令
              作用
              yarn install
              安装所有依赖
              yarn add lodash
              安装生产依赖
              yarn add eslint --dev
              安装开发依赖
              yarn global add nodemon
              全局安装

              (3) 更新依赖

              命令
              作用
              yarn upgrade
              更新所有依赖
              yarn upgrade lodash
              更新指定包
              yarn outdated
              检查过时的包

              (4) 运行脚本

              命令
              作用
              yarn start
              运行 start 脚本
              yarn test
              运行测试脚本
              yarn run build
              运行自定义脚本

              (5) 发布包

              命令
              作用
              yarn login
              登录 npm 账号
              yarn publish
              发布包

              (6) 工作区命令

              命令
              作用
              yarn workspaces list
              列出所有工作区
              yarn workspace <pkg> add lodash
              为指定工作区安装依赖

              3.4. Yarn的工作流

              (1) 初始化项目

              (2) 安装依赖

              (3) 运行项目

              (4) 发布包

               

              3.5. Yarn的优缺点

              ✅ 优点

              1. 速度快:并行下载 + 缓存机制。
              1. 稳定性高yarn.lock 确保依赖一致性。
              1. 安全性强:checksum 验证防止篡改。
              1. Monorepo 支持:工作区功能优秀。

              ❌ 缺点

              1. Yarn 2+ 学习成本高:PnP 模式可能引发兼容性问题。
              1. 生态兼容性:某些工具链可能不支持 PnP。
               

              3.6. 最佳实践

              1. 优先使用 yarn.lock:提交到版本控制以确保一致性。
              1. 利用工作区:适合多包项目(如 React + 组件库)。
              1. 谨慎升级 Yarn 2+:评估工具链兼容性后再迁移。
              • Yarn 是 npm 的高性能替代方案,尤其适合大型项目。
              • Yarn 1 适合传统项目,Yarn 2+ 适合追求极致效率的开发者。
              • 核心优势:速度稳定性Monorepo 支持
               

              4. PNMP详细介绍

              pnpm(Performant npm)是一个快速、高效、节省磁盘空间的 JavaScript 包管理器,旨在解决 npm 和 Yarn 在依赖管理上的性能问题。它采用独特的硬链接 + 符号链接机制,大幅提升安装速度并减少磁盘占用。

              4.1. pnpm的核心特点

              • 🚀 极快的安装速度:并行下载 + 依赖复用,比 npm/Yarn 快 2-3 倍。
              • 💾 节省磁盘空间:所有依赖集中存储在全局存储(~/.pnpm-store),通过硬链接引用。
              • 🔒 严格的依赖隔离node_modules 中只包含显式声明的依赖,避免“幽灵依赖”。
              • 📦 兼容 npm/Yarn:支持 package.jsonworkspaces 和大多数 CLI 命令。
              • 🌍 支持 Monorepo:原生优化多包项目管理。
               

              4.2.pnpm的核心机制

              (1) 硬链接(Hard Links) + 符号链接(Symlinks)

              • 全局存储:所有下载的包存储在 ~/.pnpm-store(跨项目共享)。
              • 硬链接引用:每个项目的 node_modules 中的依赖是全局存储的硬链接(非副本),避免重复占用磁盘。
              • 符号链接组织
                • 直接依赖通过符号链接映射到 node_modules/.pnpm
                • 依赖的依赖(子依赖)被提升到 .pnpm 目录,避免嵌套。
              目录结构示例

              (2) 依赖隔离(Strictness)

              • 无幽灵依赖:只有 package.json 中显式声明的依赖才能被访问。
              • 解决依赖冲突:不同版本的同一包可以共存(如 lodash@4lodash@5)。

              (3) 缓存与离线模式

              • 全局缓存:下载的包永久存储在 ~/.pnpm-store(可配置位置)。
              • 离线安装pnpm install --offline 直接使用缓存。
               

              4.3.pnpm常用命令

              (1) 初始化与安装

              命令
              作用
              pnpm init
              创建 package.json
              pnpm install
              安装所有依赖
              pnpm add lodash
              安装生产依赖
              pnpm add eslint -D
              安装开发依赖
              pnpm add -g pnpm
              全局安装 pnpm 自身

              (2) 运行脚本

              命令
              作用
              pnpm start
              运行 start 脚本
              pnpm test
              运行测试脚本
              pnpm run build
              运行自定义脚本

              (3) 依赖管理

              命令
              作用
              pnpm update
              更新所有依赖
              pnpm update lodash
              更新指定包
              pnpm remove lodash
              卸载包
              pnpm outdated
              检查过时的包

              (4) Monorepo 支持

              命令
              作用
              pnpm add -w lodash
              为整个工作区安装依赖
              pnpm --filter <package> add lodash
              为指定子包安装依赖
              pnpm -r run build
              在所有子包中运行 build 脚本

              4.4.pnpm的工作流

              (1) 初始化项目

              (2) 安装依赖

              (3) 运行项目

              (4) 发布包

              4.5. pnpm的优缺点

              ✅ 优点

              1. 极快的安装速度:依赖复用 + 并行下载。
              1. 节省磁盘空间:全局存储 + 硬链接(相同包只存一份)。
              1. 依赖隔离严格:避免“幽灵依赖”问题。
              1. 兼容 npm/Yarn:无缝迁移现有项目。
              1. 优秀的 Monorepo 支持:比 Yarn Workspaces 更高效。

              ❌ 缺点

              1. 生态兼容性:少数工具可能不兼容 pnpm 的 node_modules 结构(如某些 Webpack 插件)。
              1. 调试复杂性:符号链接可能导致调试时路径显示异常(可通过 -shamefully-hoist 临时提升依赖)。

              4.6. 最佳实践

              1. 迁移现有项目
                1. 处理兼容性问题
                    • 使用 -shamefully-hoist 临时提升依赖:
                      • .npmrc 中配置:
                    1. 优化 Monorepo
                        • 使用 pnpm-workspace.yaml 定义工作区:
                      总之,pnpm适合:追求极致性能、磁盘空间敏感、严格依赖管理的项目。
                      • 推荐场景
                        • 大型项目或 Monorepo。
                        • 开发环境磁盘空间有限(如笔记本)。
                        • 需要避免依赖冲突的团队协作。
                      示例:
                       

                      5. NPX详细介绍

                      npx(Node Package Execute)是 npm(Node Package Manager)5.2.0 版本及更高版本中内置的一个工具,用于临时执行npm包中的命令,而无需全局或本地安装它们。它的设计目标是简化Node.js生态系统中CLI(命令行工具)的使用方式。

                      5.1. npx的核心功能

                      (1) 直接运行本地已安装的包

                      如果某个包已经安装在项目的 node_modules/.bin 目录下,npx 可以直接运行它,而无需手动输入完整路径:
                      等价于:

                      (2) 临时下载并运行远程包

                      如果包未安装,npx 会自动从 npm 仓库下载它,执行后默认删除(除非指定 --no-cleanup):
                      • 这里 create-react-app 不会被全局安装,而是临时下载并运行。

                      (3) 运行不同版本的包

                      可以指定版本号运行某个包,而不影响全局或本地环境:

                      (4) 执行二进制脚本

                      可以直接运行 package.jsonbin 字段定义的命令:
                      http-server 是一个简单的 HTTP 服务器工具)
                       

                      5.2. npx的工作原理

                      (1) 查找顺序

                      1. 检查本地 node_modules/.bin
                          • 如果项目依赖中包含该命令(如 eslintwebpack),npx 会直接运行本地版本。
                      1. 检查全局安装的包
                          • 如果本地没有,但该包已全局安装(如 npm install -g create-react-app),npx 会运行全局版本。
                      1. 临时下载并执行
                          • 如果本地和全局都没有,npx 会从 npm 下载最新版本,执行后删除(默认行为)。

                      (2) 缓存机制

                      • 下载的包会存储在 npm 的全局缓存目录(如 ~/.npm/_npx),后续运行相同命令时可能会复用缓存以提高速度。
                      • 不会npm install -g 那样持久化到全局 node_modules

                      5.3. npx的常见用途

                      (1) 运行脚手架工具

                      避免全局安装 create-react-appvitenext 等工具:

                      (2) 测试不同版本的包

                      (3) 执行一次性命令

                      (4) 运行 npm 脚本

                      如果 package.json 中有脚本:
                      可以直接用 npx 运行:
                      (相当于 npm run start

                      5.4. npx的常用选项

                      选项
                      说明
                      --no-install
                      强制使用本地或全局已安装的包,不下载
                      --ignore-existing
                      忽略本地/全局已安装的包,强制下载最新版
                      -p, --package
                      指定要运行的包(可多个)
                      -c
                      在同一个子进程中执行多个命令
                      --quiet
                      减少日志输出
                      示例:

                      5.5. 为什么推荐使用npx?

                      避免全局污染:减少全局安装的包数量,防止版本冲突。
                      灵活性:可以轻松测试不同版本的包。
                      便捷性:无需手动安装即可运行 CLI 工具。
                      安全性:临时下载的包不会长期驻留系统。
                       
                      总之npx是npm提供的一个便捷工具,用于临时执行npm包。它不会全局安装包,而是按需下载并运行,适合脚手架、一次性命令和测试不同版本。相比 npm install -g,它更安全、灵活,是现代 Node.js 开发的推荐做法。示例:
                       
                       
                    2. 部署
                    3. 运维
                    4. 数据库迁移工具——Alembic如何将已经开发好的fastapi应用部署到生产环境
                      Loading...
                      目录
                      0%