ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
[TOC] # 官网 https://yarnpkg.com/zh-Hans/ # 简介 Yarn 是 Facebook, Google, Exponent 和 Tilde 开发的一款新的 JavaScript 包管理工具。 它并没有试图完全取代 npm。Yarn 同样是一个从 npm 注册源获取模块的新的 CLI 客户端。注册的方式不会有任何变化 —— 你同样可以正常获取与发布包。 # yarn 解决了哪些 npm 的问题呢? * yarn 缓存了每次你下载的模块,所以同样模块同样的版本不会发送第二次下载请求,对于没有缓存的模块, yarn 也可以通过并行的网络请求最大限度利用网络资源。现在真的是没有什么几十秒安装不完的依赖的。一个 50 个依赖的 webpack + babel 项目可以在 20 秒左右安装完成。 * yarn 在开始安装一个包之前会先用 checksums 来验证,你不用担心本地的缓存的包被破坏了导致安装失败。 * 比如今天安装模块的时候C和D是某一个版本,而当以后C、D更新的时候,再次安装模块就会安装C和D的最新版本,如果新的版本无法兼容你的项目,你的程序可能就会出BUG,甚至无法运行。这就是npm的弊端,而yarn为了解决这个问题推出了`yarn.lock`的机制。 ## 其他功能 * workspace (npm 7之后就会有了~), * resolutions 字段的解析(npm 不支持,不过有一个[第三方库](https://github.com/rogeriochaves/npm-force-resolutions)支持) # Yarn常用命令 ~~~ yarn init // 项目初始化,等同于npm的npm init yarn / $ yarn install // 安装package.json中的依赖包,等同于npm install yarn add vue // 添加并安装依赖包,等同于npm install vue(现在无需加--save,已经成为默认行为) yarn global add vue // 全局安装包 yarn remove vue // 删除依赖包,等同于npm uninstall vue yarn upgrade // 升级package.json指定的所有依赖包(在package.json指定的版本范围内) yarn upgrade --latest //升级package.json指定的所有依赖包,但忽略package.json指定的版本范围,同时package.json中指定的版本将被重写 yarn outdated // 列出包的所有依赖项的版本信息。此信息包括当前安装的版本、基于语义版本所需的版本和最新的可用版本 yarn run // 列出包里所有可运行的脚本 yarn run dev // 运行package.json中scripts定义的脚本命令,等同于 npm runx ~~~ 把 Yarn 的下载源设置为淘宝镜像: ~~~ yarn config list // 查看config yarn config list // 查看当前目录相关config yarn config get registry // 查看当前下载源,初始为https://registry.yarnpkg.com yarn config set registry https://registry.npm.taobao.org -g // 更改为淘宝 yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g ~~~ [yarn global](https://yarnpkg.com/zh-Hans/docs/cli/global) [从 npm 迁移到 Yarn](https://yarn.bootcss.com/docs/migrating-from-npm.html) # 安装路径 npm 的全局模块安装路径: ``` C:\Users\Administrator\AppData\Roaming\npm\node_modules\ ``` yarn 的全局模块安装路径: ``` C:\Users\Administrator\AppData\Local\Yarn\config\global\node_modules\ ``` # 查看全局安装包 ```shell npm list -g --depth 0 yarn global list ``` # PnP PnP,`Plug'n'Play`的缩写,意为即插即用。 启用PnP后(Yarn 2默认启用),`yarn install`不再生成`node_modules`目录,而是生成了`.yarn`目录和`.pnp.js`文件。 `.yarn`目录存放了项目中下载的所有依赖的 zip 包,`.pnp.js`的内容是项目的 npm 模块解析规则。 ## 实现方案 PnP 的具体工作原理是,作为把依赖从缓存拷贝到`node_modules`的替代方案,Yarn 会维护一张静态映射表,该表中包含了以下信息: * 当前依赖树中包含了哪些依赖包的哪些版本 * 这些依赖包是如何互相关联的 * 这些依赖包在文件系统中的具体位置 这个映射表在 Yarn 的 PnP 实现中对应项目目录中的`.pnp.js`文件。 这个`.pnp.js`文件是如何生成,Yarn 又是如何利用它的呢? 在安装依赖时,在第 3 步完成之后,Yarn 并不会拷贝依赖到`node_modules`目录,而是会在`.pnp.js`中记录下该依赖在缓存(`.yarn`)中的具体位置。这样就避免了大量的 I/O 操作同时项目目录也不会有`node_modules`目录生成。 同时`.pnp.js`还包含了一个特殊的 resolver,Yarn 会利用这个特殊的 resolver 来处理`require()`请求,该 resolver 会根据`.pnp.js`文件中包含的静态映射表直接确定依赖在文件系统中的具体位置,从而避免了现有实现在处理依赖引用时的 I/O 操作。 > [Yarn 的 Plug'n'Play 特性](https://loveky.github.io/2019/02/11/yarn-pnp/) > [Yarn PnP - Suyi的小站](https://suyi.xyz/posts/yarn-pnp) # `yarn create` 从任何`create-*`入门套件中创建新项目。 ``` yarn create <starter-kit-package> [<args>] ``` 这个命令是一个速记,可以帮助你一次完成两件事情: * `create-<starter-kit-package>` 全局安装,或者如果软件包已存在,则将软件包更新为最新版本 * 运行位于 `bin` 入门工具包领域的可执行文件 `package.json`,将其转发 `<args>` 给它 例如,`yarn create react-app my-app`相当于: ```shell $ yarn global add create-react-app $ create-react-app my-app ``` # WorkSpaces ~~~shell # packageA 安装 axios yarn workspace packageA add axios # packageA 移除 axios yarn workspace packageA remove axios ~~~ > `packageA`是需要安装依赖的包名,即`package.json`中的`name`字段,而非目录名 root package ~~~shell # root package 安装 commitizen yarn add -W -D commitizen # root package 移除 commitizen yarn remove -W commitizen ~~~ > [yarn官网-workspaces](https://classic.yarnpkg.com/zh-Hans/docs/workspaces/) > [yarn 的 WorkSpaces 功能介绍](https://www.dazhuanlan.com/2019/12/25/5e027015a4775/) ## lerna 前端包的管理 使用 [lerna](https://lerna.js.org/) 和 yarn 构建 monorepo 项目,核心思想是**用 yarn 来处理依赖问题,用 lerna 来处理发布问题。** 一个基本的 Lerna 管理的仓库结构如下: ``` lerna-repo/ ┣━ packages/ ┃ ┣━ package-1/ ┃ ┃ ┣━ ... ┃ ┃ ┗━ package.json ┃ ┗━ package-2/ ┃ ┃ ┣━ ... ┃ ┃ ┗━ package.json ┣━ ... ┣━ lerna.json ┗━ package.json ``` 根据使用 lerna 的经验,总结出一个最佳实践。下面是一些特性。 ``` 采用 Independent 模式 根据 Git 提交信息,自动生成 changelog eslint 规则检查 prettier 自动格式化代码 提交代码,代码检查 hook (husky、lint-staged) 遵循 semver 版本规范 ``` 大家应该也可以看出来,在开发这种工程的过程的,最为重要的一点就是规范 。 > [lerna多包管理实践](https://juejin.cn/post/6844904194999058440) > [Monorepo实战](https://www.jianshu.com/p/dafc2052eedc) > [结合 lerna 和 yarn workspace 管理多项目工作流](https://segmentfault.com/a/1190000025173538) > [http://www.learnfuture.com/InnerSite/ArticleContent?code=6040](http://www.learnfuture.com/InnerSite/ArticleContent?code=6040) > [All in one:项目级 monorepo 策略最佳实践 - 掘金 (juejin.cn)](https://juejin.cn/post/6924854598268108807#heading-7) # 我该提交 `yarn.lock` 和 `package-lock.json` 文件吗 通常情况下,应该总是提交依赖锁文件。 https://stackoverflow.com/questions/44552348/should-i-commit-yarn-lock-and-package-lock-json-files