yarn — 一个用于 Node.js 的替代包管理器,由 Facebook 与 Exponent、Google 和 Tilde 于 2016 年共同创建。yarn 解决了 npm 2-4 的速度和安全问题:并行安装、严格的锁定文件和离线缓存。如今,yarn 在 React Native、Expo 和 monorepository 中仍然保持流行。更多信息请访问 yarn Documentation。
要点
yarn(Yet Another Resource Negotiator)于 2016 年 10 月发布,是 Facebook 对 npm 2-4 问题的回应:安装缓慢、缺少锁定文件和不安全的包。yarn 提供了并行下载包、确定性 yarn.lock 以及通过校验和进行完整性验证。2020 年,yarn 迁移到第 2 版(Berry),采用 Plug'n'Play 和 TypeScript-first 方法。
yarn 的架构与 npm 不同:yarn 并行下载包(npm 到第 5 版之前为顺序下载),将每个包缓存到 ~/.cache/yarn 中,项目之间不重复,并通过 checksum 验证完整性。yarn 在每次安装时都会生成 yarn.lock,而 npm 中的 package-lock.json 直到第 5 版才出现。
从 yarn 2(Berry,2020)开始,yarn 完全用 TypeScript 重写,支持 Plug'n'Play、workspaces、用于 monorepository 的 constraints 以及来自不同来源(npm、git、tarball)的安装协议。yarn 3+(2022)增加了 Zero-Installs — 将缓存存储在仓库中,以便无需网络即可即时安装。
yarn install — 主命令,读取 package.json 和 yarn.lock 并安装依赖项。yarn 并行下载包,与 npm 4 及更早版本相比,安装速度提升了 2-3 倍。yarn 使用离线缓存:如果包已在其他项目中下载过,它从缓存中复制,而不是重新下载。
# yarn 主要命令
$ yarn install
$ yarn add react-native-webview
$ yarn add --dev typescript
$ yarn global add expo-cli
# 交互式更新
$ yarn upgrade-interactive
# 删除重复包
$ yarn dedupe
yarn add — 用于安装新包的命令。yarn add <package> 添加到 dependencies,yarn add --dev — 添加到 devDependencies。yarn 自动更新 yarn.lock。yarn upgrade 将包更新到语义范围内的最新版本。yarn upgrade-interactive — 交互式模式,用于选择要更新的特定包。
yarn cache — ~/.cache/yarn/v6 中的全局缓存。每个包在 ZIP 归档中存储一次,并带有校验和。yarn cache 会自动清理,但也可以手动执行 yarn cache clean。yarn cache dir 显示缓存路径。yarn cache list — 已缓存包的列表。
yarn.lock — 用于锁定所有依赖项及其传递包精确版本的文件。与 package-lock.json(JSON)不同,yarn.lock 使用 YAML 格式,结构扁平。yarn.lock 总是在 yarn install 或 yarn add 时自动生成 — 这保证了所有开发人员和 CI 服务器获得相同的包集。
# yarn.lock 结构示例
react@^18.3.0:
version: "18.3.1"
resolution: "react@npm:18.3.1"
dependencies:
loose-envify: "^1.1.0"
checksum: "abc123def456..."
react-native@^0.76.0:
version: "0.76.3"
resolution: "react-native@npm:0.76.3"
dependencies:
react: "18.3.1"
checksum: "def789ghi012..."
yarn.lock 的字段:version — 包的精确版本,resolution — 来源和版本,dependencies — 它的依赖项,checksum — 用于验证的校验和。yarn.lock 被提交到仓库,是依赖项的唯一真相来源。如果 yarn.lock 和 package.json 不一致,yarn 会发出警告。
Yarn constraints — 用于 monorepository 的规则系统,用于检查和强制执行 yarn.lock 中的依赖版本。约束条件在 yarn.constraints.js 文件中以 Yarn Constraint Language 描述。Constraints 可以保证 monorepository 中的所有包使用相同版本的 React 或 TypeScript。
React Native 传统上与 yarn 紧密相关。Expo CLI、React Native CLI 和 Create React Native App 最初都使用 yarn。在 React Native 项目中,yarn.lock 锁定原生模块的版本,这对于通过 CocoaPods(iOS)和 Gradle(Android)进行稳定编译至关重要。yarn workspaces 在具有共享代码的 React Native monorepository 中很流行。
React Native monorepository 中的 yarn workspaces:根 package.json 包含 "workspaces": ["packages/*", "mobile"]。yarn install 在根级别创建一个统一的 node_modules 文件夹。包之间通过 symlink 相互引用。修改原生依赖项后执行 npx pod-install 以更新 CocoaPods。
{
"private": true,
"workspaces": [
"packages/*",
"apps/mobile",
"apps/web"
],
"scripts": {
"mobile:start": "yarn workspace mobile start",
"mobile:ios": "yarn workspace mobile ios",
"lint": "yarn workspaces run lint"
}
}
Expo SDK 50+ 正式推荐 yarn 用于通过 npx create-expo-app 创建的新项目。yarn 确保与 Expo 模块的兼容性,并自动生成正确的 yarn.lock。yarn 3+ 中的 Zero-Installs 允许将缓存提交到仓库 — 开发人员在 git clone 后无需安装依赖项即可获得现成的环境。
npm 和 yarn 解决相同的任务 — 管理 Node.js 包。随着 npm 5-7 的发布,功能差距几乎消失。npm 7+ 包括 workspaces、npm ci(相当于 yarn install --frozen-lockfile)和并行安装。然而,yarn 在特定场景中保留了优势:Plug'n'Play、Zero-Installs 和成熟的 constraints 系统。
| 特性 | npm | yarn |
|---|---|---|
| 创建年份 | 2010 | 2016 |
| 锁定文件 | package-lock.json (JSON) | yarn.lock (YAML) |
| 安装方式 | 顺序(npm 5+) | 并行 |
| Plug'n'Play | 不支持 | 支持(yarn 2+) |
| Workspaces | 支持(npm 7+) | 支持 |
| Zero-Installs | 不支持 | 支持(yarn 3+) |
| 缓存 | node_modules 带 flattening | 全局 ~/.cache/yarn |
| 实现语言 | JavaScript | TypeScript(yarn 2+) |
何时选择 yarn:Expo SDK 50+ 项目、大型 monorepository(100 多个包)、重视 Zero-Installs 以快速设置环境的团队以及已经使用 yarn 的遗留项目。何时选择 npm:标准的 create-react-app、Next.js、Vite 项目,对包管理器没有特定要求的团队。
yarn 4(2024)引入了改进的性能、原生 ESM 支持以及对大型 monorepository 的优化。npm 10+ 继续发展,专注于安全性和兼容性。今天在 npm 和 yarn 之间进行选择是团队偏好和项目特定要求的问题,而不是某个工具的技术优势。
常见问题
yarn 最初在速度上超越 npm,得益于并行安装包和积极的缓存。yarn.lock 在每次安装时自动生成,而 package-lock.json 在 npm 5 中才出现。yarn 提供 Plug'n'Play — node_modules 的替代方案,安装时间为零。从 npm 7+ 开始,基本场景的速度和功能差异极小。
yarn workspaces — 在单个仓库中管理多个包的机制。根 package.json 包含 "workspaces": ["packages/*"] 字段。yarn install 将公共依赖项安装到顶层的一个 node_modules 中,在本地包之间创建 symlink,并避免重复。命令通过 yarn workspaces run <script> 为所有 workspace 执行。
Plug'n'Play(PnP)— 传统 node_modules 文件夹的替代方案,在 yarn 2 中引入。不是复制文件,yarn 在 .pnp.cjs 中创建依赖映射,并将包存储在全局缓存的 ZIP 归档中。PnP 的优点:几秒钟内安装完成,Node.js 启动时间减少 30-50%,没有 node_modules 及其相关的路径问题。
全局安装 yarn:npm install -g yarn。在项目根目录执行 yarn import — yarn 将读取 package-lock.json 并创建等效的 yarn.lock。删除 node_modules 和 package-lock.json,执行 yarn install 进行验证。更新 CI/CD 配置,将 npm 替换为 yarn。yarn 与 package.json 完全兼容。
"Integrity check failed" 错误在 yarn.lock 和 node_modules 不匹配时出现。解决方案:删除 node_modules、yarn.lock 并清空缓存(yarn cache clean),然后重新执行 yarn install。对于版本冲突,使用 yarn upgrade-interactive 选择特定的更新。yarn dedupe 将删除重复的包。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。