[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