yarn 是在工做中離不開的工具,但在工做中,不少人基本只會使用 yarn install
,並且會手動刪除 node-modules
,或刪除 yarn.lock
文件等不規範操做。本文將從一些基礎的知識點開始介紹,按部就班的讓你對 Yarn
有一個更深刻的瞭解,來保證規範的使用yarn,避免一些隱藏bug的產生。
本文主要介紹如下知識:前端
- 什麼是registry
- 依賴的版本含義及寫法
- 依賴類型及區別(
devDependences
,devDependences
,peerDependences
,optionalDependencies
,bundledDependencies
)- 緩存介紹
yarn.lock
文件做用及介紹yarn install
安裝依賴的過程- 依賴關係樹的模塊扁平化
- 經常使用的
yarn
命令介紹
registry
是 模塊倉庫提供了一個查詢服務,也就是咱們常說的源。以yarn官方鏡像源爲例,它的查詢服務網址是https://registry.yarnpkg.com
。vue
這個網址後面跟上模塊名,就會獲得一個 JSON 對象,裏面是該模塊全部版本的信息。好比,訪問 https://registry.npmjs.org/vue
,就會看到 vue 模塊全部版本的信息。node
registry 網址的模塊名後面,還能夠跟上版本號或者標籤,用來查詢某個具體版本的信息。 https://registry.yarnpkg.com/vue/2.6.10
webpack
上面返回的 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
中依賴版本範圍的表示方法有如下幾種:數組
表示 | 含義描述 |
---|---|
<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 |
若是沒有指定運算符,默認爲 =緩存
表示 | 含義描述 |
---|---|
2.0.0 - 3.1.4 | >=2.0.0 <=3.1.4 |
0.4 - 2 | >=0.4.0 <=2.0.0 |
版本號中缺乏的那些部分會用數字 0 填充。
表示 | 含義描述 |
---|---|
* | >=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 |
修訂號
變動。同時使用字符 ~ 和主版本號,代表容許 次版本
號變動。表示 | 含義描述 |
---|---|
~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 |
表示 | 含義描述 |
---|---|
^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
中會準確的存儲每一個依賴的具體版本信息,以保證在不一樣機器安裝能夠獲得相同的結果。
下面以@babel/code-frame爲例,看看yarn.lock 中會記錄哪些信息。
"@babel/code-frame@7.0.0-beta.54"
包的name和語義化版本號,這些都來自package.json中的定義。version
字段,記錄的是一個確切的版本。resolved
字段記錄的是包的URL地址。其中hash值,即上文的 dist.shasum
。dependencies
字段記錄的是當前包的依賴,即當前包在 package.json
的 dependencies
字段中的全部依賴。Yarn
在安裝期間,只會使用當前項目的 yarn.lock
文件(即 頂級 yarn.lock
文件),會忽略任何依賴裏面的 yarn.lock
文件。在頂級 yarn.lock
中包含須要鎖定的整個依賴樹裏所有包版本的全部信息。
yarn.lock
文件是在安裝期間,由 Yarn
自動生成的,而且由yarn來管理,不該該手動去更改,更不該該刪除yarn.lock文件,且要提交到版本控制系統中,以避免由於不一樣機器安裝的包版本不一致引起問題。
首次執行 yarn install
安裝,會按照 package.json
中的語義化版本,去向 registry
進行查詢,並獲取到符合版本規則的最新的依賴包進行下載,並構建構建依賴關係樹。 好比在 package.json
中指定 vue 的版本爲 ^2.0.0
,就會獲取符合 2.x.x
的最高版本的包。而後自動生成 yarn.lock
文件,並生成緩存。
以後再執行 yarn install
,會對比 package.json
中依賴版本範圍和 yarn.lock
中版本號是否匹配。
yarn.lock
中的 resolved
字段去查看緩存, 若是有緩存,直接copy,沒有緩存則按照 resolved
字段的url去下載包。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
複製代碼
當代碼中 require
或 import
某個模塊時,會從當前 package
的 node-modules
裏中開始找,找不到就到當前package的上一層 node-modules
裏找,這樣一直找到全局的node_modules。 因此上面的安裝的樹結構,能夠保證每一個 package
都能獲取到所須要版本的包。
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 的包
複製代碼
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。
複製代碼
yarn config get <key> 查看配置key的值
yarn config list 查看當前的配置
yarn config delete <key> 從配置中刪除配置key
yarn config set <key> <value> [-g|--global] 設置配置項 key 的值爲 value
複製代碼
yarn list 查詢當前工做文件夾全部的依賴
yarn info <package> [<field>] 查看包信息,能夠查看特定
yarn remove <package...> 從依賴裏移除名包,同時更新你 package.json 和 yarn.lock 文件。
yarn <script> [<args>] 執行用戶自定義的腳本
複製代碼
--verbose
,這對排查錯誤時頗有幫助yarn <command> --verbose
複製代碼
能夠打印出執行的詳細信息(建立目錄、複製文件或 HTTP 請求等)
歡迎關注個人公衆號「前端小苑」,我會按期在上面更新原創文章。