[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
- 讲解 Markdown
- 示例
- SVN
- Git笔记
- github 相关
- DESIGNER'S GUIDE TO DPI
- JS 模块化
- CommonJS、AMD、CMD、UMD、ES6
- AMD
- RequrieJS
- r.js
- 模块化打包
- 学习Chrome DevTools
- chrome://inspect
- Chrome DevTools 之 Elements
- Chrome DevTools 之 Console
- Chrome DevTools 之 Sources
- Chrome DevTools 之 Network
- Chrome DevTools 之 Memory
- Chrome DevTools 之 Performance
- Chrome DevTools 之 Resources
- Chrome DevTools 之 Security
- Chrome DevTools 之 Audits
- 技巧
- Node.js
- 基础知识
- package.json 详解
- corepack
- npm
- yarn
- pnpm
- yalc
- 库处理
- Babel
- 相关库
- 转译基础
- 插件
- AST
- Rollup
- 基础
- 插件
- Webpack
- 详解配置
- 实现 loader
- webpack 进阶
- plugin 用法
- 辅助工具
- 解答疑惑
- 开发工具集合
- 花样百出的打包工具
- 纷杂的构建系统
- monorepo
- 前端工作流
- 爬虫
- 测试篇
- 综合
- Jest
- playwright
- Puppeteer
- cypress
- webdriverIO
- TestCafe
- 其他
- 工程开发
- gulp篇
- Building With Gulp
- Sass篇
- PostCSS篇
- combo服务
- 编码规范检查
- 前端优化
- 优化策略
- 高性能HTML5
- 浏览器端性能
- 前后端分离篇
- 分离部署
- API 文档框架
- 项目开发环境
- 基于 JWT 的 Token 认证
- 扯皮时间
- 持续集成及后续服务
- 静态服务器搭建
- mock与调试
- browserslist
- Project Starter
- Docker
- 文档网站生成
- ddd