包管理器深度解析:npm / yarn / pnpm 实战指南
前言
在现代前端工程化体系中,包管理器是整个依赖生态的基石。从 npm install 到 pnpm add,每一次包管理器的选择都在悄然影响着项目的安装速度、磁盘占用和协作体验。本文档将深入剖析三大主流包管理器的核心差异,并提供生产环境级别的最佳实践。
技术概述与定位
包管理器在现代前端生态中的角色
包管理器是现代前端开发不可或缺的核心工具,它解决了以下关键问题:
依赖管理:自动化下载、安装、更新和卸载项目依赖。
版本控制:确保团队成员使用相同版本的依赖包。
锁文件机制:保证在不同环境下构建结果的一致性。
发布管理:简化包发布到 npm registry 的流程。
JavaScript 包管理器发展史
npm (2010) → Bower (2011) → Component (2012) → Browserify (2013)
↓ ↓
Yarn (2016) Webpack (2014)
↓ ↓
npm 5+ (2017) ←─────────────── 整合时代 (2016-2019)
↓
pnpm (2017) → Turbo (2020) → pnpm 8+ (2023)
三大主流包管理器定位对比
| 包管理器 | 创建时间 | 创建者 | 核心优势 | 定位 |
|---|---|---|---|---|
| npm | 2010 | Isaac Z. Schlueter | 最大生态、兼容性最好 | 企业级标准 |
| yarn | 2016 | 离线缓存、并行安装 | 大型团队协作 | |
| pnpm | 2017 | Zoltan Kochan | 极速、节省磁盘 | 现代高效开发 |
技术选型建议
选择 npm 的场景:
- 需要最大兼容性
- 团队对现有工具有依赖
- 企业环境有特殊配置要求
选择 yarn 的场景:
- 大型团队协作项目
- 需要稳定的离线能力
- 已经习惯 yarn 工作流
选择 pnpm 的场景:
- 新项目快速启动
- Monorepo 大型项目
- 对磁盘空间敏感
- 追求极致安装速度
包管理器的核心价值
在现代前端开发中,包管理器已经不仅仅是一个安装工具,而是整个开发生态系统的核心枢纽:
依赖解析:现代包管理器不仅仅是简单地下载和安装包,还需要处理复杂的依赖解析、版本冲突、循环依赖等问题。pnpm 的严格依赖隔离机制能够提前发现潜在的依赖问题,而 npm 和 yarn 则通过扁平化结构提供了更大的灵活性。
锁文件机制:锁文件是保证团队协作和构建一致性的关键。不同的锁文件格式反映了各自的设计哲学:npm 的 package-lock.json 采用 JSON 格式,易于程序化处理;yarn 的 yarn.lock 采用 YAML 格式,可读性更强;pnpm 的 pnpm-lock.yaml 包含了 workspace 的完整信息。
性能优化:安装速度直接影响开发体验和 CI/CD 效率。根据 benchmark 数据,pnpm 在大多数场景下比 npm 快 2-3 倍,比 yarn 快 1.5-2 倍。这种性能优势在大型项目中尤为明显。
完整安装与配置
npm 安装与配置
安装与升级
# 安装 Node.js(npm 随 Node.js 一起安装)
# 推荐使用 nvm 管理 Node.js 版本
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# 验证安装
nvm --version
# 安装特定版本 Node.js
nvm install 20
nvm install --lts # 安装最新 LTS 版本
# 切换 Node.js 版本
nvm use 20
nvm alias default 20 # 设置默认版本
# 升级 npm
npm install -g npm@latest
# 验证版本
npm --version # 10.x.x
node --version # 20.x.xnpm 配置文件 (.npmrc)
# ===== 基础配置 =====
# 设置 npm registry
registry=https://registry.npmjs.org/
# 使用国内镜像(可选)
registry=https://registry.npmmirror.com
# 设置包缓存目录
cache=~/.npm
# 设置临时目录
tmp=/tmp/npm
# ===== 用户信息 =====
# 登录 npm 账户
npm adduser
npm login
# 查看当前用户
npm whoami
# ===== 安装配置 =====
# 安装时保存到 dependencies
save=true
# 安装时保存到 devDependencies
save-dev=true
# 安装时保存到 optionalDependencies
save-optional=true
# 安装时添加精确版本号
save-exact=true
# 安装时包含 peer dependencies
legacy-peer-deps=true
# 不安装 peer dependencies
legacy-peer-deps=false
# ===== 其他配置 =====
# 启用颜色输出
color=true
# 不显示进度条
progress=false
# 显示 npm 输出
loglevel=info
# 启用审计
audit=true
# 执行审计后继续
audit-level=lowyarn 安装与配置
安装与升级
# 使用 npm 安装
npm install -g yarn
# 使用 Corepack 安装(Node.js 16.10+ 内置)
corepack enable
corepack prepare yarn@stable --activate
# 升级 yarn
yarn set version stable
# 验证安装
yarn --version # 4.x.xyarn 配置文件
# ===== .yarnrc 文件 =====
# 设置 registry
registry "https://registry.npmjs.org/"
# 启用离线缓存
enableOfflineCache true
# 设置缓存目录
cacheFolder ".yarn/cache"
# 启用压缩
compressionLevel 9
# 启用全局缓存
enableGlobalCache true
# 离线模式
yarn_offline_mirror "./.yarn-mirrors"
# ===== .yarnrc.yml 文件(Yarn Berry)=====
# Yarn Berry 配置文件
packageExtensions:
"@types/react@*":
dependencies:
react: "*"
# 插件配置
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-exec.cjs
spec: "https://yarnpkg.com/plugin-exec"
# 设置 nodeLinker
nodeLinker: node-modules
# 或使用 PnP(Plug'n'Play)
nodeLinker: pnppnpm 安装与配置
安装与升级
# 使用 npm 安装
npm install -g pnpm
# 使用 Corepack 安装(Node.js 16.10+)
corepack enable
corepack prepare pnpm@stable --activate
# 使用安装脚本
curl -fsSL https://get.pnpm.io/install.sh | sh -
# 升级 pnpm
pnpm add -g pnpm@latest
# 验证安装
pnpm --version # 9.x.xpnpm 配置文件
# ===== .npmrc 文件 =====
# 设置 registry
registry=https://registry.npmjs.org/
# 使用国内镜像
registry=https://registry.npmmirror.com
# 启用 shamefully-hoist(提升 node_modules)
shamefully-hoist=true
# 启用 public-hoist-pattern
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
public-hoist-pattern[]=*stylelint*
# 启用自动安装 peer dependencies
auto-install-peers=true
# 严格 peer dependencies 检查
strict-peer-dependencies=false
# ===== pnpm-workspace.yaml =====
packages:
- 'packages/*'
- 'apps/*'
- 'tools/*'
# 排除特定目录
- '!**/test/**'
- '!**/__tests__/**'
- '!**/node_modules/**'全局配置示例
# ===== 创建项目目录 =====
mkdir my-project && cd my-project
# ===== 初始化项目 =====
npm init -y
# 或带参数初始化
npm init -y \
--name "@scope/project-name" \
--version "1.0.0" \
--description "项目描述" \
--author "Your Name <email@example.com>" \
--license "MIT"
# ===== 创建 .gitignore =====
cat > .gitignore << 'EOF'
node_modules/
dist/
build/
.env
.env.local
*.log
.DS_Store
coverage/
.cache/
.vscode/
.idea/
EOF
# ===== 初始化 git =====
git init
git add .
git commit -m "Initial commit"企业环境配置
对于企业环境,通常需要额外的配置来满足安全和管理需求:
# ===== 企业 .npmrc 配置 =====
# 私有 registry
registry=https://npm.my-company.com
@my-scope:registry=https://npm.my-company.com
# 认证令牌
# //npm.my-company.com/:_authToken=${NPM_TOKEN}
# 代理设置
proxy=http://proxy.my-company.com:8080
https-proxy=http://proxy.my-company.com:8080
# 安全设置
engine-strict=true
# 审计配置
audit=true
audit-level=high
# 性能优化
fetch-retries=5
fetch-retry-mintimeout=20000
fetch-retry-maxtimeout=120000核心概念详解
核心对比:安装速度、磁盘占用与 Lockfile
1.1 架构差异决定性能上限
三大包管理器的底层架构存在本质区别:
| 特性 | npm | yarn | pnpm |
|---|---|---|---|
| 存储方式 | 扁平化 node_modules | 扁平化 node_modules | 内容寻址存储 (CAS) |
| 依赖复用 | 同一包多版本共存 | 同一包多版本共存 | 硬链接同一版本包 |
| 安装速度 | 中等 | 中等 | 最快 (并行+硬链接) |
| 磁盘占用 | 最高 | 高 | 最低 (可节省 50-90%) |
| Lockfile 格式 | JSON | YAML | YAML |
npm 的问题:扁平化地狱
npm 3 引入的扁平化 node_modules 解决了路径过深问题,但带来了新的困扰:
project/
└── node_modules/
├── lodash/ # A 依赖的 4.17.20
│ └── package.json
│
└── @scope/
└── pkg/
└── node_modules/
└── lodash/ # B 依赖的 4.17.21,重复安装!
└── package.json
# 问题:
# 1. 磁盘空间浪费
# 2. 依赖解析不一致
# 3. npm dedupe 效果有限
# 4. 依赖遮蔽可能导致意外行为
pnpm 的解决方案:硬链接 + 内容寻址
pnpm 使用 Content Addressable Storage (CAS) 架构:
~/.pnpm-store/ # 全局 Store(只存一份)
└── content-addressable-store/
└── sha512/
└── a3/
└── .../ # 包的校验和路径
projects/
├── project-a/
│ └── node_modules/
│ └── .pnpm/
│ └── lodash@4.17.21/
│ └── node_modules/
│ └── lodash -> 硬链接到 Store
│
└── project-b/
└── node_modules/
└── .pnpm/
└── lodash@4.17.21/
└── node_modules/
└── lodash -> 同一个硬链接!
# 优势:
# 1. 同一版本的包只存一份
# 2. 跨项目复用
# 3. 节省 50-90% 磁盘空间
1.2 安装速度基准测试
# ===== 清理测试环境 =====
rm -rf node_modules package-lock.json pnpm-lock.yaml yarn.lock
# ===== 冷启动测试(无缓存)=====
time npm install # 典型时间: 45-90s
time yarn install # 典型时间: 35-80s
time pnpm install # 典型时间: 15-40s
# ===== 增量安装测试(有缓存)=====
time npm install # 典型时间: 10-20s
time yarn install # 典型时间: 5-15s
time pnpm install # 典型时间: 2-5spnpm 极速的原因:
- 并行下载:使用 Promise.all 并发下载多个包
- 硬链接复用:已存在的包直接硬链接,无需重新下载
- 跳过重复解析:CAS 直接定位,无需递归解析依赖树
- 全局 Store:所有项目共享同一个 Store
1.3 Lockfile 对比
npm 的 package-lock.json
{
"name": "my-project",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "my-project",
"version": "1.0.0"
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/--4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/@babel/core": {
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz",
"integrity": "sha512-..."
}
}
}特点:
- 包含完整的依赖树信息
npm ci严格按 lockfile 安装- 不包含可选依赖的完整信息
- lockfileVersion 3 支持目录嵌套结构
yarn 的 yarn.lock
lodash@4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
"@babel/core@npm:^7.23.0":
version "7.23.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.0.tgz"
integrity sha512-...
dependencies:
"@babel/code-frame" "^7.22.13"
"@babel/generator" "^7.23.0"特点:
- Yarn 1 采用 YAML 格式,语义更清晰
- Yarn Berry (Berry/PnP) 使用
.yarnrc.yml - 支持 plugins 扩展
- workspace 信息完整
pnpm 的 pnpm-lock.yaml
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
specifiers:
lodash: ^4.17.21
typescript: ^5.0.0
dependencies:
lodash: 4.17.21
devDependencies:
typescript: 5.3.3
packages/my-lib:
specifiers:
react: ^18.0.0
dependencies:
react: 18.2.0
packages:
/lodash/4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
engines: {node: '>=4'}
dev: false
optional: false
/@babel/code-frame/7.22.13:
resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9KsX9f7}
engines: {node: '>=6.9.0'}
dev: false
optional: false
dependencies:
'@types/babel__traverse': 7.20.1特点:
- 包含 workspace 完整信息
- 支持
shamefully-hoist兼容模式 - 严格遵循 semver 规范
- 自动安装 peer dependencies
npm Scripts 高级用法
2.1 生命周期脚本
npm 提供了完整的生命周期钩子:
{
"name": "my-package",
"version": "1.0.0",
"scripts": {
"prepublishOnly": "npm test", // 发布前运行
"preversion": "npm test", // 版本更新前运行
"version": "git add -A", // 版本号更新后运行
"postversion": "git push && git push --tags", // 发布后运行
"preinstall": "node scripts/check-node-version.js", // 安装前
"postinstall": "husky install", // 安装后
"preuninstall": "echo 'Uninstalling...'", // 卸载前
"postuninstall": "echo 'Uninstall complete'", // 卸载后
"pretest": "echo 'Running tests...'", // 测试前
"posttest": "echo 'Tests complete'", // 测试后
"prestart": "echo 'Starting...'", // 启动前
"poststart": "echo 'Server started'", // 启动后
"prestop": "echo 'Stopping...'", // 停止前
"poststop": "echo 'Stopped'", // 停止后
"prebuild": "echo 'Building...'", // 构建前
"postbuild": "echo 'Build complete'" // 构建后
}
}执行顺序:当运行 npm version 1.0.0 时:
preversion→ 运行测试- 更新
package.json版本号 version→ git add -Apostversion→ git push
2.2 跨平台兼容
使用 cross-env 处理环境变量
{
"scripts": {
"dev": "vite",
"build": "vite build",
"build:dev": "cross-env NODE_ENV=development vite",
"build:prod": "cross-env NODE_ENV=production vite build",
"build:staging": "cross-env NODE_ENV=staging vite build"
}
}使用 npm-run-all 并行/串行执行
{
"scripts": {
"dev": "npm-run-all --parallel dev:client dev:server",
"build": "npm-run-all --sequential clean build:client build:server",
"lint": "npm-run-all --parallel lint:js lint:css lint:types",
"test": "npm-run-all --parallel test:unit test:e2e"
}
}使用 concurrently 同时运行多个进程
{
"scripts": {
"dev": "concurrently \"npm:dev:server\" \"npm:dev:client\" \"npm:dev:docs\"",
"dev:server": "nodemon server/index.js",
"dev:client": "vite --port 3000",
"dev:docs": "vitepress dev docs"
}
}使用 rimraf 跨平台删除
{
"scripts": {
"clean": "rimraf dist coverage node_modules",
"reinstall": "rimraf node_modules && npm install"
}
}2.3 条件脚本 (npm 8.3+)
现代 npm 支持基于条件的脚本选择:
{
"scripts": {
"dev": "vite",
"dev:win": "vite.exe",
"build": "vite build",
"build:win": "vite.exe build"
}
}# Unix 系统执行
npm run dev
# Windows 系统自动执行
npm run dev:win2.4 脚本参数传递
# 传递参数给底层命令(使用 -- 分隔)
npm run build -- --mode production --minify
# 使用 npm_config_* 访问配置
# package.json
{
"scripts": {
"build": "vite build --mode $npm_config_mode"
}
}
# 执行时传入
npm run build --config_mode=production
# 环境变量方式
{
"scripts": {
"build": "NODE_ENV=production vite build"
}
}
# Windows 兼容
npm install -D cross-env
{
"scripts": {
"build": "cross-env NODE_ENV=production vite build"
}
}package.json 最佳实践
3.1 exports 字段:精确控制导出
{
"name": "my-awesome-lib",
"version": "1.0.0",
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.mjs"
},
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/index.cjs"
},
"browser": "./dist/index.browser.js"
},
"./utils": {
"types": "./utils/index.d.ts",
"import": "./utils/index.mjs",
"require": "./utils/index.cjs"
},
"./package.json": "./package.json"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
]
}exports 的优势:
- 替代
main/module/types,提供更精确的控制 - 支持条件导出(CJS/ESM/browser)
- 可以隐藏内部模块
- Node.js 12.16+ 支持
3.2 sideEffects 字段:Tree Shaking 优化
// 声明全部为纯函数(都可 tree-shaking)
"sideEffects": false
// 只标记有副作用的文件
"sideEffects": [
"dist/styles.css",
"src/polyfills.js",
"src/effects/analytics.ts"
]
// 空数组 = 无副作用
"sideEffects": []Tree Shaking 工作原理:
// src/utils.js
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;
// src/side-effect.js
import { createAnalytics } from './analytics';
createAnalytics(); // 副作用
// package.json
{
"sideEffects": ["./src/side-effect.js"]
}
// 结果:build 时只打包使用的代码
// add 和 multiply 如果没被 import 就不会被打包
// 但 side-effect.js 一定会被打包3.3 engines 字段:环境约束
{
"engines": {
"node": ">=18.0.0",
"npm": ">=9.0.0",
"pnpm": ">=8.0.0"
}
}注意:engines 默认不强制执行,需配合 .npmrc:
# .npmrc
engine-strict=truepnpm 强制执行:
# pnpm 默认强制执行 engines
engine-strict=true3.4 files 字段:发布控制
{
"files": [
"dist",
"types",
"!dist/**/*.map",
"README.md",
"LICENSE"
]
}规则说明:
dist- 包含构建输出types- 包含 TypeScript 类型定义!dist/**/*.map- 排除 source mapsREADME.md- 包含 READMELICENSE- 包含许可证
发布时自动排除:
node_modules(自动排除).gitignore中的文件files字段白名单之外的文件
3.5 publishConfig:发布特定配置
{
"name": "@my-org/my-lib",
"publishConfig": {
"registry": "https://npm.my-org.com",
"access": "restricted",
"tag": "beta",
"directory": "dist"
}
}3.6 funding 字段:赞助信息
{
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/my-project"
}
}
// 或者多个赞助选项
{
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/username"
},
{
"type": "opencollective",
"url": "https://opencollective.com/my-project"
}
]
}Workspace Monorepo 配置
4.1 npm Workspace
// 根 package.json
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*",
"tools/*"
],
"scripts": {
"dev": "npm run dev --workspace=@my/app",
"build": "turbo run build",
"test": "turbo run test",
"clean": "turbo run clean",
"lint": "turbo run lint"
}
}4.2 pnpm Workspace
# pnpm-workspace.yaml
packages:
- 'packages/*'
- 'apps/*'
- 'tools/*'
# 排除测试目录
- '!packages/**/test/**'
- '!packages/**/node_modules/**'pnpm workspace 优势:
- 自动创建
.pnpm虚拟存储 - 支持 workspace 协议引用本地包
- 更严格的依赖隔离
// packages/my-lib/package.json
{
"name": "@my/shared-ui",
"version": "1.0.0",
"dependencies": {
"@my/utils": "workspace:*", // 始终指向本地最新
"@my/utils": "workspace:^1.0.0", // 匹配 semver 范围
"@my/utils": "workspace:~1.0.0" // 匹配补丁版本
}
}4.3 yarn Workspace
// 根 package.json
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
],
"install": {
"hoistingLimits": "dependencies"
}
}Yarn Berry PnP 模式:
# .yarnrc.yml
nodeLinker: pnp
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"4.4 完整 Monorepo 结构示例
my-monorepo/
├── package.json # 根 workspace
├── pnpm-workspace.yaml # pnpm workspace 配置
├── turbo.json # Turborepo 配置
├── .npmrc # npm/pnpm 配置
├── .nvmrc # Node.js 版本
├── .editorconfig # 编辑器配置
│
├── apps/
│ ├── web/ # 主 Web 应用
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ ├── vite.config.ts
│ │ └── src/
│ │ ├── App.tsx
│ │ ├── main.tsx
│ │ └── components/
│ │
│ ├── admin/ # 管理后台
│ │ ├── package.json
│ │ └── src/
│ │
│ └── docs/ # 文档站点
│ ├── package.json
│ └── docs/
│
├── packages/
│ ├── shared-ui/ # 共享 UI 组件库
│ │ ├── package.json
│ │ ├── tsconfig.json
│ │ ├── src/
│ │ │ ├── Button/
│ │ │ ├── Card/
│ │ │ └── Modal/
│ │ └── dist/
│ │
│ ├── shared-utils/ # 共享工具库
│ │ ├── package.json
│ │ └── src/
│ │ ├── format.ts
│ │ ├── validate.ts
│ │ └── storage.ts
│ │
│ ├── shared-types/ # 共享类型定义
│ │ ├── package.json
│ │ └── index.ts
│ │
│ └── shared-constants/ # 共享常量
│ ├── package.json
│ └── src/
│ ├── api.ts
│ └── config.ts
│
└── tools/
├── eslint-config/ # 共享 ESLint 配置
│ ├── package.json
│ └── index.js
│
├── tsconfig/ # 共享 TypeScript 配置
│ ├── base.json
│ ├── react.json
│ └── nextjs.json
│
└── vite-config/ # 共享 Vite 配置
├── package.json
└── base.ts
常用命令与操作
npm 常用命令
# ===== 安装命令 =====
npm install # 安装所有依赖
npm install <package> # 安装包
npm install <package>@1.0.0 # 安装指定版本
npm install <package>@latest # 安装最新版本
npm install -D <package> # 安装到 devDependencies
npm install -O <package> # 安装到 optionalDependencies
npm install -g <package> # 全局安装
# ===== 包信息 =====
npm view <package> # 查看包信息
npm info <package> # 同 view
npm show <package> # 同 view
npm outdated # 检查过时包
npm ls # 列出已安装包
npm ls <package> # 查看特定包
# ===== 更新命令 =====
npm update # 更新所有包
npm update <package> # 更新特定包
npm update -g # 更新全局包
npx npm-check-updates # 检查可更新的包
# ===== 卸载命令 =====
npm uninstall <package> # 卸载包
npm remove <package> # 同 uninstall
npm rm <package> # 同 uninstall
npm uninstall -D <package> # 卸载 devDependencies
npm uninstall -g <package> # 卸载全局包
# ===== 缓存管理 =====
npm cache clean --force # 清理缓存
npm cache verify # 验证缓存
# ===== 发布命令 =====
npm publish # 发布包
npm publish --access public # 发布公开包
npm publish --tag beta # 发布到 beta 标签
npm unpublish <package> # 取消发布
npm deprecate <package> # 弃用包
# ===== 其他命令 =====
npm init # 初始化项目
npm pack # 打包为 .tgz
npm login # 登录 npm
npm logout # 登出
npm whoami # 查看当前用户
npm explore <package> # 查看包目录
npm link # 创建全局链接
npm bin # 查看 bin 目录yarn 常用命令
# ===== 安装命令 =====
yarn install # 安装所有依赖
yarn add <package> # 添加包
yarn add <package>@1.0.0 # 添加指定版本
yarn add -D <package> # 添加到 devDependencies
yarn add -P <package> # 添加 peerDependencies
yarn add -g <package> # 全局安装
# ===== 包信息 =====
yarn info <package> # 查看包信息
yarn list # 列出已安装包
yarn list --pattern <package> # 列出特定包
# ===== 更新命令 =====
yarn upgrade # 更新所有包
yarn upgrade <package> # 更新特定包
yarn upgrade-interactive # 交互式更新
# ===== 卸载命令 =====
yarn remove <package> # 移除包
yarn remove <package> -D # 移除 devDependencies
# ===== 脚本命令 =====
yarn run <script> # 运行脚本
yarn dev # 运行开发脚本
yarn build # 运行构建脚本
yarn test # 运行测试
# ===== 其他命令 =====
yarn init # 初始化项目
yarn init -y # 快速初始化
yarn why <package> # 查看包依赖原因
yarn disambiguation # 包解析
yarn policies set-version # 设置 Yarn 版本pnpm 常用命令
# ===== 安装命令 =====
pnpm install # 安装所有依赖
pnpm add <package> # 添加包
pnpm add <package>@1.0.0 # 添加指定版本
pnpm add -D <package> # 添加到 devDependencies
pnpm add -w <package> # 添加到 workspace 根目录
pnpm add -g <package> # 全局安装
# ===== 包信息 =====
pnpm list # 列出已安装包
pnpm list <package> # 查看特定包
pnpm why <package> # 查看包依赖原因
# ===== 更新命令 =====
pnpm update # 更新所有包
pnpm update <package> # 更新特定包
pnpm up # 同 update
pnpm up <package> # 更新特定包
# ===== 卸载命令 =====
pnpm remove <package> # 移除包
pnpm rm <package> # 同 remove
pnpm uninstall <package> # 同 remove
# ===== 其他命令 =====
pnpm import # 从 package-lock.json 导入
pnpm store status # 查看 store 状态
pnpm store prune # 清理未使用的包
pnpm env use # 使用特定 Node.js 版本
pnpm init # 初始化项目
pnpm patch # 创建补丁
pnpm patch-commit # 提交补丁
# ===== Workspace 命令 =====
pnpm -r <command> # 在所有 workspace 运行命令
pnpm -r --filter <pkg> <cmd> # 在特定 workspace 运行命令
pnpm --filter <pattern> ... # 过滤 workspace高级配置与技巧
企业级 .npmrc
# ===== .npmrc 企业配置 =====
# ===== Registry 配置 =====
registry=https://registry.npmmirror.com
# 私有 Registry(可选)
# @scope:registry=https://npm.my-company.com
# //npm.my-company.com/:_authToken=${NPM_TOKEN}
# ===== 安装行为 =====
strict-peer-dependencies=false
save-exact=true
legacy-peer-deps=true
prefer-dedupe=true
# ===== 构建优化 =====
omit=dev # 生产环境安装跳过 devDependencies
production=true # 同 omit=dev
# ===== pnpm 特有配置 =====
shamefully-hoist=false
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
public-hoist-pattern[]=*stylelint*
public-hoist-pattern[]=*tailwindcss*
public-hoist-pattern[]=*postcss*
public-hoist-pattern[]=*autoprefixer*
auto-install-peers=true
resolution-mode=highest
# ===== 网络优化 =====
fetch-retries=5
fetch-retry-mintimeout=10000
fetch-retry-maxtimeout=60000
fetch-timeout=300000
# ===== 缓存配置 =====
cache=~/.npm
prefix=~/.npm-globalCI 环境优化
GitHub Actions 配置
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # 或 'pnpm', 'yarn'
- name: Install dependencies
run: pnpm install --frozen-lockfile --prefer-offline
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Type check
run: pnpm run typecheck
- name: Lint
run: pnpm run lint
- name: Test
run: pnpm run test
- name: Build
run: pnpm run build
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/GitLab CI 配置
# .gitlab-ci.yml
stages:
- install
- test
- build
variables:
NPM_CONFIG_PREFIX: "${CI_PROJECT_DIR}/.npm-global"
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .npm/
- node_modules/
install:
stage: install
image: node:20-alpine
script:
- npm ci --prefer-offline
artifacts:
paths:
- node_modules/
test:
stage: test
image: node:20-alpine
script:
- npm run test
- npm run lint
build:
stage: build
image: node:20-alpine
script:
- npm run build
artifacts:
paths:
- dist/Docker 配置
# Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
# 复制 package files
COPY package.json pnpm-lock.yaml ./
# 安装依赖
RUN corepack enable && corepack prepare pnpm@stable --activate
RUN pnpm install --frozen-lockfile --prod
# 复制源代码
COPY . .
# 构建
RUN pnpm run build
# 生产镜像
FROM node:20-alpine AS runner
WORKDIR /app
# 从 builder 复制构建产物
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "dist/index.js"]依赖安全审计
# ===== npm audit =====
npm audit # 审计依赖
npm audit fix # 自动修复
npm audit fix --force # 强制修复
npm audit --json # JSON 格式输出
# ===== yarn audit =====
yarn audit # 审计依赖
# ===== pnpm audit =====
pnpm audit # 审计依赖
pnpm audit --fix # 自动修复
# ===== 安全最佳实践 =====
# 1. 定期更新依赖
npx npm-check-updates -u
pnpm up -r
# 2. 锁定关键依赖版本
{
"resolutions": {
"lodash": "4.17.21"
}
}
# 3. 使用替代包
# - 替换 eval() 使用的包
# - 替换已知漏洞的包性能优化技巧
# ===== 使用 ci 安装(CI 环境推荐)=====
npm ci # 精确按 lockfile 安装
yarn install --frozen-lockfile # 冻结 lockfile
pnpm install --frozen-lockfile # 冻结 lockfile
# ===== 离线模式 =====
npm ci --offline # 离线安装
yarn install --offline # 离线安装
pnpm install --offline # 离线安装
# ===== 使用 prefer-offline 加速 =====
npm install --prefer-offline # 优先使用缓存
pnpm install --prefer-offline # 优先使用缓存
# ===== 减少安装内容 =====
npm install --production # 不安装 devDependencies
npm ci --omit=dev # 同上
pnpm install --prod # 不安装 devDependencies
# ===== 增量安装 =====
pnpm install # pnpm 默认增量安装高级依赖管理技巧
依赖版本范围管理
{
"dependencies": {
"react": "^18.2.0", // ^: 允许次版本和补丁更新
"react-dom": "~18.2.0", // ~: 允许补丁更新
"lodash": ">=4.0.0", // >=: 最小版本限制
"next": "14.x", // x: 匹配任意版本
"preact": "*" // *: 任意版本(不推荐)
}
}依赖覆盖(Overrides)
{
"overrides": {
// 覆盖单个包
"lodash": "4.17.21",
// 覆盖嵌套依赖
"webpack": {
"webpack-bundle-analyzer": "4.9.0"
},
// 使用 $ 前缀引用原始版本
"react": {
"$original": "^18.0.0",
"loose-envify": "^1.1.0"
}
}
}依赖预取和懒加载
# 使用 npm pack 创建离线包
npm pack <package-name>
# pnpm 预取
pnpm add <package> --prefer-offline
# yarn 离线镜像
yarn config set yarn-offline-mirror ./yarn-offline-mirror
yarn install --offline与同类技术对比
详细功能对比表
| 特性 | npm | yarn | pnpm |
|---|---|---|---|
| 安装速度 | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 磁盘效率 | ⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| Lockfile 格式 | JSON | YAML | YAML |
| 离线支持 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| Workspace 支持 | 原生 | 原生 | 原生 |
| Monorepo 体验 | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Node.js 版本要求 | 10+ | 10+ | 14+ |
| peerDependencies | 警告 | 警告 | 严格安装 |
| 幽灵依赖 | 有 | 有 | 无 |
| 全局缓存 | 有 | 有 | 有 |
性能基准测试
# ===== 测试命令 =====
# 项目:create-react-app (约 1400 依赖)
# 环境:MacBook Pro M1, 16GB RAM
# 冷安装(首次安装)
npm ci # ~45-60s
yarn # ~35-50s
pnpm # ~15-25s
# 增量安装(添加一个包)
npm add lodash # ~5-10s
yarn add lodash # ~3-8s
pnpm add lodash # ~1-3s
# 更新所有依赖
npm update # ~30-45s
yarn upgrade # ~20-35s
pnpm update # ~10-20s使用场景对比
| 场景 | 推荐 | 原因 |
|---|---|---|
| 新项目快速启动 | pnpm | 安装速度最快 |
| 大型 Monorepo | pnpm | 严格的依赖隔离 |
| 企业内部项目 | npm/pnpm | 兼容性最好 |
| 开源项目 | 均可 | 根据团队偏好 |
| CI/CD 环境 | pnpm | 速度最快 |
| 遗留项目 | npm | 兼容性最好 |
包管理器选择决策树
开始选择包管理器
│
├─ 项目规模?
│ ├─ 小型(< 50 依赖)→ 任意选择
│ ├─ 中型(50-500 依赖)→ pnpm 或 yarn
│ └─ 大型(> 500 依赖)→ pnpm(必需)
│
├─ 团队技术栈?
│ ├─ 已有 npm 经验 → npm
│ ├─ 已有 yarn 经验 → yarn
│ └─ 新团队 → pnpm(推荐)
│
├─ 是否需要离线开发?
│ ├─ 是 → yarn 或 pnpm
│ └─ 否 → 任意选择
│
└─ Monorepo 项目?
├─ 是 → pnpm(强烈推荐)
└─ 否 → 任意选择
常见问题与解决方案
问题1:peer dependencies 警告
症状:
npm warn ERESOLVE overriding peer dependency
npm warn ERESOLVE peer dependency "react@>=17.0.0" is not satisfied
原因:包声明的 peer dependencies 与实际安装的版本不匹配
解决方案:
# 方法1:忽略 peer dependencies 警告(npm)
npm install --legacy-peer-deps
# 方法2:强制安装 peer dependencies(npm)
npm install --force
# 方法3:配置 .npmrc
echo "legacy-peer-deps=true" >> .npmrc
# 方法4:pnpm 自动安装
# pnpm 默认会安装 peer dependencies
# 如需禁用
echo "auto-install-peers=false" >> .npmrc
# 方法5:使用 overrides
{
"overrides": {
"styled-components": {
"react": "18.2.0",
"react-dom": "18.2.0"
}
}
}问题2:幽灵依赖问题
症状:
// 项目中引用了未声明的包
import _ from 'lodash'; // 未在 package.json 中声明
// 但由于其他包的 node_modules 包含它,代码能正常运行原因:npm/yarn 的扁平化 node_modules 导致
解决方案:
# 使用 pnpm(默认隔离)
npm install -g pnpm
# pnpm 使用严格的虚拟存储
pnpm install
# pnpm 会报错:ERR_PNPM_PEER_DEP_ISSUES问题3:Lockfile 冲突
症状:
error: Your lockfile needs to be updated, but package.json was not.
error: cannot work with "package-lock.json" because the lockfile's version is 2
原因:不同版本的 npm 生成不同格式的 lockfile
解决方案:
# 方法1:从 lockfile 重新安装
npm ci # npm
pnpm import # 从 npm/yarn 导入 pnpm
# 方法2:删除 lockfile 重新生成
rm package-lock.json
npm install
# 方法3:统一团队的工具版本
# package.json
{
"engines": {
"npm": ">=9.0.0"
}
}
# .npmrc
engine-strict=true问题4:安装失败/网络问题
症状:
npm ERR! network timeout
npm ERR! fetch failed
npm ERR! ECONNREFUSED
解决方案:
# 方法1:使用镜像
npm config set registry https://registry.npmmirror.com
# 方法2:使用代理
npm config set proxy http://proxy.example.com:8080
npm config set https-proxy http://proxy.example.com:8080
# 方法3:清理缓存重试
npm cache clean --force
npm install
# 方法4:使用离线缓存
npm install --prefer-offline
# 方法5:增加超时时间
npm config set fetch-timeout 300000
npm config set fetch-retry-mintimeout 10000问题5:磁盘空间不足
症状:
npm ERR! ENOSPC: no space left on device
解决方案:
# 方法1:使用 pnpm(节省空间)
npm install -g pnpm
pnpm import
rm -rf node_modules
pnpm install
# 方法2:清理 npm 缓存
npm cache clean --force
# 方法3:清理 pnpm store
pnpm store status
pnpm store prune
# 方法4:删除 yarn 缓存
yarn cache clean
# 方法5:使用 PNPM_HOME 自定义缓存位置
export PNPM_HOME=/path/to/large/disk/.pnpm问题6:包版本不一致
症状:
Package A requires B@^1.0.0
Package C requires B@^2.0.0
Both B@1.0.0 and B@2.0.0 are installed
原因:不同包依赖同一包的不同主版本
解决方案:
# 使用 npm dedupe
npm dedupe
# 使用 yarn deduplicate
yarn deduplicate
# pnpm 默认自动去重
# 对于主版本冲突,考虑:
# 1. 升级到统一的版本
# 2. 使用 alias 引用不同版本
{
"dependencies": {
"lodash4": "npm:lodash@4",
"lodash3": "npm:lodash@3"
}
}实战项目示例
示例1:企业级 Monorepo 配置
// 根 package.json
{
"name": "enterprise-monorepo",
"version": "1.0.0",
"private": true,
"type": "module",
"workspaces": [
"apps/*",
"packages/*",
"tools/*"
],
"scripts": {
"dev": "turbo run dev",
"build": "turbo run build",
"test": "turbo run test",
"lint": "turbo run lint",
"typecheck": "turbo run typecheck",
"clean": "turbo run clean",
"format": "prettier --write \"**/*.{ts,tsx,json,md}\"",
"prepare": "husky install"
},
"devDependencies": {
"@turbo/test-utils": "workspace:*",
"eslint": "^8.50.0",
"husky": "^8.0.3",
"prettier": "^3.0.3",
"turbo": "^1.11.0",
"typescript": "^5.2.2"
},
"engines": {
"node": ">=18.0.0",
"pnpm": ">=8.0.0"
},
"packageManager": "pnpm@8.10.0"
}# pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
- 'tools/*'
- '!apps/**/test/**'
- '!packages/**/test/**'// apps/web/package.json
{
"name": "@enterprise/web",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest",
"lint": "eslint src",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@enterprise/ui": "workspace:*",
"@enterprise/utils": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.16.0"
},
"devDependencies": {
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@vitejs/plugin-react": "^4.2.0",
"typescript": "^5.2.0",
"vite": "^5.0.0",
"vitest": "^1.0.0"
}
}示例2:库发布配置
// packages/my-lib/package.json
{
"name": "@my-org/my-lib",
"version": "1.0.0",
"description": "一个高性能的 TypeScript 工具库",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./utils": {
"types": "./dist/utils.d.ts",
"import": "./dist/utils.js",
"require": "./dist/utils.cjs"
},
"./package.json": "./package.json"
},
"files": [
"dist"
],
"sideEffects": false,
"scripts": {
"build": "tsup",
"test": "vitest",
"lint": "eslint src",
"typecheck": "tsc --noEmit",
"prepublishOnly": "npm run build && npm run test"
},
"keywords": [
"utils",
"typescript",
"helper"
],
"author": "My Org <dev@my-org.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/my-org/my-lib"
},
"bugs": {
"url": "https://github.com/my-org/my-lib/issues"
},
"peerDependencies": {
"react": ">=16.8.0"
},
"devDependencies": {
"@types/react": "^18.2.0",
"react": "^18.2.0",
"tsup": "^7.2.0",
"typescript": "^5.2.0",
"vitest": "^1.0.0"
},
"engines": {
"node": ">=16.0.0"
}
}附录:常见问题速查
npm/yarn/pnpm 常用命令对照
| 功能 | npm | yarn | pnpm |
|---|---|---|---|
| 安装依赖 | npm install | yarn install | pnpm install |
| 添加包 | npm add | yarn add | pnpm add |
| 添加开发依赖 | npm add -D | yarn add -D | pnpm add -D |
| 移除包 | npm remove | yarn remove | pnpm remove |
| 更新包 | npm update | yarn upgrade | pnpm update |
| 执行脚本 | npm run | yarn <script> | pnpm |
| 清理缓存 | npm cache clean | yarn cache clean | pnpm store prune |
| 锁定版本安装 | npm ci | yarn install —frozen-lockfile | pnpm install —frozen-lockfile |
| 查看依赖树 | npm ls | yarn list | pnpm list |
| 升级到最新 | npm update -g | yarn global upgrade | pnpm update -g |
package.json 字段速查
| 字段 | 说明 | 示例 |
|---|---|---|
| name | 包名称 | ”my-package” |
| version | 版本号 | ”1.0.0” |
| description | 描述 | ”一个有用的包” |
| main | 主入口文件 | ”./dist/index.js” |
| module | ESM 入口 | ”./dist/index.mjs” |
| types | TypeScript 类型 | ”./dist/index.d.ts” |
| exports | 导出配置 | { ”.”: “./dist/index.js” } |
| files | 发布包含文件 | [“dist”] |
| scripts | 脚本命令 | { “build”: “tsc” } |
| dependencies | 生产依赖 | { “react”: “^18.0.0” } |
| devDependencies | 开发依赖 | { “typescript”: “^5.0.0” } |
| peerDependencies | 对等依赖 | { “react”: ”>=16.0.0” } |
| optionalDependencies | 可选依赖 | { “fsevents”: “^2.0.0” } |
| engines | 环境要求 | { “node”: ”>=18.0.0” } |
| sideEffects | 副作用标记 | false |
| repository | 仓库地址 | ”github:user/repo” |
| keywords | 关键词 | [“utils”, “helper”] |
| author | 作者 | ”Name |
| license | 许可证 | ”MIT” |
| funding | 赞助信息 | ”https://…” |
Semver 版本规则
major.minor.patch
1.2.3
│ │ │
│ │ └── Patch: 补丁版本,不影响 API 兼容性
│ └── Minor: 次版本,新增功能,向后兼容
└── Major: 主版本,破坏性变更
| 范围 | 含义 | 示例 |
|---|---|---|
| ^1.2.3 | >=1.2.3 <2.0.0 | 1.x.x 最新 |
| ~1.2.3 | >=1.2.3 <1.3.0 | 1.2.x 最新 |
| >=1.0.0 | >=1.0.0 | 无上限 |
| 1.0.0 - 2.0.0 | >=1.0.0 ⇐2.0.0 | 范围限制 |
| * | 最新版本 | 任意版本 |
| 1.x.x | >=1.0.0 <2.0.0 | 同 ^1.0.0 |
附录:配置文件模板
企业级 .npmrc 模板
# ===== 基础配置 =====
registry=https://registry.npmmirror.com
cache=~/.npm
prefix=~/.npm-global
# ===== 安装配置 =====
save-exact=true
legacy-peer-deps=false
strict-peer-dependencies=false
prefer-dedupe=true
# ===== 构建优化 =====
production=false
omit=dev
# ===== 网络配置 =====
fetch-retries=5
fetch-retry-mintimeout=10000
fetch-retry-maxtimeout=60000
fetch-timeout=300000
# ===== pnpm 配置 =====
shamefully-hoist=false
auto-install-peers=true
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
public-hoist-pattern[]=*stylelint*
public-hoist-pattern[]=*tailwindcss*package.json 生产模板
{
"name": "@scope/my-package",
"version": "1.0.0",
"description": "A well-documented package",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
},
"files": [
"dist"
],
"sideEffects": false,
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"test": "vitest",
"test:coverage": "vitest --coverage",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"typecheck": "tsc --noEmit",
"format": "prettier --write src",
"prepublishOnly": "pnpm run build && pnpm run test"
},
"keywords": [
"typescript",
"utils",
"helpers"
],
"author": "Your Name <email@example.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/scope/my-package"
},
"peerDependencies": {
"react": ">=16.8.0"
},
"devDependencies": {
"typescript": "^5.2.0",
"tsup": "^7.2.0",
"vitest": "^1.0.0",
"@types/node": "^20.0.0",
"eslint": "^8.50.0",
"prettier": "^3.0.0"
},
"engines": {
"node": ">=16.0.0",
"pnpm": ">=8.0.0"
}
}Turborepo 配置模板
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": [
".env"
],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "build/**"],
"cache": true
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {
"dependsOn": ["^build"],
"outputs": []
},
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"cache": true
},
"typecheck": {
"dependsOn": ["^build"],
"cache": true
}
}
}附录:包管理器性能对比数据
安装速度对比(大型项目)
| 包管理器 | 冷启动 | 增量安装 | 锁定安装 | 磁盘占用 |
|---|---|---|---|---|
| npm | 45-60s | 10-20s | 30-45s | ~500MB |
| yarn | 35-50s | 8-15s | 25-40s | ~400MB |
| pnpm | 15-25s | 2-5s | 10-15s | ~100MB |
测试项目规格
# 测试环境
# - 操作系统: macOS 14 (Apple Silicon M3)
# - Node.js: 20.x
# - 网络: 100Mbps
# 测试项目: create-react-app (约 1400 依赖)
# - node_modules: ~32000 文件
# - 依赖树深度: ~5 层
# 测试命令
hyperfine --warmup 3 \
'rm -rf node_modules && npm ci' \
'rm -rf node_modules && yarn install --frozen-lockfile' \
'rm -rf node_modules && pnpm install --frozen-lockfile'依赖解析性能
| 操作 | npm | yarn | pnpm |
|---|---|---|---|
| 解析 100 个包 | ~5s | ~4s | ~1s |
| 解析 500 个包 | ~25s | ~20s | ~5s |
| 解析 1000 个包 | ~60s | ~50s | ~12s |
附录:常见错误码与解决方案
npm 错误码
| 错误码 | 含义 | 解决方案 |
|---|---|---|
| ERESOLVE | 版本冲突 | 使用 --legacy-peer-deps 或调整依赖版本 |
| ENOSPC | 磁盘空间不足 | 清理缓存或删除不必要的依赖 |
| ECONNREFUSED | 网络连接失败 | 检查网络或更换 registry |
| EACCES | 权限不足 | 使用 sudo 或修复 npm 目录权限 |
| ENOENT | 文件不存在 | 重新安装或清理缓存 |
| EBADENGINE | 引擎版本不匹配 | 更新 Node.js 版本 |
| EPEERINVALID | peerDependencies 无效 | 安装缺失的 peer 依赖 |
pnpm 错误码
| 错误码 | 含义 | 解决方案 |
|---|---|---|
| ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND | 未找到 package.json | 在项目目录执行 |
| ERR_PNPM_PEER_DEP_ISSUES | peerDependencies 冲突 | 安装冲突的 peer 依赖 |
| ERR_PNPM_ARTIFACT_NOT_FOUND | Store 中未找到包 | 使用 pnpm store prune 清理 |
| ERR_PNPM_LOCKFILE_MISSING_DEPENDENCY | lockfile 缺少依赖 | 删除 lockfile 重新安装 |
yarn 错误码
| 错误码 | 含义 | 解决方案 |
|---|---|---|
| EACCES | 权限不足 | 修复 yarn 目录权限 |
| EEXIST | 文件已存在 | 清理后重试 |
| ENOENT | 文件不存在 | 重新安装 |
| ECONNRESET | 连接重置 | 检查网络或更换 registry |
附录:高级包管理技巧
多 registry 配置
# .npmrc 多 registry 配置
# 默认 registry
registry=https://registry.npmmirror.com
# 私有包使用私有 registry
@my-org:registry=https://npm.my-company.com
@my-private:registry=https://npm.my-company.com
# 认证配置
# //npm.my-company.com/:_authToken=${MY_ORG_TOKEN}Workspace 依赖管理策略
# 查看 workspace 包依赖关系
pnpm why react
# 检查过时的 workspace 依赖
pnpm up --interactive
# 更新 workspace 依赖到最新
pnpm up -r
# 锁定 workspace 依赖版本
pnpm up "workspace:*"包版本发布工作流
# 1. 更新版本
npm version patch # 补丁版本
npm version minor # 次版本
npm version major # 主版本
# 2. 发布到 npm
npm publish
# 3. 发布到私有 registry
npm publish --registry=https://npm.my-company.com
# 4. 打标签
npm dist-tag add my-package@1.0.0 beta
# 5. 从标签安装
npm install my-package@beta依赖健康度检查清单
## 依赖健康度检查清单
- [ ] 定期运行安全审计
- [ ] 保持依赖更新
- [ ] 使用 lockfile
- [ ] 指定 engines 要求
- [ ] 检查包的活跃度
- [ ] 评估包的依赖大小
- [ ] 使用官方或知名包
- [ ] 避免未维护的包
- [ ] 检查包的类型定义
- [ ] 评估包的包体大小TIP
推荐配置:新项目推荐使用 pnpm + Turborepo,可获得最佳安装速度和构建性能。企业项目建议使用 npm 或 pnpm workspace,保持最大兼容性。