npm 与 yarn 使用技巧
Tips
本教程全面介绍 npm 和 yarn 包管理工具的使用方法,从基础命令到高级应用,适用于 npm 6+/yarn 1.22+ 及更高版本。
1. 包管理工具简介
包管理工具是现代前端开发中不可或缺的组成部分,它们负责管理项目依赖、执行脚本任务和发布包。npm (Node Package Manager) 是 Node.js 默认的包管理器,而 yarn 是由 Facebook 开发的替代方案,两者都提供了丰富的功能来提升开发效率。
1.1 npm 与 yarn 的历史
- npm:2010年随 Node.js 推出,是最早的 JavaScript 包管理工具
- yarn:2016年由 Facebook 推出,旨在解决 npm 早期版本的性能和安全问题
1.2 各工具对比
特性 | npm | yarn | pnpm |
---|---|---|---|
初始发布 | 2010年 | 2016年 | 2017年 |
依赖安装速度 | 中等 | 快 | 非常快 |
并行安装 | npm 5+ 支持 | 原生支持 | 原生支持 |
自动锁文件 | package-lock.json | yarn.lock | pnpm-lock.yaml |
工作区支持 | npm 7+ 支持 | 支持 | 支持 |
存储方式 | 扁平 node_modules | 扁平 node_modules | 内容寻址存储 |
脚本运行 | npm run | yarn run | pnpm run |
2. 基础安装与配置
2.1 安装 npm 和 yarn
npm 安装: npm 随 Node.js 一起安装,无需单独安装:
# 检查版本
npm -v
# 更新 npm
npm install -g npm@latest
yarn 安装:
# 通过 npm 安装 yarn
npm install -g yarn
# Windows 下使用安装包
# 下载: https://classic.yarnpkg.com/latest.msi
# macOS 使用 Homebrew
brew install yarn
# 检查版本
yarn -v
2.2 基本配置
npm 配置:
# 查看配置
npm config list
# 设置配置
npm config set init-author-name "记得晚安(JDWA)"
npm config set init-license "MIT"
# 设置镜像源
npm config set registry https://registry.npmmirror.com
yarn 配置:
# 查看配置
yarn config list
# 设置配置
yarn config set init-author-name "记得晚安(JDWA)"
yarn config set init-license "MIT"
# 设置镜像源
yarn config set registry https://registry.npmmirror.com
2.3 创建新项目
使用 npm 初始化:
mkdir jdwa-npm-demo
cd jdwa-npm-demo
npm init
# 使用默认值
npm init -y
使用 yarn 初始化:
mkdir jdwa-yarn-demo
cd jdwa-yarn-demo
yarn init
# 使用默认值
yarn init -y
3. 依赖管理基础
3.1 添加依赖
npm 添加依赖:
# 添加生产依赖
npm install react react-dom
# 添加开发依赖
npm install --save-dev webpack typescript
# 简写形式
npm i react
npm i -D webpack
yarn 添加依赖:
# 添加生产依赖
yarn add react react-dom
# 添加开发依赖
yarn add --dev webpack typescript
# 简写形式
yarn add webpack -D
3.2 依赖类型
两个工具都支持以下依赖类型:
- dependencies:生产环境依赖
- devDependencies:开发环境依赖
- peerDependencies:同等依赖,需要由使用者安装
- optionalDependencies:可选依赖,安装失败不会导致整体失败
- bundledDependencies:打包依赖,将随包一起发布
3.3 查看与更新
npm 查看与更新:
# 查看过时依赖
npm outdated
# 更新所有依赖
npm update
# 更新特定依赖
npm update react react-dom
yarn 查看与更新:
# 查看过时依赖
yarn outdated
# 更新所有依赖
yarn upgrade
# 更新特定依赖
yarn upgrade react react-dom
3.4 删除依赖
npm 删除依赖:
npm uninstall react-router
# 简写
npm un react-router
npm rm react-router
yarn 删除依赖:
yarn remove react-router
4. 锁文件与版本控制
4.1 锁文件的作用
锁文件确保在不同环境中安装相同版本的依赖:
- npm 使用
package-lock.json
- yarn 使用
yarn.lock
4.2 语义化版本
npm 和 yarn 都使用语义化版本 (Semantic Versioning):
主版本号.次版本号.修订号
- 主版本号:不兼容的 API 修改
- 次版本号:向下兼容的新功能
- 修订号:向下兼容的问题修复
4.3 版本范围语法
符号 | 含义 | 例子 |
---|---|---|
^ | 兼容不更改左侧第一个非零位的更新 | ^1.2.3 = >=1.2.3 <2.0.0 |
~ | 允许修订号更新 | ~1.2.3 = >=1.2.3 <1.3.0 |
>= | 大于等于 | >=1.2.3 |
<= | 小于等于 | <=1.2.3 |
1.2.x | x 位置的任何版本 | 1.2.x = >=1.2.0 <1.3.0 |
* | 任意版本 | * = >=0.0.0 |
latest | 最新版本 | latest |
5. 脚本与任务管理
5.1 定义脚本
在 package.json
文件的 scripts
部分定义脚本:
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"lint": "eslint src/**/*.js",
"format": "prettier --write \"src/**/*.{js,jsx,json,css}\""
}
}
5.2 运行脚本
npm 运行脚本:
# 运行命名脚本
npm run start
npm run build
# start、test、stop 等可以省略 run
npm start
npm test
yarn 运行脚本:
# 运行命名脚本
yarn run start
yarn run build
# 简写形式
yarn start
yarn build
5.3 脚本传参
npm 传递参数:
npm run test -- --watch
# 在 package.json 中使用
{
"scripts": {
"build": "webpack --mode=$NODE_ENV"
}
}
yarn 传递参数:
yarn test --watch
# 在 package.json 中使用
{
"scripts": {
"build": "webpack --mode=$NODE_ENV"
}
}
5.4 复合脚本
依次或并行执行多个脚本:
{
"scripts": {
"clean": "rimraf dist",
"prebuild": "npm run clean",
"build": "webpack --config webpack.config.js",
"postbuild": "echo 'Build complete!'",
"dev": "npm-run-all --parallel start watch",
"start": "nodemon server.js",
"watch": "webpack --watch"
}
}
- 前置/后置钩子:
pre<script>
、post<script>
会自动在主脚本前后执行 - npm-run-all:用于并行或串行执行多个 npm 脚本
6. Workspace 工作区
6.1 配置 Workspaces
npm Workspaces(npm 7+):
{
"name": "jdwa-monorepo",
"private": true,
"workspaces": [
"packages/*"
]
}
yarn Workspaces:
{
"name": "jdwa-monorepo",
"private": true,
"workspaces": [
"packages/*"
]
}
6.2 工作区命令
npm 工作区命令:
# 在特定工作区安装依赖
npm install moment --workspace=packages/app
# 在所有工作区安装依赖
npm install lodash --workspaces
# 在特定工作区运行脚本
npm run build --workspace=packages/app
# 在所有工作区运行脚本
npm run test --workspaces
yarn 工作区命令:
# 在特定工作区安装依赖
yarn workspace packages/app add moment
# 在所有工作区安装依赖
yarn workspaces add lodash
# 在特定工作区运行脚本
yarn workspace packages/app build
# 在所有工作区运行脚本
yarn workspaces run test
6.3 工作区依赖管理
工作区间依赖:
// packages/app/package.json
{
"name": "app",
"dependencies": {
"common": "workspace:*"
}
}
// packages/common/package.json
{
"name": "common",
"version": "1.0.0"
}
7. 高级特性
7.1 npm/yarn 缓存管理
npm 缓存管理:
# 查看缓存目录
npm config get cache
# 清理缓存
npm cache clean --force
# 验证缓存
npm cache verify
yarn 缓存管理:
# 查看缓存目录
yarn cache dir
# 清理缓存
yarn cache clean
# 列出缓存包
yarn cache list
7.2 离线安装
npm 离线安装:
# 启用离线模式
npm install --offline
# 仅使用缓存
npm install --prefer-offline
yarn 离线安装:
# 启用离线模式
yarn install --offline
# 仅使用缓存
yarn install --prefer-offline
7.3 审计与修复安全漏洞
npm 安全审计:
# 审计依赖
npm audit
# 修复漏洞
npm audit fix
# 强制修复(可能更新主版本)
npm audit fix --force
yarn 安全审计:
# 审计依赖
yarn audit
# Yarn 2+ 推荐使用
yarn npm audit
7.4 发布自己的包
npm 发布流程:
# 登录到 npm 仓库
npm login
# 发布包
npm publish
# 发布带标签的版本
npm publish --tag beta
# 更新版本号
npm version patch # 1.0.0 -> 1.0.1
npm version minor # 1.0.0 -> 1.1.0
npm version major # 1.0.0 -> 2.0.0
yarn 发布流程:
# 登录到 npm 仓库
yarn login
# 发布包
yarn publish
# 交互式更新版本并发布
yarn publish --new-version 1.1.0
8. 配置文件详解
8.1 package.json
package.json
是项目的核心配置文件:
{
"name": "jdwa-project",
"version": "1.0.0",
"description": "JDWA 示例项目",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"scripts": {
"start": "node dist/index.js",
"build": "tsc",
"test": "jest"
},
"keywords": ["jdwa", "example"],
"author": "记得晚安(JDWA)",
"license": "MIT",
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"typescript": "^4.9.5",
"jest": "^29.5.0"
},
"engines": {
"node": ">=14.0.0"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11"
]
}
8.2 npm 配置文件
.npmrc:
# 项目级配置
registry=https://registry.npmmirror.com
save-exact=true
fund=false
audit=false
全局 npmrc 位置:
- Windows:
%USERPROFILE%\.npmrc
- macOS/Linux:
~/.npmrc
8.3 yarn 配置文件
.yarnrc:
registry "https://registry.npmmirror.com"
save-exact true
yarn 2+ (.yarnrc.yml):
nodeLinker: node-modules
npmRegistryServer: "https://registry.npmmirror.com"
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"
yarnPath: .yarn/releases/yarn-3.2.3.cjs
9. 性能优化技巧
9.1 加速安装
npm 加速技巧:
# 并行安装
npm set maxsockets 50
# 跳过可选依赖
npm install --no-optional
# 禁用进度条
npm set progress=false
# CI 模式(速度更快)
npm ci
yarn 加速技巧:
# 跳过可选依赖
yarn install --ignore-optional
# 禁用进度条
yarn install --silent
# 离线缓存优化
yarn install --prefer-offline
9.2 CI/CD 环境优化
npm 在 CI 环境中:
# 使用 CI 专用命令(基于 package-lock.json 的精确安装)
npm ci
# 禁用进度条和通知
npm ci --no-progress --no-audit
yarn 在 CI 环境中:
# 纯净安装,不生成 yarn.lock
yarn install --frozen-lockfile
# 禁用进度条和交互
yarn install --non-interactive --silent
9.3 缓存重用策略
优化构建管道:
# 示例 GitHub Actions 工作流配置
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
cache: 'npm' # 或 'yarn'
- name: Install dependencies
run: npm ci # 或 yarn install --frozen-lockfile
10. 常见问题与解决方案
10.1 依赖树冲突
问题:项目依赖不同版本的同一个包 解决方法:
# npm 查看依赖树
npm ls packagename
# 修复重复依赖
npm dedupe
# yarn 查看依赖树
yarn why packagename
# 解决嵌套依赖
yarn deduplicate
10.2 版本锁定
问题:需要精确控制依赖版本 解决方法:
# npm 精确安装版本
npm config set save-exact true
npm install express
# yarn 精确安装版本
yarn add express --exact
10.3 依赖引用本地包
问题:开发时需要引用本地包 解决方法:
# npm 链接本地包
cd ~/projects/my-library
npm link
cd ~/projects/my-app
npm link my-library
# yarn 链接本地包
cd ~/projects/my-library
yarn link
cd ~/projects/my-app
yarn link my-library
10.4 peer 依赖警告
问题:Peer dependency 未满足要求 解决方法:
# npm 7+ 自动安装 peer 依赖
npm install --legacy-peer-deps # 使用旧行为
# yarn 处理 peer 依赖
yarn add @some-scope/package-with-peers
11. 最佳实践
11.1 版本管理策略
- 使用锁文件(package-lock.json/yarn.lock)
- 在 CI/CD 中使用确定性安装(npm ci/yarn --frozen-lockfile)
- 考虑版本范围的影响:
- 生产依赖使用精确版本(
"express": "4.18.2"
) - 或保守更新(
"express": "~4.18.2"
) - 开发工具可用宽松更新(
"eslint": "^8.36.0"
)
- 生产依赖使用精确版本(
11.2 项目结构规范
project/
├── package.json
├── package-lock.json (或 yarn.lock)
├── node_modules/
├── src/
│ └── index.js
├── tests/
├── dist/ (或 build/)
└── .npmrc (或 .yarnrc)
11.3 私有 npm 仓库
使用私有 npm 仓库管理内部包:
- Verdaccio(开源,易于部署)
- Nexus Repository(企业级)
- GitHub Packages(集成 GitHub)
- npm 企业版
# 设置私有仓库
npm config set registry http://company-npm.local
# 设置作用域注册表
npm config set @company:registry http://company-npm.local
11.4 依赖维护流程
- 定期检查更新:
npm outdated
/yarn outdated
- 自动化安全更新:
- 使用 Renovate 或 Dependabot
- 编写良好的测试,确保依赖更新不会破坏功能
- 为自己的包提供清晰的更新日志(CHANGELOG.md)
结语
npm 和 yarn 是现代 JavaScript 开发中不可或缺的工具,掌握这些工具的高级特性和最佳实践,可以显著提高开发效率和项目质量。根据项目需求和团队习惯选择合适的包管理工具,并保持一致的使用方式,是成功项目管理的关键因素之一。