[譯] Yarn - Javascript 新一代套件管理

本文轉譯並補充自 - Yarn: A new package manager for JavaScriptvue

在 Javascript 社羣中,開發者們分享成千上萬的原始碼讓我們能夠省去重造輪子的時間,不用從新打造函式庫,框架,元件等。
而每段原始碼都有可能相依於其餘原始碼片斷,這些相依的程式碼一般會透過套件管理(package manager)來管理。
其中在 Javascript 裡,最熱門的就屬 npm ,在上面有 5 百萬個開發者,套件庫提供了超過 300,000 模組,更驚人的是每個月有超過 5 億次的下載量。node

<!--more-->git

Facebook 的團隊使用 npm 客戶端工具已經好幾年了,隨著原始碼大幅的成長,我們開始遭遇到一些問題包含了一致性,安全性,效能方面。
在嘗試解決遇到的每一個問題之後,我們開始創造一套新的、更可靠的解決方案來協助我們管理相依性的問題。github

這東西叫作 Yarn - 一個快速,可靠,更安全取代 npm 客戶端的工具。vue-cli

我們很開心的發佈釋出 Yarn 為開放原始碼專案,並和 Exponent, Google, Tilde 協做。使用 Yarn ,開發者仍然存取 npm 套件庫 (npm registry),但能夠更快速的安裝和管理套件,保持套件的一致性,可靠的離線環境的安全性
Yarn 讓開發者在使用這些分享的開源碼時能夠自信的更新,替換,所以開發者們能夠專注在他們的任務 - 開發產品和功能。npm

npm registry 收錄開發者提供模組的檔案庫與其對應資訊列表,翻譯為註冊表,但譯者認為套件庫較能表達其意義。json

Facebook 管理 Javascript 模組的演化

在使用套件管理以前,常見的狀況就是 Javascript 開發者直接透過 CDN 存取相依的片斷原始碼。初版的 npm 在 Nodejs 出現之後很快的就被開發出來,很快的它就成為世界上最熱門的套件管理工具。創造了數以千計的新開源專案以及比以往更多的開發者分享他們的成果。windows

Facebook 的許多專案像是 React,也相依於 npm 上面的程式碼。然而當我們內部成員增長的時候,當不一樣的成員與機器要安裝這些相依模組就開始面臨到一致性的問題,大量的時間花在處理安裝相依模組。同時由於 npm 會自動執行一些相依的程式碼而伴隨著安全性的議題。於是我們嘗試開發一個解決方案去處理這些問題。安全

嘗試擴展 npm 客戶端工具(npm client)

起初,跟著官方的最佳實踐,我們只檢查 package.json 然後要求開發者手動執行 npm install。這對開發者來說運做還算良好,不過卻在我們持續整合環境(continuous integration environments)中出現問題,因為該環境處於沙箱模式,並且基於安全性的因素不與外部網路連接。bash

接著我們的解決方案則是檢查全部的 node_modules 然後存到檔案庫裡套件庫(registry)。雖然它能運做,但同時讓一些簡單的操做變得很是困難。舉例來說更新次版號的 babel 會產生高達 800,000 行的 commit 導致完整下載,執行 lint 規則檢查像是不符合規範的 utf8 字節序列,windows 行結尾,非 png 壓縮圖片,等等等這些任務變得很難完成。合併 node_modules 的修改極可能就耗掉開發者一成天。

我們的版本控制團隊也指出那些我們 check-in 的 node_modules 目錄包含了太大量的 metadata。例如:React Native 的 package.json 現在就有 68 個相依的模組,然後在執行 npm install 之後 node_modules 目錄包含了 121,358 個檔案。

我們作了最後的嘗試 - 補強 npm client,使其適用於 Facebook 的工程師。協助處理那些我們須要安裝的大量程式碼。
我們決定 zip 打包整個 node_modules 目錄,然後上傳到內部的 CDN,之後開發者和持續整合環境均可如下載一樣的檔案。
這讓我們能夠從版本控制中移除數以千計的檔案,不過為了達到這個功能開發者提取和建置時須要內部的存取權限。

另外,我們在處理問題的時候也會須要使用 shrinkwrap 的功能,這讓我們能夠鎖定特定相依套件的版本。預設 shrinkwrap 並不會產出,所以若是工程師忘記下指令的話那麼版本又會不一致,因此我們寫了一個工具用來驗證 shrinkwrap 的檔案內容是否符合 node_modules。

這些檔案是超大的 JSON blob 並且 keys 沒有排序,所以要修改它們勢必會產生大量的輸出,然後難以審核 commit。
為瞭解決這個問題我們須要加入額外的 script 來排序它們。

最後,使用某些版本的 npm 更新單一的相依套件可能會連帶更新一些不相關的檔案。這將導致每一次更新比預期的更大,並且必須將其納入整個提交 node_modules 或更新到 CDN 的流程,這不是開發者樂於見到的狀況。

開發新的客戶端工具(client)

比起持續補強 npm 客戶端工具,我們選擇嘗試更全面的看待這些問題。假如我們開發一個全新的客戶端工具能夠徹底解決我們曾遭遇過的這些問題呢?倫敦辦公室的 Sebastian McKenzie 開始嘗試挑戰這個點子,這點子的潛力讓我們很興奮。

一開始,我們開始詢問業界的開發者們,發現他們都面臨一系列類似的問題,嘗試使用類似的解決方案,一次解決一個遭遇的問題。
很明顯的社羣正面臨通過合做來解決這一系列的問題,而我們能夠開發出一個方案適用於任何人。
獲得 Exponent, Google, Tilde 工程師的協助,我們開發出了 Yarn 並在各個主流的 JS 框架中測試與驗證其效能,還包括了 Facebook 之外開發團隊的使用情境。今天(2016-10-11)我們很開心與社羣分享這個成果。

Yarn 介紹

Yarn 是一個新的套件管理工具,主要用來取代既有的工做流程中 npm client 或其餘套件管理工具的部分(安裝、更新、移除套件等的指令集),同時兼容於現有的 npm registry。大部分的功能與操做與既有的流程相同並且更快速,安全,可靠。

任何套件管理工具的主要功能是安裝模組套件 - 一個特定用途的片斷程式碼 -- 從全球通用的套件庫(registry)中安裝到開發者本地的環境中。每一個套件可能會相依於其餘套件。一個典型的專案可能具備數十,數百甚至上千個相依的模組。

這些相依的模組都有版號並且基於語意化版本規範(semver)安裝或更新。語意化版本規範了版號的意義與相關符號的規則,這些規則能夠讓我們知道該版本是否相容於上個版本,是屬於加入新功能,或者只是修復 Bug,然後基於這些規則來確認是否能更新或該更新到什麼版號。

然而語意化版本規範(semver)須要仰賴套件開發者不犯任何錯誤 - 若是沒有鎖定相依套件的版本,新的 Bug 或錯誤的修改極有可能就被安裝了。

架構

在 Node 的生態圈裡,相依的模組會被放在專案下的 node_modules 目錄。然而隨著合併重複模組的狀況,這個檔案結構可能不一樣於真實的目錄結構

譯者補充:npm 顯示的相依階層跟實際目錄結構不一樣。

npm 客戶端工具安裝相依模組到 node_modules 目錄並不會依據模組結構(不確定性)。意味著它只會依序安裝模組,而 node_modules 目錄中的結構每一個人多是不一樣的。這些差異可能最形成『我能夠跑啊』的狀況,一般須要很長的時間去找問題點。

Yarn 透過 lockfiles(yarn.lock) 鎖定機制和一套安裝邏輯解決了這些關於版本和不確定性的問題使其具備可靠性與確定性。這些 lockfiles 會鎖定安裝的相依模組為特定版本,確保安裝在每臺機器上的 node_modules 結果是一致的。lockfile 使用精準的格式撰寫與排序的鍵 (keys)來確保修改動做最小化,同時在審核的時候比較單純。

整個安裝流程拆解為下面三個步驟:

  1. 辨識:Yarn 透過發送請求到套件庫(registry)開始解析相依的套件模組,然後層層遞迴的檢查每一個模組相依的東西。

  2. 擷取:下一步,Yarn 檢查全域快取的目錄(global cache directory)看看是否有須要的套件已經被下載了。若是沒有,Yarn 開始下載模組的壓縮包(tarball)並將其存放到全域快取的目錄下,因此這表示我們是能夠離線工做的,同樣的模組不須要下載兩次。您也能夠將相依的模組使用壓縮檔的形式加入版控來達到徹底離線安裝。

  3. 連結:最後,Yarn 從全域快取(global cache)複製所需的檔案到本地的 node_modules 完成整個流程。

因為清楚的分拆這些步驟並確保一致的結果,Yarn 便有能力平行處理每個操做,讓整個安裝流程更快速。
在某些 Facebook 專案 ,Yarn 簡化了整個安裝流程,從幾分鐘到只剩幾秒鐘。Yarn 也提供互斥的機制確保多個執行的指令不會互相干擾。

Yarn 會嚴格把關整個安裝流程,協助您掌控安裝流程。套件的檢核資訊會存放在 lockfiles(yarn.lock )確保每一次安裝的都是一樣的套件模組。

功能

除了確保安裝流程更迅速和可靠,Yarn 也支援其餘功能讓我們更方便的管理相依套件,簡化工做流程。

  • 與 npm 和 bower 相容,同時也支援不一樣的套件庫(registry)

  • 嚴格限制安裝套件的 Licenses 和輸出相關訊息

  • 提供 API 協助建置工具取得輸出一些工具的資訊(譯者註:此部分還沒有完成,更多資訊參考此 Issue

  • 精簡有意義且美觀的指令輸出資訊

使用 Yarn 於正式環境

在 Facebook 我們已經在正式產品中使用 Yarn,同時其運做很是良好。使得許多專案在管理相依套件上更加方便。
我們讓工程師即使在每次的移動中都能夠快速的離線建置,加速整個工做流程。

您能夠看到 Yarn 和 npm 安裝 React Native 的時間差距,具體資料您能夠查閱這裡

入門

最快速的入手方式就是執行

$ npm install -g yarn
$ yarn

# 又或者參考官方文件:https://yarnpkg.com/en/docs/install

yarn 就能夠在工做流程中透過相同或類似的指令取代 npm

  • npm install -> yarn

此指令不需任何參數,yarn 會讀取 package.json 然後從 npm registry 擷取套件並安裝到 node_modules。等同時使用 npm install

  • npm install --save <name> -> yarn add <name>

我們移除 npm 預設不紀錄模組並把 --save 拆開為參數的行為。執行 yarn add <name> 等於 npm install --save <name>

發展

許多人和我們一塊兒建造了 Yarn 來解決常見的問題,我們意識到 Yarn 須要成為一個社羣專案讓更多人使用。Yarn 現在已經釋出能夠在Github上找到,我們為 Node 社羣貢獻最棒的東西就是:使用 Yarn,分享一些點子,撰寫文件,互相支援。我們相信 Yarn 有了一個好的開始,但有了您的幫助它會變得更好。

相關閱讀

相關文章
相關標籤/搜索