這篇文章已經(jīng)被 Adrian Sandu, Marcello La Rocca, Matt Burnett, Nuria Zuazo and Vildan Softic 審稿過(guò)了。
Yarn 是由 Facebo,google,Exponent 和 Tilde 制作的一種新的JavaScript 軟件包管理器??梢栽?a target="_blank" rel="nofollow">官方公告上看到,其目的是解決團(tuán)隊(duì)在 npm 面臨的問(wèn)題,即
- 安裝包不足夠 快/連續(xù)
- 有安全隱患,npm 允許安裝包執(zhí)行代碼
但是,別慌! 這并不是說(shuō)要去完全替代 npm。yarn 是從 npm 注冊(cè)表獲取模塊的唯一的一個(gè)新的CLI 客戶端。對(duì)注冊(cè)表本身沒(méi)有任何的改變——你依舊可以跟以前一樣獲取和發(fā)布包。
現(xiàn)在所有人都應(yīng)該上 Yarn 的宣傳車了嗎?這些都是你用 npm 體驗(yàn)不到的。在這篇文章,我們將比較 npm 和 yarn,你可以比較哪個(gè)更適合你。
Yarn vs npm: 功能上的差異
乍一看,yarn 和 npm 看起來(lái)差不多。當(dāng)我們看下底層的時(shí)候,我們可以知道 yarn 不一樣在哪里。
yarn.lock 文件
packege.json 文件可以讓 npm 和 yarn 跟蹤到項(xiàng)目的依賴,但是其版本號(hào)并不總是很準(zhǔn)確。相反,你可以定義一個(gè)版本范圍。這種方式,你可以選擇包的一個(gè)特定的主要和次要的一個(gè)版本,但允許npm 安裝最新的補(bǔ)丁(可以修正一些錯(cuò)誤)。
在一個(gè)理想世界的語(yǔ)義版本,補(bǔ)丁版本不包含任何重大更改。不幸的是,這并不總是對(duì)的。npm 采用的策略可能會(huì)導(dǎo)致同一package.json文件兩機(jī),具有不同版本的安裝包,可能引入錯(cuò)誤。 npm 采用的策略可能會(huì)導(dǎo)致同一 package.json文件兩機(jī),安裝不同版本的安裝包,可能會(huì)造成引入錯(cuò)誤。
為了避免包版本引入錯(cuò)誤,一個(gè)確切的安裝版本被固定在一個(gè) lock 文件中。每次加入一個(gè)模塊, yarn 便創(chuàng)建(或更新)一個(gè) yarn.lock 文件。 這種方式可以保證另一臺(tái)機(jī)器上安裝同樣的包,同時(shí)還可以在package.json中定義一系列允許的版本。在 npm 中, npm shrinkwrap 命令也可以生成一個(gè) lock 文件,然后 npm install 在讀 package.json 前,先從 lock 文件中讀取,就像 yarn 先讀 yarn.lock文件先一樣。重要的區(qū)別是 yarn 總是創(chuàng)建和更新 yarn.lock,而 npm 不會(huì)只創(chuàng)建一個(gè)默認(rèn)的并且僅僅在 npm-shrinkwrap.json 存在的時(shí)候更新它。
平行安裝
無(wú)論什么時(shí)候 npm 或者 yarn 需要安裝一個(gè)包,它會(huì)執(zhí)行一系列的任務(wù)。
在 npm,這些任務(wù)按順序并且在每個(gè)包中都執(zhí)行,意味著它將會(huì)在一個(gè)包完全安裝的時(shí)候才跳到下個(gè)包。
yarn 則并行的執(zhí)行這些任務(wù),提高了性能。
相比之下,我在沒(méi)有 shrinkwrap/lock 文件和緩存的情況下, 使用 npm 和 yarn 安裝 express 包??偣舶惭b了 42 個(gè)包。
- npm: 9 秒
- yarn: 1.37 秒
重復(fù)相同的步驟還是產(chǎn)生類似的結(jié)果。然后我安裝 gulp , 結(jié)果有 195 個(gè)依賴包。
- npm: 11 秒
- Yarn: 7.81 秒
似乎較小的區(qū)別取決于正在安裝包的數(shù)量。無(wú)論哪種方式, yarn 始終更快。
更簡(jiǎn)潔的輸出(cleaner output)
默認(rèn)情況下 npm 的輸出非常詳細(xì)。比如,它在執(zhí)行 npm install <package> 的時(shí)候,遞歸地列出所有已安裝的包。相反 yarn 一點(diǎn)都不詳細(xì)。當(dāng)細(xì)節(jié)可以通過(guò)其他命令時(shí),它使用貼切的表情展示出相當(dāng)少的信息(除非是在 windows 上)。

Yarn vs npm: CLI 的區(qū)別
除了一些功能差異, Yarn 也有不同的命令。有些 npm 已經(jīng)刪除的命令,還有修改和添加了一些有趣的命令。
yarn global
不像 npm , 全局操作在使用 -g 或者 --global 標(biāo)志的命令的時(shí)候執(zhí)行,Yarn 命令需要帶有 global 前綴。跟 npm 一樣,特定項(xiàng)目的依賴不需要全局安裝。
global 前綴只對(duì) yarn add, yarn bin,yarn ls 和 yara remove 有效。除了 yarn add,這些命令跟 npm 的是等價(jià)的。
yarn install
npm install 命令會(huì)從 package.json 文件安裝依賴,并且允許添加新的包。
yarn install 僅僅順序的安裝 yarn.lock 或者 package.json 列出的依賴。
yarn add [–dev]
跟 npm install <package>一樣,yarn add <package> 允許你添加或者安裝一個(gè)依賴。
正如命令名稱所暗示的一樣,它添加了一個(gè)依賴,意味著它會(huì)自動(dòng)保存一個(gè)包的引用到 package.json 中,就跟 npm 的 --save 標(biāo)志做的一樣。
Yarn 的 --dev 標(biāo)記添加包作為開發(fā)依賴,就跟 npm 的 --save-dev標(biāo)記一樣。
- yarn add documentation
- npm install documentation
yarn licenses [ls|generate-disclaimer]
在撰寫本文的時(shí)間為止,沒(méi)有npm等效可用。
yarn licenses ls 列出了所有安裝包的許可證。
yarn licenses generate-disclaimer 生成一個(gè)免責(zé)聲明包含所有執(zhí)照的所有包的內(nèi)容。在你的項(xiàng)目中,你必須包括項(xiàng)目的許可證,在這些狀態(tài)下,這是一個(gè)相當(dāng)有用的工具。
- yarn licenses documentation
yarn why
這個(gè)命令窺探到依賴圖,找出為什么包是安裝在您的項(xiàng)目。也許你顯式地添加它,也許這是一個(gè)依賴的包安裝。yarn why幫助你弄清楚。
- yarn why documentation
yarn upgrade [package]
這個(gè)命令會(huì)更新包到符合設(shè)置在 package.json版本的最新的版本并且重建 yarn.lock。這類似于 npm update.
有趣的是,當(dāng)指定一個(gè)包,包會(huì)更新到最新版本和更新package.json中定義的標(biāo)簽。這意味著該命令可能更新包到一個(gè)新的主要版本
- yarn upgrade documentation
yarn generate-lock-entry
yarn generate-lock-entry命令基于 package.json的依賴生成一個(gè) yarn.lock文件。這類似于 npm shrinkwrap。這個(gè)命令應(yīng)該小心使用,當(dāng)通過(guò) yarn add 和 yarn upgrade添加和更新依賴的時(shí)候,lock 文件會(huì)自動(dòng)生成和更新。
- yarn generate-lock-entry documentation
- npm shrinkwrap documentation
穩(wěn)定性和可靠性
Yarn 宣傳火車會(huì)出軌? 在第一天發(fā)布到公眾的時(shí)候,確實(shí)收到了很多的問(wèn)題,但是解決問(wèn)題的速度也是驚人的。同時(shí)聲明,社區(qū)正在努力查找和刪錯(cuò) bugs??磫?wèn)題的數(shù)量和類型, Yarn 對(duì)于大多數(shù)用戶來(lái)說(shuō)是穩(wěn)定的,但可能不適合邊界情況。
注意,盡管包管理器對(duì)您的項(xiàng)目可能是至關(guān)重要的,它只是一個(gè)包管理器。如果出現(xiàn)錯(cuò)誤,重新安裝包也不困難,而不是重新回到 npm 的懷抱。