前端工程師應該知道的yarn知識

yarn 是在工做中離不開的工具,但在工做中,不少人基本只會使用 yarn install,並且會手動刪除 node-modules,或刪除 yarn.lock 文件等不規範操做。本文將從一些基礎的知識點開始介紹,按部就班的讓你對 Yarn 有一個更深刻的瞭解,來保證規範的使用yarn,避免一些隱藏bug的產生。
本文主要介紹如下知識:前端

  1. 什麼是registry
  2. 依賴的版本含義及寫法
  3. 依賴類型及區別(devDependencesdevDependencespeerDependencesoptionalDependenciesbundledDependencies
  4. 緩存介紹
  5. yarn.lock 文件做用及介紹
  6. yarn install 安裝依賴的過程
  7. 依賴關係樹的模塊扁平化
  8. 經常使用的 yarn 命令介紹

什麼是registry

registry是 模塊倉庫提供了一個查詢服務,也就是咱們常說的源。以yarn官方鏡像源爲例,它的查詢服務網址是https://registry.yarnpkg.comvue

這個網址後面跟上模塊名,就會獲得一個 JSON 對象,裏面是該模塊全部版本的信息。好比,訪問 https://registry.npmjs.org/vue,就會看到 vue 模塊全部版本的信息。node

registry 網址的模塊名後面,還能夠跟上版本號或者標籤,用來查詢某個具體版本的信息。 https://registry.yarnpkg.com/vue/2.6.10webpack

上面返回的 JSON 對象裏面,有一個dist.tarball屬性,是該版本壓縮包的網址。dist.shasum 屬性至關於hash值,在lock和緩存時會使用到,下文會提到。web

dist: {
  "shasum": "a72b1a42a4d82a721ea438d1b6bf55e66195c637",
  "tarball":"https://registry.npmjs.org/vue/-/vue-2.6.10.tgz"
},
複製代碼

咱們在執行 yarn install 時,就是向 registry 查詢獲得上面的壓縮包地址進行下載的。
工做中,咱們可能有須要修改鏡像源的場景,好比修改爲淘寶源或者本身公司的私有源。
查看和設置源,能夠經過 yarn config 命令來完成
查看當前使用的鏡像源vue-router

yarn config get registry
複製代碼

修改鏡像源(以修改爲淘寶源爲例)npm

yarn config set registry https://registry.npm.taobao.org/
複製代碼

依賴版本

yarn的包遵照 semver,即語義化版本。 SemVer 是一套語義化版本控制的約定,定義的格式爲json

X.Y.Z(主版本號.次版本號.修訂號):
X.主版本號:進行不向下兼容的修改時,遞增主版本號
Y.次版本號: 作了向下兼容的新增功能或修改
Z.修訂號:作了向下兼容的問題修復
複製代碼

yarn 中依賴版本範圍的表示方法有如下幾種:數組

  1. 經過比較器
表示 含義描述
<2.0.0 任何小於 2.0.0 的版本
<=3.1.4 任何小於或等於 3.1.4 的版本
>0.4.2 任何大於 0.4.2 的版本
>=2.7.1 任何大於或等於 2.7.1 的版本
=4.6.6 任何等於 4.6.6 的版本
>=2.0.0 <3.1.4 交集,大於或等於 2.0.0 並小於 3.1.4
<2.0.0 || >3.1.4 並集 小於 2.0.0 或者大於 3.1.4

若是沒有指定運算符,默認爲 =緩存

  1. 經過連字符
表示 含義描述
2.0.0 - 3.1.4 >=2.0.0 <=3.1.4
0.4 - 2 >=0.4.0 <=2.0.0

版本號中缺乏的那些部分會用數字 0 填充。

  1. X範圍
    字符 X、x 或者 * 均可以做爲通配符,用於填充部分或所有版本號。 被省略的那部分版本號默認爲 x 範圍。
表示 含義描述
* >=0.0.0 (任意版本)
2.x >=2.0.0 <3.0.0(匹配主要版本)
3.1.x > = 3.1.0 < 3.2.0(匹配主要和次要版本)
``(空字符串) * 或 > = 0.0.0
2 2.x.x 或 > = 2.0.0 < 3.0.0
3.1 3.1.x 或 > = 3.1.0 < 3.2.0
  1. ~ 字符範圍
    同時使用字符 ~ 和次版本號,代表容許 修訂號 變動。同時使用字符 ~ 和主版本號,代表容許 次版本 號變動。
表示 含義描述
~3.1.4 >=3.1.4 <3.2.0
~3.1 3.1.x 或 > = 3.1.0 < 3.2.0
~3 3.x 或 > = 3.0.0 < 4.0.0
  1. ^ 字符範圍
    字符 ^ 代表不會修改版本號中的第一個非零數字,3.1.4 裏的 3 或者 0.4.2 裏的 4。版本號中缺乏的部分將被 0 填充,且在匹配時這些位置容許改變。
表示 含義描述
^3.1.4 >=3.1.4 <4.0.0
^0.4.2 >=0.4.2 <0.5.0
^0.0.2 >=0.0.2 <0.0.3

使用 yarn add [package-name] 命令安裝依賴,默認使用的是 ^ 範圍。
須要注意的是,若是一個比較器包含有預發佈標籤的版本,它將只匹配有相同 major.minor.patch 的版本。 例如 >=3.1.4-beta.2,能夠匹配 3.1.4-beta.3,但不會匹配 3.1.5-beta.3 版本。

依賴類型

dependences 代碼運行時所須要的依賴,好比vue,vue-router。

devDependences 開發依賴,就是那些只在開發過程當中須要,而運行時不須要的依賴,好比babel,webpack。

peerDependences 同伴依賴,它用來告知宿主環境須要什麼依賴以及依賴的版本範圍。
若是宿主環境沒有對應版本的依賴,在安裝依賴時會報出警告。
好比包 eslint-plugin-import 中有依賴:

"peerDependencies": {
    "eslint": "2.x - 5.x"
  },
複製代碼

在install時,若是宿主環境沒有 2.x-5.x 版本的 eslint,cli就會拋出警告。但不會自動幫咱們安裝,仍然須要手動安裝。

optionalDependencies 可選依賴,這種依賴即使安裝失敗,Yarn也會認爲整個依賴安裝過程是成功的。
可選依賴適用於那些即使沒有成功安裝可選依賴,也有後備方案的狀況。

bundledDependencies 打包依賴,在發佈包時,這個數組裏的包都會被打包打包到最終的發佈包裏,須要注意 bundledDependencies 中的包必須是在devDependencies或dependencies聲明過的。

緩存

yarn 會將安裝過的包緩存下來,這樣再次安裝相同包的時候,就不須要再去下載,而是直接從緩存文件中直接copy進來。

能夠經過命令 yarn cache dir 查看yarn的全局緩存目錄。個人緩存目錄在 /Library/Caches/Yarn/v1 下。

能夠看出,yarn 會將不通版本解壓後的包存放在不一樣目錄下,目錄以

npm-[package name]-[version]-[shasum]` 
複製代碼

來命名。shasum 即上文中 registry 獲取的 dist.shasum

咱們能夠經過命令查看已經緩存過的包。

yarn cache list    列出已緩存的每一個包

yarn cache list --pattern <pattern>  列出匹配指定模式的已緩存的包
複製代碼

例如執行 yarn cache list --pattern vue

yarn.lock

yarn.lock 中會準確的存儲每一個依賴的具體版本信息,以保證在不一樣機器安裝能夠獲得相同的結果。

下面以@babel/code-frame爲例,看看yarn.lock 中會記錄哪些信息。

  1. 第一行 "@babel/code-frame@7.0.0-beta.54" 包的name和語義化版本號,這些都來自package.json中的定義。
  2. version 字段,記錄的是一個確切的版本。
  3. resolved 字段記錄的是包的URL地址。其中hash值,即上文的 dist.shasum
  4. dependencies 字段記錄的是當前包的依賴,即當前包在 package.jsondependencies 字段中的全部依賴。

Yarn 在安裝期間,只會使用當前項目的 yarn.lock 文件(即 頂級 yarn.lock 文件),會忽略任何依賴裏面的 yarn.lock 文件。在頂級 yarn.lock 中包含須要鎖定的整個依賴樹裏所有包版本的全部信息。

yarn.lock文件是在安裝期間,由 Yarn 自動生成的,而且由yarn來管理,不該該手動去更改,更不該該刪除yarn.lock文件,且要提交到版本控制系統中,以避免由於不一樣機器安裝的包版本不一致引起問題。

Yarn install過程

首次執行 yarn install 安裝,會按照 package.json 中的語義化版本,去向 registry 進行查詢,並獲取到符合版本規則的最新的依賴包進行下載,並構建構建依賴關係樹。 好比在 package.json 中指定 vue 的版本爲 ^2.0.0,就會獲取符合 2.x.x 的最高版本的包。而後自動生成 yarn.lock 文件,並生成緩存。

以後再執行 yarn install,會對比 package.json 中依賴版本範圍和 yarn.lock 中版本號是否匹配。

  1. 版本號匹配,會根據 yarn.lock 中的 resolved 字段去查看緩存, 若是有緩存,直接copy,沒有緩存則按照 resolved 字段的url去下載包。
  2. 版本號不匹配,根據 package.json 中的版本範圍去 registry 查詢,下載符合版本規則最新的包,並更新至 yarn.lock 中。

模塊扁平化

上面提到,在安裝依賴時,會解析依賴構建出依賴關係樹。 好比我項目的首層依賴(即當前項目的dependence和devDependences中的依賴,不包括依賴的依賴)中有A,B,C三個包,A 和 B包同時依賴了相同版本範圍的D包。那麼這部分的依賴關係樹是這樣的:

├── A    				
│ └── D    
├── B    				
│ └── D  
├── C 
複製代碼

若是按照這樣的依賴關係樹直接安裝的話,D模塊會在A包和B包的 node_modules中都安裝,這樣會致使模塊冗餘。

爲了保證依賴關係樹中沒有大量重複模塊,yarn在安裝時會作dedupe(去重)操做,它會遍歷全部節點,逐個將模塊放在根節點下面,也就是當前項目的 node-modules 中。當發現有相同的模塊時,會判斷當前模塊指定的 semver 版本範圍是否交集,若是有,則只保留兼容版本,若是沒有則在當前的包的 node-modules 下安裝。
因此上面的說的狀況,最終安裝完成是下面這樣的,A,B,C,D包都會安裝在第一層 node-modules 下。

├── A    				
├── B    				
├── C 
├── D
複製代碼

若是A包和B包依賴的是不兼容的版本,假設A包依賴的是D@1版本的包,B包依賴的是D@2版本。則最終安裝的結果以下:

├── A    				
├── B    
│ └── D@2 
├── C 
├── D@1
複製代碼

當代碼中 requireimport 某個模塊時,會從當前 packagenode-modules 裏中開始找,找不到就到當前package的上一層 node-modules 裏找,這樣一直找到全局的node_modules。 因此上面的安裝的樹結構,能夠保證每一個 package 都能獲取到所須要版本的包。

經常使用的yarn命令

  1. yarn install 安裝依賴
yarn install / yarn  在本地 node_modules 目錄安裝 package.json 裏列出的全部依賴
yarn install --force 從新拉取全部包,即便以前已經安裝的(因此之後別在刪除node-modules了...)
yarn install --modules-folder <path> 爲 node_modules 目錄指定另外一位置,代替默認的 ./node_modules
yarn install --no-lockfile 不讀取或生成 yarn.lock 文件
yarn install --production[=true|false] / --production / --prod 只安裝 dependence下的包,不安裝 devDependencies 的包

複製代碼
  1. yarn add
yarn add package-name 會安裝 latest 最新版本。
yarn add <package...>  安裝包到dependencies中
yarn add <package...> [--dev/-D]  用 --dev 或 -D 安裝包到 devDependencies
yarn add <package...> [--peer/-P]  用 --peer 或者 -P 安裝包到 peerDependencies
yarn add <package...> [--optional/-O] 用 --optional 或者 -O 安裝包到 optionalDependencies 
yarn add <package...> [--exact/-E] 用 --exact 或者 -E 會安裝包的精確版本。默認是安裝包的主要版本里的最新版本。 好比說, yarn add foo@1.2.3 會接受 1.9.1 版,可是 yarn add foo@1.2.3 --exact 只會接受 1.2.3 版。
yarn add <package...> [--tilde/-T]  用 --tilde 或者 -T 來安裝包的次要版本里的最新版。 默認是安裝包的主要版本里的最新版本。 好比說,yarn add foo@1.2.3 --tilde 會接受 1.2.9,但不接受 1.3.0。
複製代碼
  1. yarn config 管理配置文件
yarn config get <key> 查看配置key的值
yarn config list 查看當前的配置
yarn config delete <key> 從配置中刪除配置key
yarn config set <key> <value> [-g|--global] 設置配置項 key 的值爲 value
複製代碼
  1. 其餘經常使用命令
yarn list 查詢當前工做文件夾全部的依賴
yarn info <package> [<field>]  查看包信息,能夠查看特定
yarn remove <package...>  從依賴裏移除名包,同時更新你 package.json 和 yarn.lock 文件。
yarn <script> [<args>] 執行用戶自定義的腳本
複製代碼
  1. 詳細日誌模式 運行yarn命令時,增長參數 --verbose,這對排查錯誤時頗有幫助
yarn <command> --verbose
複製代碼

能夠打印出執行的詳細信息(建立目錄、複製文件或 HTTP 請求等)

歡迎關注個人公衆號「前端小苑」,我會按期在上面更新原創文章。

相關文章
相關標籤/搜索