作者:京東零售 陳震
在前端工程化中,JavaScript 依賴包管理是非常重要的一環。依賴包通常是專案所依賴的第三方庫、工具和框架等資源,它們能夠幫助我們減少重複開發、提高效率並且確保專案可以正確的執行。
目前比較常見的前端包管理器有 npm 和 Yarn,npm 是 Node.js 自帶的包管理器,它可以安裝、共用和分發 node.js 模組。最近pnpm也挺火的,通過並行下載和安裝依賴項,在執行安裝、更新、刪除等操作時也更快。
但無論使用哪個包管理器,都要通過 package.json 檔案的版本控制功能,保證在不同開發環境中的一致性。那麼,package.json是如何進行依賴包管理的呢?我們來一起深入瞭解一下package.json的設定方式。
根據package.json規範,依賴包被大致分為以下幾種:dependencies、devDependencies、optionalDependencies、peerDependencies和bundledDependencies總共5種。dependencies和devDependencies這兩項是我們使用較為頻繁的。
工程在生產環境下也需要使用的依賴,例如react、antd等,使用npm安裝外掛時,會預設寫入dependencies,也可以使用-P或--save-prod字尾。
工程只有開發環境需要,生產環境不需要的依賴,例如eslint、babel等,使用-D或--save-dev來寫入devDependencies。
顧名思義,依賴是可選的,它們只有在執行時需要使用某些功能時才會被引入。通常用於實現某些可選的功能或優化。例如,一個包可能依賴於某個庫來實現某種高階功能,但是這個庫在某些環境下不存在或不可用。在這種情況下,可以將該庫宣告為可選依賴項,並在程式碼中檢查該依賴項是否存在,然後根據情況來決定是否使用該高階功能。使用這個功能的工程比較少,使用-O或--save-optional來寫入optionalDependencies。
工程需要和這個依賴配套使用,一般用於解決外掛依賴的核心庫的版本和主專案依賴的核心庫的版本不一致的問題,常見於開發配套外掛。例如[email protected]宣告了:
"peerDependencies": {
"vue": "^3.2.0"
}
表明[email protected]需要和vue@^ 3.2.0一起安裝和使用,否則可能會出現異常。使用-O或--save-optional來寫入optionalDependencies。
工程依賴於某些特定的依賴項,並且希望在執行時不必再次下載它們,則可以使用該選項。npm pack會將這些依賴一同放入生成的包中,並且在npm install時本工程,這些依賴項也會被一同安裝。使用-B或--save-bundle來寫入bundledDependencies。
看到這裡你可能會有點疑問,為什麼npm沒有提供類似--save-peer的指令來寫入peerDependencies呢?原因是peerDependencies暗示本工程將會被其他主模組使用,但是主模組本身並不需要在專案程式碼中顯式使用。因此官方沒有支援這一指令。
一般情況下,以上依賴設定(除了bundledDependencies)都需要指定依賴的版本號,版本號遵循semver語意化版本規範(Semantic Versioning)命名規則,可以用下圖表示,如2.1.0、3.1.4-beta.2等。
可選的-tags即先行版本號,可以作為釋出正式版之前的版本,格式是在修訂版本號後面加上一個連線號(-),再加上一連串以點(.)分割的識別符號,識別符號可以由英文、數位和連線號([0-9A-Za-z-])組成。
在 npm 的依賴的規則中,還有~、>、<、=、>=、<=、-、||、x、X、*
等符號來描述適用的版本範圍;
^ :表示只鎖定major,不小於指定版本號的版本範圍。例如^1.1.0
,代表>=1.1.0 <2.0.0
的版本範圍。
~ :表示鎖定major和minor,不小於指定版本號的版本號。例如~1.1.0
,代表>=1.1.0 <1.2.0
的版本範圍。
x、X、*:表示萬用字元。例如1.1.x
,也代表>=1.1.0 <1.2.0
的版本範圍。
預設情況下,若指定了一個版本範圍,npm會在範圍內安裝最新版本的依賴。當使用 npm install XX 時,會安裝當前最新版本,並在版本號前預設加上 ^ 符號。因此在安裝執行老專案時,很容易出現安裝依賴後,專案啟動報錯的情況,原因就是某些依賴沒有做到很好的向下相容,導致重新安裝的版本太高造成相容性錯誤,此時需要定位錯誤依賴並回退版本。
npm install核心流程大致分為以下5步:
1、npm 向 registry 查詢依賴壓縮包的網址。
2、下載壓縮包,存放在cache目錄,供下次安裝時使用。
3、解壓壓縮包到當前專案的node_modules目錄。
4、把所有安裝的包資訊寫入package-lock.json,供下次安裝時使用。
5、繼續處理依賴的依賴。
install的過程速度也和每一個步驟息息相關:
(1)共用工程package-lock.json,可以避免向registry查詢的步驟,並且保證不同環境下安裝包的一致性。
(2)使用下載速度快的registry映象(例如jd映象)。
(3)預先進行依賴關係分解構建依賴關係,然後最後再並行下載(例如yarn)。
希望以上的介紹能夠幫助你更好的理解npm的依賴管理。