Article
第一章:Yarn 简介与安装
1.1 什么是 Yarn
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| Yarn 定义 | Yarn 是由 Facebook(现 Meta)推出的 JavaScript 包管理器,用于替代 npm,提供更快、更安全、更可靠的依赖管理。 | Yarn 并非完全取代 npm,而是兼容 npm registry,可与现有生态无缝集成。 |
| 核心特性 | - 并行安装提升速度 - 确定性安装(通过 yarn.lock) - 离线模式支持 - 内置工作区(Workspaces)支持 | 自 v2 起(Yarn Berry),架构发生重大变化,引入 Plug’n’Play、零安装等新范式。 |
| 版本演进 | - v1(Classic):基于 node_modules - v2+(Berry):默认启用 PnP,可选 node_modules 插件 | 升级到 v2+ 需要迁移配置,部分旧工具链可能不兼容。 |
1.2 安装 Yarn
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 通过 npm 安装(v1) | npm install -g yarn | 全局安装 Yarn Classic | npm install -g yarnyarn --version | 需已安装 Node.js 和 npm;不推荐用于生产环境初始化。 |
| 通过 Corepack 安装(推荐方式) | corepack enablecorepack prepare yarn@stable --activate | 使用 Node.js 内置的 Corepack 管理 Yarn 版本 | corepack enablecorepack prepare yarn@4.0.0 --activate | Node.js ≥ v16.13 支持 Corepack;无需全局安装,版本可项目级锁定。 |
| 通过脚本安装(Linux/macOS) | curl -o- -L https://yarnpkg.com/install.sh | bash | 从官方脚本安装 Yarn v1 | curl -o- -L https://yarnpkg.com/install.sh | bash | 仅适用于 Yarn v1;官方已弃用该方式,建议改用 Corepack。 |
| 通过包管理器安装(如 Homebrew) | brew install yarn | 在 macOS 上通过 Homebrew 安装 | brew install yarn | 仍安装的是 Yarn v1;若需 v2+,应使用 Corepack。 |
注意:自 Yarn v2 起,官方强烈推荐使用 Corepack 管理 Yarn,避免全局安装多个版本导致冲突。
1.3 配置源与代理
| 配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 设置 registry 源 | yarn config set registry <url> | 更换 npm 包下载源(如淘宝镜像) | yarn config set registry https://registry.npmmirror.com | 配置写入用户目录的 .yarnrc.yml 或 .npmrc(取决于版本)。 |
| 查看当前配置 | yarn config get registry | 获取当前 registry 地址 | yarn config get registry | 可用于验证配置是否生效。 |
| 设置代理 | yarn config set proxy <url>yarn config set https-proxy <url> | 为 Yarn 设置 HTTP/HTTPS 代理 | yarn config set https-proxy http://user:pass@proxy.example.com:8080 | 若代理需认证,需在 URL 中包含用户名和密码。 |
| 删除配置项 | yarn config delete registry | 移除自定义配置,恢复默认 | yarn config delete proxy | 删除后将回退到默认行为或上级配置。 |
| 项目级配置文件 | 在项目根目录创建 .yarnrc.yml | 为特定项目设置源或行为 | registry: "https://registry.npmmirror.com"nodeLinker: node-modules | Yarn Berry(v2+)使用 .yarnrc.yml;v1 使用 .yarnrc(INI 格式)。 |
注意事项:
- Yarn v1 与 v2+ 的配置文件格式不同:v1 用
.yarnrc(键值对),v2+ 用.yarnrc.yml(YAML)。- 修改 registry 后,建议删除
yarn.lock并重新运行yarn install以确保一致性。- 企业环境中常结合私有 registry(如 Verdaccio、Nexus)使用自定义源。
第二章:项目初始化与依赖管理
2.1 初始化项目
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 初始化新项目(交互式) | yarn init | 创建 package.json,引导用户输入项目信息 | yarn init(按提示输入 name、version 等) | 适用于 Yarn v1;Yarn Berry(v2+)默认使用 yarn init -2。 |
| 初始化新项目(Berry 风格) | yarn init -2 | 使用 Yarn v2+ 推荐方式初始化,生成 .yarnrc.yml 和现代配置 | yarn init -2 | 自动启用 Corepack、PnP(可后续修改),并安装 yarn 为项目依赖。 |
| 快速初始化(跳过交互) | yarn init -y 或 yarn init --yes | 使用默认值快速生成 package.json | yarn init -y | 所有字段使用默认值(如 name 为当前目录名)。 |
| 从现有 package.json 安装 | yarn install | 根据已有 package.json 和 yarn.lock 安装依赖 | yarn install | 若无 yarn.lock,Yarn 会生成新的 lock 文件。 |
注意:Yarn v2+ 初始化后会在项目中安装 yarn 本身(作为
.yarn/releases/下的压缩包),实现”零安装”和版本锁定。
2.2 添加依赖(dependencies / devDependencies)
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 添加生产依赖 | yarn add <package> | 安装包并写入 dependencies | yarn add lodash | 默认安装最新稳定版;支持语义化版本(如 yarn add lodash@4.17.21)。 |
| 添加开发依赖 | yarn add -D <package> 或 yarn add --dev <package> | 安装包并写入 devDependencies | yarn add -D eslint | 仅在开发环境使用,如构建工具、测试框架等。 |
| 添加可选依赖 | yarn add --optional <package> | 安装可选依赖(optionalDependencies) | yarn add --optional fsevents | 安装失败不会中断流程,常用于平台特定包。 |
| 添加精确版本 | yarn add <package>@<version> | 指定安装特定版本 | yarn add react@18.2.0 | 支持 tag(如 @latest、@beta)或 git URL。 |
| 从 Git 安装 | yarn add <git-url> | 从 Git 仓库安装包 | yarn add https://github.com/user/repo.gityarn add user/repo#branch | 需确保仓库包含有效 package.json。 |
| 从本地路径安装 | yarn add file:../my-lib | 安装本地文件夹中的包 | yarn add file:./local-module | 常用于开发阶段联调本地模块。 |
注意:
- Yarn 会自动更新
yarn.lock文件以确保依赖一致性。- 在 Yarn Berry 中,若使用 PnP,本地路径安装需确保目标包已正确构建。
2.3 删除依赖
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 删除依赖 | yarn remove <package> | 从 dependencies/devDependencies 中移除包,并更新 yarn.lock | yarn remove lodash | 同时删除 node_modules 中对应内容(若使用 nodeLinker)。 |
| 删除多个依赖 | yarn remove pkg1 pkg2 | 一次性移除多个包 | yarn remove eslint prettier | 所有指定包必须已安装,否则报错。 |
| 仅删除但保留代码引用 | 无直接命令 | 需手动清理代码后执行 remove | yarn remove moment | 删除后若代码仍引用该包,运行时将报错(尤其在 PnP 模式下)。 |
注意:Yarn 不会自动清理未被引用的间接依赖(transitive deps),需通过
yarn install重新计算依赖树。
2.4 更新依赖
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 更新单个依赖 | yarn upgrade <package> | 将指定包更新至符合 package.json 范围的最新版本 | yarn upgrade lodash | 不会突破 version range(如 ^1.0.0 不会升到 2.0.0)。 |
| 更新到最新版本(无视范围) | yarn upgrade <package>@latest | 强制更新到最新发行版 | yarn upgrade react@latest | 可能引入破坏性变更,需谨慎。 |
| 更新所有依赖 | yarn upgrade | 更新所有包至符合当前范围的最新版本 | yarn upgrade | 不会修改 package.json 中的版本范围。 |
| 交互式更新 | yarn upgrade-interactive | 以交互方式选择要更新的包(Yarn v1 特有) | yarn upgrade-interactive --latest | Yarn Berry(v2+)中已移除,改用 yarn set version + 插件或第三方工具。 |
| 检查可更新包 | yarn outdated | 列出所有可更新的依赖及其版本信息 | yarn outdated | 显示当前版本、wanted 版本、最新版本三列。 |
注意:Yarn Berry 默认不提供
upgrade-interactive,可通过插件@yarnpkg/plugin-interactive-tools启用。
2.5 列出依赖
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 列出所有依赖 | yarn list | 显示项目中所有已安装的包及其版本(树状结构) | yarn listyarn list --depth=0 | Yarn v1 支持;Yarn Berry 中需启用 node-modules linker 或使用 yarn info。 |
| 列出顶级依赖 | yarn list --depth=0 | 仅显示直接依赖(非嵌套) | yarn list --depth=0 | 在大型项目中可提高可读性。 |
| 搜索特定包 | yarn list <pattern> | 过滤包含关键词的包 | yarn list react | 支持通配符(如 *react*)。 |
| 查看包为何被安装 | yarn why <package> | 显示包的依赖来源(谁依赖了它) | yarn why lodash | 对排查重复依赖或意外安装非常有用。 |
| 查看包元信息 | yarn info <package> | 获取包在 registry 中的详细信息 | yarn info lodash versionsyarn info lodash --json | Yarn Berry 中替代 list 的主要命令。 |
注意:
- 在 Yarn Berry 的 PnP 模式下,
yarn list不可用,应使用yarn info或查看.pnp.cjs文件。yarn why在 Berry 中依然有效,是调试依赖关系的核心命令。
第三章:Yarn 命令详解
3.1 yarn install
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 安装依赖(标准) | yarn install | 根据 package.json 和 yarn.lock 安装所有依赖 | yarn install | 若无 yarn.lock,Yarn 会生成新的 lock 文件并安装最新兼容版本。 |
| 强制重新安装 | yarn install --force | 忽略缓存,强制重新下载和链接所有包 | yarn install --force | 适用于依赖状态异常或缓存损坏时。 |
| 离线安装 | yarn install --offline | 仅使用本地缓存安装,不访问网络 | yarn install --offline | 需此前已成功安装过相同依赖;常用于 CI/CD 或内网环境。 |
| 仅安装生产依赖 | yarn install --production | 跳过 devDependencies 安装 | yarn install --production | 适用于部署到生产环境,减少体积。 |
| 检查模式(不写入) | yarn install --check-cache | 验证缓存完整性,不修改 node_modules | yarn install --check-cache | 用于诊断缓存问题。 |
| 使用特定模块链接器 | (配置项) | 在 .yarnrc.yml 中设置 nodeLinker | nodeLinker: node-modules | Yarn Berry 默认使用 PnP,若需 node_modules 需显式配置。 |
注意:
- Yarn Berry 中
yarn install不再生成node_modules(除非启用 node-modules linker)。- 首次运行会生成
.pnp.cjs(PnP 模式)或填充node_modules。
3.2 yarn add / remove / upgrade
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 添加依赖 | yarn add <package> | 安装包并更新 package.json 和 yarn.lock | yarn add axios | 默认添加到 dependencies;支持版本、tag、git URL 等。 |
| 添加开发依赖 | yarn add -D <package> | 安装到 devDependencies | yarn add -D jest | 简写 -D 等价于 --dev。 |
| 删除依赖 | yarn remove <package> | 从 package.json 和 yarn.lock 中移除包 | yarn remove lodash | 同时清理本地安装内容(如 node_modules 或 PnP 映射)。 |
| 升级依赖(范围内) | yarn upgrade <package> | 更新至符合 package.json 版本范围的最新版 | yarn upgrade react | 不会突破语义化版本约束(如 ^1.0.0 不会升到 2.x)。 |
| 升级到最新版 | yarn upgrade <package>@latest | 强制升级到最新发行版 | yarn upgrade eslint@latest | 可能引入 breaking change,建议配合测试。 |
| 批量操作 | yarn add pkg1 pkg2yarn remove pkg1 pkg2 | 一次性添加或删除多个包 | yarn add express cors | 所有包必须有效,否则整个命令失败。 |
注意:
- 所有操作均自动更新
yarn.lock,确保可重现性。- 在 Yarn Berry 中,这些命令由内置插件提供,行为一致但底层机制不同(基于 PnP)。
3.3 yarn list / outdated / check
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 列出已安装包 | yarn list | 显示依赖树(Yarn v1) | yarn listyarn list --pattern "react" | Yarn Berry 中默认不可用;需启用 node-modules linker 或使用 yarn info。 |
| 检查过期依赖 | yarn outdated | 列出可更新的包(当前 vs 最新) | yarn outdated | 显示三列:Current(当前)、Wanted(范围内最新)、Latest(最新发行版)。 |
| 验证依赖一致性 | yarn check | 检查 package.json 与 yarn.lock 是否一致(Yarn v1) | yarn check --integrity | Yarn Berry 已废弃此命令,改用 yarn install --check-cache 或依赖 PnP 自校验。 |
| 替代方案(Berry) | yarn info <pkg> | 查看包信息(Berry 推荐方式) | yarn info lodashyarn info . dependencies | 支持 JSON 输出:yarn info lodash --json。 |
| 检查许可证 | (需插件) | 使用 @yarnpkg/plugin-licenses 插件 | yarn licenses list | 非内置功能,需额外安装插件。 |
注意:
yarn check在 Yarn v2+ 中完全移除,因其在 PnP 架构下冗余。yarn outdated在 Berry 中仍可用,但输出格式可能略有不同。
3.4 yarn why
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 分析依赖来源 | yarn why <package> | 显示为何安装了某个包(直接或间接依赖) | yarn why lodash | 输出依赖路径,如 my-app → react-scripts → lodash。 |
| 显示多版本原因 | yarn why <package> | 若存在多个版本,列出各自依赖链 | yarn why uuid | 有助于识别重复依赖或版本冲突。 |
| Berry 兼容性 | yarn why <package> | 在 Yarn Berry 中依然完全支持 | yarn why typescript | 是调试复杂依赖关系的核心工具。 |
| 结合工作区使用 | yarn why <package> | 在 Workspaces 项目中显示跨包依赖 | yarn why chalk | 可显示来自其他 workspace 的引用。 |
注意:
- 该命令不修改任何文件,仅用于诊断。
- 在大型项目中,输出可能较长,建议结合 grep 或分页查看。
第四章:Yarn 工作区(Workspaces)
4.1 启用 Workspaces
| 操作名称 | 操作细节 | 注意事项 |
|---|---|---|
| 在根项目 package.json 中声明 workspaces | 添加 "workspaces" 字段,值为包含工作区路径的数组或对象 | 路径相对于根目录;支持 glob 模式(如 ["packages/*"]) |
| 使用数组形式声明 | "workspaces": ["packages/*", "libs/**"] | 最常用方式;Yarn 会自动查找匹配目录下的 package.json |
| 使用对象形式声明(Berry 特有) | "workspaces": { "packages": ["packages/*"], "nohoist": ["**/react-native", "**/react-native/**"] } | nohoist 可防止特定包被提升到根 node_modules(适用于原生模块等) |
| 启用 Yarn Berry 工作区 | 确保使用 Yarn v2+,并运行 yarn install | Yarn v1 也支持基础 Workspaces,但功能有限;Berry 提供更强大支持 |
| 验证工作区是否生效 | 运行 yarn workspaces list | 输出所有识别到的工作区及其位置和名称 |
注意:
- 所有工作区子目录必须包含有效的
package.json(至少含 name 字段)。- Yarn 会将所有工作区的依赖统一安装在根目录(hoisting),避免重复下载。
- 在 Yarn Berry 中,即使使用 PnP,工作区之间也能直接引用而无需发布。
4.2 添加工作区包
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 手动创建工作区包 | 在工作区目录下创建 package.json | { "name": "@myorg/utils", "version": "1.0.0" } | — | 建议使用作用域包名(如 @scope/name)以避免冲突 |
| 使用脚手架工具生成 | 如 yarn create react-app packages/web | 快速初始化标准项目结构 | — | 需确保生成的目录符合 workspaces glob 规则 |
| 通过命令添加(无内置命令) | 无专用命令,需手动创建 | — | — | Yarn 本身不提供 yarn workspace create,但可结合自定义脚本 |
| 安装外部依赖到工作区 | yarn workspace <workspace-name> add <pkg> | 仅为指定工作区添加依赖 | yarn workspace web add reactyarn workspace utils add -D typescript | — |
| 为所有工作区安装依赖 | yarn workspaces foreach add <pkg> | (需插件)批量操作所有工作区 | — | 需启用 @yarnpkg/plugin-workspace-tools 插件 |
注意:
- 工作区包的 name 必须唯一,且不能与已发布 npm 包冲突(除非私有)。
- 开发阶段建议使用相对路径或工作区协议进行内部引用。
4.3 跨工作区引用
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 使用工作区协议引用 | 在依赖中指定 "workspace:*" 或 "workspace:^" | 声明对同项目内其他工作区包的依赖 | { "dependencies": { "@myorg/utils": "workspace:*" } } | workspace:* 表示始终使用源码(实时同步);workspace:~ 或 workspace:^ 遵循版本匹配 |
| 安装时自动链接 | 运行 yarn install | Yarn 自动解析 workspace 协议并建立软链接或 PnP 映射 | — | 无需手动 npm link |
| 引用未发布包 | 直接使用 workspace 协议即可 | 避免临时发布到 registry | — | 被引用的工作区必须在 workspaces 范围内 |
| 查看工作区依赖关系 | yarn workspaces list --verbose | 显示各工作区及其依赖图 | — | 需插件 @yarnpkg/plugin-workspace-tools |
| 构建时处理 | 确保构建工具(如 Webpack、Vite)能解析工作区路径 | 通常无需额外配置(因 Yarn 已处理模块解析) | — | 若使用 TypeScript,需在 tsconfig.json 中配置 paths 或启用 preserveSymlinks |
注意:
workspace:*是最常用方式,确保始终使用最新本地代码,适合开发。- 若使用
workspace:^1.0.0,Yarn 会检查版本是否匹配,适用于需要版本约束的场景。- 在 CI/CD 中,
yarn install会自动处理所有 workspace 引用,无需特殊步骤。
第五章:Yarn Plug’n’Play(PnP)
5.1 启用 PnP
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 初始化项目时启用 PnP | yarn init -2 | 创建 Yarn Berry 项目,默认启用 PnP | yarn init -2 | 自动生成 .yarnrc.yml 并设置 nodeLinker: pnp |
| 在现有项目中启用 PnP | 在 .yarnrc.yml 中添加配置 | 手动切换到 PnP 模式 | nodeLinker: pnp | 需运行 yarn install 生成 .pnp.cjs 文件 |
| 禁用 PnP(回退 node_modules) | 设置 nodeLinker: node-modules | 使用传统 node_modules 结构 | nodeLinker: node-modules | 适用于工具链不兼容 PnP 的场景 |
| 验证 PnP 是否生效 | 检查是否存在 .pnp.cjs 文件 | 确认 Yarn 使用 PnP 解析模块 | ls .pnp.cjs | 运行 node -r ./.pnp.cjs index.js 可手动加载 PnP 环境 |
注意:
- PnP 是 Yarn Berry(v2+)的默认模块解析策略。
- 启用后不再生成
node_modules,所有依赖通过.pnp.cjs动态映射。
5.2 PnP 优势与限制
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| 优势:安装速度快 | 无需创建大量文件和目录,跳过 node_modules 写入 | 安装时间可减少 50% 以上,尤其在大型项目中显著 |
| 优势:确定性解析 | 所有模块路径由 .pnp.cjs 精确控制,杜绝”幽灵依赖” | 强制显式声明依赖,提升项目健壮性 |
| 优势:零安装(Zero-installs) | 依赖信息完全由仓库管理(.yarn/cache + .pnp.cjs),克隆即用 | 需将缓存提交到仓库(或使用离线镜像) |
| 限制:工具兼容性 | 部分工具(如旧版 Webpack、ESLint 插件)假设存在 node_modules | 需升级工具或使用 Yarn 提供的 SDK/补丁 |
| 限制:动态 require 风险 | 使用 require(dynamicPath) 可能因未声明依赖而失败 | 应避免非字面量路径的动态导入,或使用 packageExtensions 声明 |
| 限制:调试复杂度 | 模块路径为虚拟路径,调试器需支持 PnP | 现代 VS Code、Node.js ≥14 已良好支持 |
注意:“幽灵依赖”指代码使用了未在
package.json中声明的包,PnP 会直接报错,帮助发现隐患。虽然 PnP 有学习成本,但长期看提升项目可维护性和 CI 稳定性。
5.3 兼容性处理
| 方法名称 | 语法 / 配置 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 使用 SDK 插件 | 安装 @yarnpkg/sdks 插件 | 为 VS Code、TypeScript、Webpack 等生成 PnP 兼容配置 | yarn dlx @yarnpkg/sdks baseyarn dlx @yarnpkg/sdks vscode | 自动修改 tsconfig.json 和 IDE 配置 |
| 声明缺失依赖(packageExtensions) | 在 .yarnrc.yml 中扩展包依赖 | 修复第三方包未声明 peerDependencies 或隐式依赖的问题 | packageExtensions: "eslint-plugin-react@*": dependencies: "eslint": "*" | 修改后需运行 yarn install 重新生成 .pnp.cjs |
| 启用 node-modules 链接器 | 设置 nodeLinker: node-modules | 临时回退以兼容不支持 PnP 的工具 | nodeLinker: node-modules | 放弃 PnP 优势,仅作过渡方案 |
| 使用 pnpEnableEsmLoader | 在 .yarnrc.yml 中启用 ESM 支持 | 使原生 ES 模块(import/export)能通过 PnP 加载 | pnpEnableEsmLoader: true | 需 Node.js ≥16.12;部分旧工具仍不支持 |
| 手动加载 PnP 环境 | 通过 -r ./.pnp.cjs 启动 Node | 在脚本或测试中显式启用 PnP | node -r ./.pnp.cjs test.js | 适用于自定义运行脚本或 CI 环境 |
| 使用 yarn node 命令 | yarn node <file> | 自动注入 PnP 环境的 Node 执行器 | yarn node src/index.js | 推荐替代原生 node 命令,确保模块解析正确 |
注意:
- 大多数现代前端工具(Vite、Webpack 5、ESLint 8+、Jest 28+)已原生或通过插件支持 PnP。
- 若必须使用不兼容工具,可考虑在子进程中启用
node-moduleslinker,或使用 Docker 隔离环境。
第六章:Yarn 缓存与离线模式
6.1 查看/清理缓存
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 查看缓存位置 | yarn cache dir | 输出 Yarn 全局缓存目录路径 | yarn cache dir | 路径通常为 ~/.yarn/berry/cache(Berry)或 ~/.cache/yarn(v1) |
| 列出缓存内容 | yarn cache list | 显示已缓存的包及其版本(Yarn v1) | yarn cache listyarn cache list --pattern "lodash" | Yarn Berry(v2+)中此命令不可用;缓存以 ZIP 文件形式存储,需手动查看目录 |
| 清理全部缓存 | yarn cache clean | 删除所有全局缓存的包 | yarn cache clean | 下次安装将重新下载;适用于磁盘空间不足或缓存损坏 |
| 清理特定包缓存 | yarn cache clean <package> | 仅清除指定包的缓存(Yarn v1) | yarn cache clean lodash | Yarn Berry 不支持按包清理,需手动删除 .yarn/cache 中对应 ZIP 文件 |
| 强制跳过缓存安装 | yarn install --no-cache | 安装时不使用本地缓存(Berry 特有) | yarn install --no-cache | 用于验证网络安装是否正常 |
| 查看项目级缓存 | 检查 .yarn/cache/ 目录 | 在启用零安装(Zero-installs)的 Berry 项目中,缓存提交在仓库内 | ls .yarn/cache | 此缓存用于离线安装,与全局缓存不同 |
注意:
- Yarn Berry 默认将依赖缓存为 ZIP 文件(
.yarn/cache/*.zip),并可通过 Git 提交实现”零安装”。- 全局缓存用于加速跨项目安装,项目级缓存用于离线协作。
- 清理缓存不会影响已安装的项目,但会延长下次安装时间。
6.2 离线安装依赖
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 启用离线镜像(Berry) | 运行 yarn install 并提交 .yarn/cache | 首次在线安装后,缓存自动可用于离线 | git add .yarn/cache && git commit -m "Add offline cache" | 需在 .yarnrc.yml 中启用 enableOfflineMirror: true(默认已启用) |
| 离线安装(无网络) | yarn install --offline | 仅使用本地缓存安装依赖,不访问 registry | yarn install --offline | 若缓存缺失所需包,命令将失败 |
| 验证离线可用性 | 在无网络环境下运行 yarn install | 测试项目是否真正支持离线开发 | 断网后执行 yarn install | 成功前提是 .yarn/cache 包含所有依赖 ZIP |
| 从离线镜像恢复 | 克隆仓库后直接 yarn install | 新开发者无需联网即可安装依赖 | git clone repo && cd repo && yarn install | 依赖 .pnp.cjs 和 .yarn/cache 完整存在 |
| 禁用离线镜像 | 设置 enableOfflineMirror: false | 不生成 .yarn/cache 目录 | enableOfflineMirror: false | 节省仓库体积,但失去离线能力 |
注意:
- 离线模式是 Yarn Berry 的核心优势之一,特别适合内网开发、CI/CD 稳定性保障。
- 所有团队成员必须使用相同 Yarn 版本,否则
.pnp.cjs可能不兼容。- 若更新依赖,需重新在线运行
yarn install以更新.yarn/cache并提交。
第七章:Yarn 配置与脚本
7.1 .yarnrc.yml 配置文件
| 配置项 | 说明 | 示例值 | 注意事项 |
|---|---|---|---|
nodeLinker | 指定模块链接方式 | pnp 或 node-modules | 默认为 pnp(Berry);设为 node-modules 可兼容传统工具链 |
yarnPath | 指定项目内 Yarn 可执行文件路径 | .yarn/releases/yarn-4.0.0.cjs | 实现”项目级 Yarn 版本锁定”,由 yarn set version 自动生成 |
enableOfflineMirror | 是否启用离线缓存镜像 | true / false | 默认 true;控制是否生成 .yarn/cache/ 目录 |
registry | 设置 npm 包 registry 地址 | https://registry.npmmirror.com | 等效于 yarn config set registry,但作用于项目级 |
npmAuthToken | 设置私有 registry 认证令牌 | your-auth-token | 用于访问受保护的私有包仓库(如 GitLab、Verdaccio) |
packageExtensions | 为第三方包补充缺失依赖 | 见下方示例 | 用于修复未声明 peerDependencies 的包 |
pnpEnableEsmLoader | 启用原生 ESM 模块 PnP 支持 | true | 需 Node.js ≥16.12;使 import 能正确解析 PnP 路径 |
plugins | 声明使用的插件 | ["@yarnpkg/plugin-workspace-tools"] | 插件需预先下载到 .yarn/plugins/ |
packageExtensions 示例:
packageExtensions:
"eslint-plugin-react@*":
dependencies:
"eslint": "*"
"webpack-dev-server@^4.0.0":
peerDependencies:
"webpack": "^5.0.0"
注意:
.yarnrc.yml是 Yarn Berry(v2+)的标准配置文件,使用 YAML 格式。- 配置优先级:命令行参数 > 项目
.yarnrc.yml> 用户级配置 > 默认值。- 修改后需运行
yarn install使部分配置(如packageExtensions)生效。
7.2 自定义脚本(scripts)
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 定义脚本 | 在 package.json 的 scripts 字段添加 | 封装常用命令 | "scripts": { "dev": "vite", "build": "tsc && vite build" } | 脚本在项目根目录上下文中执行 |
| 运行脚本 | yarn <script-name> | 执行自定义命令 | yarn devyarn build | 自动将 node_modules/.bin 加入 PATH |
| 并行运行脚本 | 使用 &(Unix)或 start(Windows) | 同时启动多个进程 | "dev": "vite & yarn watch:types" | 跨平台建议使用 concurrently 等工具 |
| 串行运行脚本 | 使用 && | 按顺序执行,前一个失败则停止 | "prebuild": "eslint .""build": "npm run prebuild && tsc" | pre<name> / post<name> 会自动在 <name> 前后运行 |
| 工作区脚本 | yarn workspace <name> run <script> | 在指定工作区运行脚本 | yarn workspace web run build | 脚本在该工作区目录中执行 |
| 批量运行脚本 | yarn workspaces foreach run <script> | 在所有工作区运行同一脚本 | yarn workspaces foreach run test | 需启用 @yarnpkg/plugin-workspace-tools 插件 |
| 传递参数 | yarn <script> -- --arg value | 向脚本传递额外参数 | yarn build -- --minify | -- 后的内容原样传给脚本命令 |
注意:
- Yarn 脚本环境自动包含项目依赖的可执行文件(如 eslint、jest),无需全局安装。
- 在 PnP 模式下,脚本通过
.pnp.cjs正确解析依赖,无需node_modules。- 避免在脚本中硬编码路径,应使用相对路径或工具内置解析。
7.3 环境变量使用
| 使用方式 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 在脚本中直接使用 | process.env.MY_VAR(Node.js) | 读取系统环境变量 | "dev": "NODE_ENV=development vite" | Unix/Linux 使用 VAR=value cmd;Windows 需 cross-env |
| 跨平台设置变量 | 使用 cross-env 包 | 兼容 Windows 和 Unix | "build": "cross-env NODE_ENV=production tsc" | 需先安装:yarn add -D cross-env |
从 .env 文件加载 | 使用 dotenv 或框架内置支持 | 管理开发环境配置 | 在代码中:require('dotenv').config() | Vite、Create React App 等默认支持 .env |
| Yarn 内置环境变量 | Yarn 自动注入的变量 | 用于条件逻辑 | "postinstall": "echo $npm_package_name" | 常见变量:npm_package_name、npm_package_version |
在 .yarnrc.yml 中引用 | 不支持直接引用 env | 配置文件不支持动态 env | — | 敏感信息(如 token)应通过命令行或 CI 注入 |
| CI/CD 中注入 | 在 GitHub Actions 等中设置 | 安全传递密钥 | env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | 避免将密钥写入代码库 |
注意:
- Yarn 本身不提供
.env自动加载功能,需依赖应用层(如 Webpack、Vite)或手动引入 dotenv。- 环境变量在脚本中是临时的,不影响当前 shell 会话。
- 在 PnP 模式下,环境变量行为与标准 Node.js 一致,无特殊限制。
第八章:Yarn Berry(v2+)特性
8.1 零安装(Zero-installs)
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| 零安装定义 | 项目所有依赖信息(包括缓存和解析逻辑)完全由仓库管理,新成员克隆后无需运行 yarn install 即可直接运行项目 | 核心文件包括 .yarn/cache/(依赖 ZIP)、.pnp.cjs(模块映射)、.yarn/releases/(Yarn 自身) |
| 实现机制 | Yarn 将每个包压缩为 ZIP 文件存入 .yarn/cache/,并通过 .pnp.cjs 提供运行时模块解析 | 所有文件均可提交到 Git,实现”开箱即用” |
| 启用方式 | 默认启用;确保 .yarnrc.yml 中 enableOfflineMirror: true(默认值) | 首次在线运行 yarn install 后,即可离线使用 |
| 优势 | - 消除”在我机器上能跑”问题 - 加速 CI/CD(无需下载依赖) - 精确锁定依赖状态 | 特别适合大型团队和严格审计环境 |
| 仓库体积影响 | .yarn/cache/ 可能较大(数百 MB) | 可通过 Git LFS 或仅在主分支保留缓存来缓解 |
| 版本一致性 | 所有开发者使用完全相同的依赖二进制和 Yarn 版本 | 避免因 Yarn 或依赖版本差异导致的构建不一致 |
注意:若更新依赖,需重新运行
yarn install并提交新的.yarn/cache/和.pnp.cjs。删除node_modules不再必要,因为根本不存在该目录(PnP 模式下)。
8.2 插件系统
| 方法名称 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| 安装插件 | yarn plugin import <plugin-name> | 添加官方或第三方插件 | yarn plugin import workspace-toolsyarn plugin import from sources | 插件将下载到 .yarn/plugins/ 并自动激活 |
| 列出已安装插件 | yarn plugin list | 查看当前项目启用的插件 | yarn plugin list | 显示插件名称、路径和来源 |
| 使用插件命令 | 直接调用插件提供的 CLI 命令 | 扩展 Yarn 功能 | yarn workspaces foreach run build(需 workspace-tools) | 插件命令与内置命令无缝集成 |
| 开发自定义插件 | 编写符合 Yarn 插件 API 的 JS 模块 | 满足特定团队需求 | 参考 @yarnpkg/plugin-hello-world 示例 | 需熟悉 Yarn 的内部架构和钩子系统 |
| 插件配置 | 在 .yarnrc.yml 中设置插件选项 | 调整插件行为 | workspacesForeachParallel: true | 具体配置项取决于插件文档 |
常用官方插件:
| 插件名称 | 功能 |
|---|---|
@yarnpkg/plugin-workspace-tools | 提供工作区批量操作 |
@yarnpkg/plugin-interactive-tools | 交互式升级依赖 |
@yarnpkg/plugin-typescript | TypeScript 类型检查集成 |
注意:
- 插件一旦导入,即成为项目的一部分,随仓库共享,确保团队行为一致。
- 插件以
.cjs文件形式存储,无需额外安装步骤。- 第三方插件需谨慎审核,因其拥有对 Yarn 生命周期的完全控制权。
8.3 可扩展性与约束策略
| 特性名称 | 说明 | 配置方式 | 注意事项 |
|---|---|---|---|
| 约束策略(Constraints) | 使用 Prolog 语言编写规则,强制执行项目规范(如依赖版本、脚本命名等) | 创建 .yarn/constraints.pro 文件,并运行 yarn constraints | 需启用 @yarnpkg/plugin-constraints 插件 |
| 可扩展的解析器 | 支持自定义协议(如 patch:、portal:、workspace:) | 在依赖中直接使用协议:"my-pkg": "patch:my-pkg@npm:1.0.0#./patches/my-pkg.patch" | — |
| 协议覆盖(Protocol Overrides) | 强制替换 registry 中的包为本地或 fork 版本 | 在 .yarnrc.yml 中配置 | — |
| 权限最小化 | Yarn 默认不执行任意生命周期脚本(如 postinstall) | 需显式启用 enableScripts: true | 减少供应链攻击风险;安全优先设计 |
| 自定义验证流程 | 结合 yarn set version 和插件,构建专属工作流 | 如集成内部审计工具 | 企业级场景可深度定制依赖治理策略 |
约束示例(.yarn/constraints.pro):
gen_enforced_dependency(WorkspaceCwd, 'lodash', '-', 'Use lodash-es instead') :-
depends_on(WorkspaceCwd, 'lodash', _).
注意:
- 约束系统强大但学习曲线陡峭,建议从简单规则开始(如禁止特定包)。
patch:协议生成的补丁文件应提交到仓库,确保团队一致性。- 默认禁用脚本执行是安全特性,若需运行(如原生模块编译),需明确开启并评估风险。
第九章:Yarn 与 npm / pnpm 对比
9.1 功能对比
| 功能特性 | Yarn (v2+ Berry) | npm (v9+) | pnpm (v8+) | 说明 |
|---|---|---|---|---|
| 依赖安装方式 | Plug’n’Play(默认)或 node_modules | node_modules(嵌套 + 扁平化) | 符号链接 + 内容寻址存储(CAS) | Yarn PnP 无 node_modules;pnpm 使用硬链接节省空间 |
| 工作区(Monorepo)支持 | 内置,强大(workspace 协议、foreach 等) | 内置(npm workspaces),基础功能 | 内置,高效(自动 hoisting) | Yarn 工作区工具链最丰富 |
| 离线安装 | 支持(通过 .yarn/cache 提交) | 部分支持(需缓存目录) | 支持(全局 store 可复用) | Yarn 的”零安装”体验最完整 |
| 确定性安装 | 是(yarn.lock + PnP) | 是(package-lock.json) | 是(pnpm-lock.yaml) | 三者均保证可重现安装 |
| 插件/扩展系统 | 强大(官方插件生态) | 有限(主要靠 CLI 参数) | 中等(支持 hooks 和自定义命令) | Yarn 可深度定制行为 |
| 约束与治理 | 支持(Prolog 约束规则) | 不支持 | 部分(通过 .pnpmfile.cjs) | Yarn 适合强规范团队 |
| 脚本生命周期安全 | 默认禁用(需 enableScripts) | 默认启用 | 默认启用(可配置) | Yarn 安全性更高 |
| 包协议扩展 | workspace:、patch:、portal: 等 | 仅 file:、git 等标准协议 | workspace:、link: 等 | Yarn 协议最灵活 |
| TypeScript/ESM 支持 | 优秀(SDK 插件) | 一般(依赖工具链) | 良好 | Yarn 提供官方 IDE 集成方案 |
9.2 性能对比
| 性能维度 | Yarn (Berry) | npm | pnpm | 说明 |
|---|---|---|---|---|
| 安装速度 | 极快(PnP 无文件写入) | 中等 | 快(硬链接复用) | Yarn 在大型项目中优势显著 |
| 磁盘空间占用 | 低(ZIP 缓存 + 无重复 node_modules) | 高(重复依赖多) | 最低(全局 store + 符号链接) | pnpm 空间效率最优 |
| CI/CD 冷启动 | 快(若提交 cache) | 慢(每次下载) | 快(store 可缓存) | Yarn 零安装 vs pnpm 缓存 store |
| 模块解析速度 | 快(.pnp.cjs 哈希映射) | 慢(递归查找 node_modules) | 快(扁平化 node_modules) | Yarn 和 pnpm 均避免查找风暴 |
| 内存占用 | 低 | 中 | 低 | 三者现代版本均优化良好 |
| 首次安装 vs 后续安装 | 首次稍慢(生成 cache),后续极快 | 每次相近 | 首次建 store,后续快 | Yarn 后续安装几乎瞬时 |
基准参考(典型大型项目):
- 首次安装:pnpm ≈ Yarn < npm
- 后续安装:Yarn (PnP) < pnpm < npm
- 磁盘占用:pnpm < Yarn < npm
9.3 适用场景建议
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 企业级 Monorepo(强规范) | Yarn Berry | 工作区功能完善、约束策略、零安装、安全默认值,适合大型团队协作 |
| 资源受限环境(如容器) | pnpm | 磁盘占用最小,硬链接机制节省空间,适合微服务密集部署 |
| 快速原型 / 个人项目 | npm | 无需额外学习,Node.js 自带,开箱即用 |
| 需要极致 CI 速度 & 离线开发 | Yarn Berry | 提交 .yarn/cache 实现真正零安装,CI 无需网络 |
| 工具链老旧(不支持 PnP) | Yarn (node-modules 模式) 或 pnpm | 可关闭 PnP 使用 nodeLinker: node-modules,或选择兼容性更好的 pnpm |
| TypeScript + VS Code 深度集成 | Yarn Berry | 官方 SDK 插件一键配置,提供最佳开发体验 |
| 安全敏感项目(防供应链攻击) | Yarn Berry | 默认禁用生命周期脚本,减少恶意代码执行风险 |
| 已有 npm 项目迁移成本低 | pnpm | 命令与 npm 高度兼容(pnpm add ≈ npm install),迁移平滑 |
总结建议:
- 追求创新性、可控性、团队规范 → 选 Yarn Berry
- 追求磁盘效率、兼容性、简洁性 → 选 pnpm
- 追求简单、默认、无额外依赖 → 用 npm
不推荐场景:
- 在 Yarn Berry 中强行使用大量不兼容 PnP 的旧工具(应评估迁移成本)
- 在磁盘空间极度紧张的环境中使用 npm(因重复依赖膨胀)