[譯] 將專案遷移到 Yarn 然後又遷回 npm

Russ_Zhong發表於2018-07-03

去年,我們決定將所有 JavaScript 專案從 npm 遷移到 Yarn

之所以這樣做,有以下兩個主要原因:

  • yarn installnpm install 快 20 倍。npm install 在我們的一些大型專案中往往需要消耗 20 分鐘以上。
  • Yarn 的依賴鎖定比 npm 的更加可靠。

檢視去年的一篇部落格(連結在上方給出了)可以瞭解更多。

使用 Yarn 的 13 個月

Yarn 解決了我們在使用 npm 時所遇到的一些煩人的問題,但是它自身也帶來了許多的問題:

  • Yarn 出現了非常不好的迴歸,這讓我們不太敢升級它。
  • Yarn 經常會在你執行 addremove 或者 update 的時候生成無效的 yarn.lock 檔案。這就使得開發者需要做一些冗餘的工作來 removeadd 這些有衝突的包,直到 Yarn 找出解決方案以使得 yarn check 能夠通過,才能改善這一現象。
  • 很多時候,因為 Yarn 進行了優化,所以當開發人員在拉取專案的最新變化後執行 yarn 時,他們的 yarn.lock 檔案會變的很“髒”,。為了解決這個問題,需要開發人員推送與他們工作無關的更改。Yarn 需要在使用命令 yarn lock 更新時立即優化,而不是在下一次使用 yarn 命令時。
  • yarn publish 不是很可靠(存在問題?)(tracked issues #1, tracked issue #2),這意味著我們不得不使用 npm publish 來發布包。這使我們很容易忘記在這種特殊場景下需要使用 npm,並且意外地使用 Yarn 釋出包導致釋出的包無法安裝。

不幸的是,在我們使用 Yarn 的 13 個月裡,這些工作流很混亂的問題一個都沒有被修復。

在經歷了特別痛苦的幾個星期(經常開 15 分鐘的 Yarn 問題解決會議)後,我們決定迴歸到 npm。

npm 6

在我們使用 Yarn 的這段時間裡,npm 做出了重大的改善,以期擁有 Yarn 的速度及其依賴鎖定的可靠性 —— 這些問題曾使得我們轉向了 Yarn。就像 Yarn 裡面的那些煩人的問題一樣,我們無法離開這些好處,因此我們首先需要驗證一下 npm 是否解決了原來的那些問題。

我們決定嘗試一下當前能夠獲取到的最新版本的 npm,npm@​6.0.0,因為我們想要利用盡可能多的速度改善和 bug 修復。據傳 npm​@6.0.0 是一個相對較小的重大更新,因此我們認為使用它不會冒很大的風險。不可思議的是,npm​@5.8.1 使我們在 6.0.0 釋出之前測試過的版本,在我們許多開發工程師的機器上(OS X Sierra/High Sierra,node​@v8.9.3)安裝依賴失敗了,出現了許多錯誤(比如 cb() never called!)。

速度

我們很高興地發現,在每個包管理器試用五個案例後,npm的平均成績與 Yarn 相當:

  • Yarn:$ rm -rf node_modules && time yarn:126s
  • npm:$ rm -rf node_modules && time npm i:132s

在正確的方向上邁出了正確的一步。我們的試驗還會繼續 :)。

Locking

npm 在 npm@​5.0.0 引入了 package-lock.json 等價於 Yarn 中的 yarn.locknpm shrinkwrap 仍然可以被用於建立 npm-shrinkwrap.json 檔案,但是根據 npm 文件的描述,這些檔案的使用場景有了一些不同:

推薦的 npm-shrinkwrap.json 使用場景是通過釋出過程在登錄檔中部署的應用程式:例如,用作全域性安裝或 devDependencies 的守護程式和命令列工具。對於庫作者釋出這個檔案非常不鼓勵,因為這會阻止終端使用者控制傳遞依賴關係更新。

另一方面,package-lock.json 檔案不跟隨包一起釋出。這相當於 Yarn 如何不尊重依賴關係的 yarn.lock 檔案 —— 父專案管理自己的依賴關係和子依賴關係(但要注意的是,如果庫的確在不應該的時候釋出 npm-shrinkwrap.json 檔案,那麼您將不得不使用它們的依賴性)。

Locking 驗證

npm 沒有與 Yarn 的 yarn check 相對應的功能,但 yarn check 看起來像一些人(如 Airbnb)使用 npm ls> / dev / null 來檢查安裝錯誤,如缺少軟體包。

不幸的是,檢查將 peer 依賴警告視為錯誤,這使得我們無法使用它,因為我們經常通過 CDN 實現 peer 依賴關係

npm 最近引入了 npm ci,很幸運它提供了一些驗證功能。npm ci 確保了 package-lock.jsonpackage.json 在同一驗證形式下是同步的。它同樣提供了一些其它好處 —— 檢視文件瞭解更多。

之前在使用 npm 時,我們從未意識到 install 的不一致性(似乎只有 Yarn 有這些問題 :)),因此我們認為只使用 npm ci 是安全的。

使用 Yarn 的煩惱

除了追上 Yarn 的速度和擁有 Yarn 依賴關係鎖定的保證之外,npm 似乎沒有任何使用 Yarn 時困擾我們的問題!

Check, check, check

npm​@6.0.0 為我們檢查了所有的盒子,所以我們決定以後繼續使用它!

在對我們的一個服務進行為期三週的試驗成功後,我們將剩餘的其它服務和專案也遷移到了 npm!

建議

deyarn

我們已經發布了一個叫做 deyarn 的開源模組,它可以幫助你將專案從 Yarn 遷移到 npm。

通過 engines 強制使用 npm

我們推薦使用 engines 選項,它可以讓你避免在應該使用 npm 的時候卻意外地使用了 Yarn 了。

我們已經新增了一個配置如下:

{
    "engines": {
    "yarn": "NO LONGER USED - Please use npm"
    }
}
複製程式碼

對於我們內部專案的所有的 package.json 而言。deyarn(連結在上方給出)會幫你管理 :)。

試試它!

我們測試過這個工作流能夠滿足我們的需求,並且我們也推薦你使用它。如果你需要一個極致快速的包管理器,然後你會發現 Yarn 仍然是最佳之選。但是如果你需要一個建立起來比較簡單的包管理器,我們發現 npm 6 在速度與可靠性上保持了很好的平衡。

想要幫助我們使用 npm 建立未來的社群嗎?

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章