Yarn 由 Facebook 于 2016 年发布,旨在解决当时 npm 的性能和一致性问题。如今 Yarn 分为两个主要版本线:Yarn Classic(1.x)和 Yarn Berry(2.x+,也称 Yarn Modern)。两者在架构和使用方式上有显著差异。
🎯 环境说明:本文基于 Yarn v1.22.x(Classic)和 Yarn v4.x(Berry)编写,Node.js v20.x 环境。
Yarn Classic vs Yarn Berry#
| 特性 | Yarn Classic (1.x) | Yarn Berry (2.x+) |
|---|---|---|
| node_modules | ✅ 传统目录结构 | ❌ 默认禁用 |
| Plug’n’Play | ❌ | ✅ 默认启用 |
| 零安装 | ❌ | ✅ 可提交依赖到 Git |
| 配置文件 | .yarnrc | .yarnrc.yml |
| 锁文件 | yarn.lock (v1) | yarn.lock (v8) |
🤔 如果项目对兼容性要求较高,建议使用 Yarn Classic;追求更激进的优化可尝试 Yarn Berry。
安装 Yarn#
通过 Corepack(推荐)#
Node.js v16.10+ 内置 Corepack,可直接管理 Yarn:
# 启用 Corepack$ corepack enable
# 激活最新稳定版 Yarn$ corepack prepare yarn@stable --activate
# 验证安装$ yarn -v4.5.3通过 npm 安装#
# 安装 Yarn Classic$ npm install -g yarn
# 验证$ yarn -v1.22.22指定项目使用的 Yarn 版本#
在项目中锁定 Yarn 版本(Yarn Berry 特性):
# 设置项目使用 Yarn 4.x$ yarn set version stable
# 设置使用特定版本$ yarn set version 4.5.3
# 设置使用 Classic$ yarn set version classic执行后会在项目中生成 .yarn/releases/ 目录和 .yarnrc.yml 配置。
项目初始化#
$ mkdir my-project && cd my-project$ yarn init交互式填写项目信息,或使用 -y 跳过:
$ yarn init -yYarn Berry 初始化#
若要从零开始使用 Yarn Berry:
$ yarn init -2这会初始化一个使用 Yarn Berry 的项目,并自动创建 .yarnrc.yml。
依赖管理#
安装依赖#
# 安装 package.json 中的所有依赖$ yarn# 或$ yarn install
# 安装生产依赖$ yarn add lodash
# 安装开发依赖$ yarn add -D typescript
# 安装指定版本$ yarn add lodash@4.17.21
# 全局安装$ yarn global add typescript移除依赖#
$ yarn remove lodash
# 全局移除$ yarn global remove typescript更新依赖#
# 交互式更新$ yarn upgrade-interactive
# 更新指定包$ yarn upgrade lodash
# 更新到最新版本(忽略 semver 范围)$ yarn upgrade lodash --latestYarn Berry 的依赖命令#
Yarn Berry 对部分命令做了调整:
# 添加依赖(同 Classic)$ yarn add lodash
# 更新依赖$ yarn up lodash
# 交互式更新$ yarn upgrade-interactiveyarn.lock#
yarn.lock 锁定依赖的精确版本。与 npm 的 package-lock.json 类似,但格式不同。
🔶 重要:务必将 yarn.lock 提交到版本控制,确保团队环境一致。
# 若 lock 文件与 package.json 冲突,重新生成$ rm yarn.lock$ yarn installYarn Scripts#
在 package.json 中定义脚本:
{ "scripts": { "dev": "vite", "build": "vite build", "test": "vitest" }}运行脚本:
$ yarn dev$ yarn build$ yarn test与 npm 不同,Yarn 运行自定义脚本无需 run 关键字(除非脚本名与 Yarn 内置命令冲突)。
传递参数时无需 --:
$ yarn test --watch --coveragePlug’n’Play (PnP)#
Yarn Berry 默认启用 Plug’n’Play 模式,不再生成 node_modules 目录。依赖以 zip 文件形式存储在 .yarn/cache/ 中,通过 .pnp.cjs 文件进行模块解析。
PnP 的优势#
✅ 安装速度快:无需写入大量小文件
✅ 零安装:可将 .yarn/cache/ 提交到 Git,团队成员无需执行 yarn install
✅ 确定性:杜绝幽灵依赖(Phantom Dependencies)
兼容性问题#
🔶 部分工具不支持 PnP,需要配置 SDK 或回退到 node_modules:
# 安装 IDE SDK(VS Code、WebStorm 等)$ yarn dlx @yarnpkg/sdks vscode若工具完全不兼容,可在 .yarnrc.yml 中禁用 PnP:
nodeLinker: node-modules.yarnrc.yml 常用配置#
# 使用 node_modules 模式nodeLinker: node-modules
# 设置 npm 源npmRegistryServer: 'https://registry.npmmirror.com'
# 启用全局缓存enableGlobalCache: true
# 设置缓存目录cacheFolder: './.yarn/cache'Workspaces#
Yarn 原生支持 Workspaces,适合 Monorepo 项目管理。
配置#
在根目录 package.json 中声明:
{ "name": "my-monorepo", "private": true, "workspaces": ["packages/*", "apps/*"]}目录结构示例:
my-monorepo/├── package.json├── packages/│ ├── shared/│ │ └── package.json│ └── utils/│ └── package.json└── apps/ ├── web/ │ └── package.json └── api/ └── package.jsonWorkspaces 命令#
# 在根目录安装所有 workspace 依赖$ yarn install
# 在指定 workspace 执行命令$ yarn workspace @my-monorepo/web dev
# 在所有 workspace 执行命令$ yarn workspaces foreach run build
# Yarn Berry 语法$ yarn workspaces foreach -A run build聚焦安装(Yarn Berry)#
yarn workspaces focus 可以只安装指定 workspace 及其依赖:
# 只安装指定 workspace 的依赖$ yarn workspaces focus @my-org/app
# 安装所有 workspace,但只安装生产依赖$ yarn workspaces focus -A --production批量执行命令#
# 并行执行,按拓扑顺序$ yarn workspaces foreach --all -pt npm publish
# 只对有变更的 workspace 执行$ yarn workspaces foreach --since run lint
# 递归执行(包含依赖的 workspace)$ yarn workspaces foreach -R run build跨 Workspace 依赖#
在一个 workspace 中引用另一个:
{ "name": "@my-monorepo/web", "dependencies": { "@my-monorepo/shared": "workspace:*" }}workspace:* 协议表示使用本地 workspace 版本。
离线模式#
Yarn 支持离线安装,前提是依赖已被缓存:
$ yarn install --offlineYarn Berry 的零安装特性可以将整个 .yarn/cache/ 提交到 Git,实现真正的离线安装。
缓存管理#
# 查看缓存目录$ yarn cache dir
# 清理缓存$ yarn cache clean
# Yarn Berry$ yarn cache clean --all常用命令对比#
| 操作 | npm | Yarn Classic | Yarn Berry |
|---|---|---|---|
| 安装所有依赖 | npm install | yarn | yarn |
| 添加依赖 | npm install pkg | yarn add pkg | yarn add pkg |
| 添加开发依赖 | npm install -D pkg | yarn add -D pkg | yarn add -D pkg |
| 移除依赖 | npm uninstall pkg | yarn remove pkg | yarn remove pkg |
| 更新依赖 | npm update pkg | yarn upgrade pkg | yarn up pkg |
| 运行脚本 | npm run dev | yarn dev | yarn dev |
| 执行二进制 | npx pkg | yarn dlx pkg | yarn dlx pkg |
| 全局安装 | npm install -g pkg | yarn global add pkg | 不推荐全局安装 |
从 npm 迁移#
若项目原先使用 npm,迁移到 Yarn:
# 删除 npm 锁文件$ rm package-lock.json
# 删除 node_modules$ rm -rf node_modules
# 使用 Yarn 安装$ yarn installYarn 会根据 package.json 生成 yarn.lock。
常见问题#
依赖安装失败#
# 清理缓存后重试$ yarn cache clean$ rm -rf node_modules yarn.lock$ yarn installPnP 模式下模块找不到#
确保 IDE 安装了对应 SDK:
$ yarn dlx @yarnpkg/sdks vscode然后在 VS Code 中选择「使用工作区版本的 TypeScript」。
切换回 node_modules 模式#
在 .yarnrc.yml 中添加:
nodeLinker: node-modules然后重新安装:
$ rm -rf .yarn/cache .pnp.cjs$ yarn install