npm中package-lock的resolevd衝突

前言

上次講到用package-lock鎖版本來保證項目的一致性和穩定性。但在使用過程中,發現同一項目的不同開發,在install安裝依賴之後,package-lock.json文件會出現衝突,下面將針對這些問題進行探究和解決。

一、合分支時由於版本不同造成的衝突

簡而言之,就是兩個開發人員安裝了不同版本的新npm包,lock文件不同,從而導致的衝突。這類都屬於應有的衝突,只要由merge人員覈對版本號,選擇正確的版本,統一項目的lock版本即可。

二、package-lock中的resolve字段被不同環境的npm registry改寫,從而導致的很多衝突

這也是此次要探究的重點。明明版本號都是相同的,但是對應資源的下載地址不同,合分支時出現了很多的衝突。

1、resoled含義

官網npm配置可知,resolved字段表示相對於倉庫源registry的一個包下載地址。如果這個包的下載地址和倉庫源不在同一服務上,那麼這個地址會是一個絕對路徑。

(在項目中,發現有的包,如【npx】包下面的依賴項的resolved值爲false,安裝發現,直接安裝npx此包,就包含了所有的下級依賴項(因此會比一般的tgz文件大,有5M,一般只會有7K。),所以可能下級依賴項的resolved值爲false,不會再根據下級依賴包再去安裝。)

2、出現衝突的原因及解決方式

(1)本地registry的配置不同,如有的是淘寶鏡像,有的是公司的等等。

本地registry的配置不同,會導致install時package-lock.json被改寫,造成衝突。所以爲了規避這個問題,需要在團隊內統一npm registry,可以在項目根目錄中使用.npmrc配置文件來配置項目級別的registry來進行統一。
如在his中的.npmrc

registry=http://npm.guahao-inc.com

(2)環境及npm和node版本不同

據反饋,在不同電腦上,由於npm和node,操作系統的不同,即便在項目裏設置了統一的.npmrc配置,在項目中執行npm install之後,package-lock.json文件會有些不同:
發現某些子依賴項的resoled:false,可能會換成“”空字符串,甚至換成url地址,造成衝突,還有就是可能增加optional字段,前者如上文所述,false替換爲“”不會造成問題,因爲都是不會再去重新下載子依賴。


示例:log-update這個包,是一個父依賴包和子依賴包都有resoled地址的,下載發現,父依賴包鏈接只會下載父依賴,他的所有子依賴會根據對應的resoled字段再去下載;而npx這個包,子依賴resolve的字段爲false或“”,根據父依賴地址安裝會發現其實已經安裝了所有的子依賴,所以resoleced字段爲false。

由於缺少官方說明,爲了重現和避免此類問題,我做了如下調研比對

對比node和npm版本

統計了團隊內大家的node和npm版本情況,覈查對應情況,在不刪除lock文件前提下,不同條件下分別執行install,結果如下

電腦 npm版本 node 版本 npx包子依賴的resolved值
mac 6.4.1 10.12.0 false
mac 6.4.1 10.15.3 false
mac 6.4.1 10.16.0 false
mac 6.13.4 10.15.3 false
mac 6.14.4 10.15.3 false
mac 6.7.0 11.13.0 false
windows 6.13.4 10.15.3 ""和url並存
windows 6.7.0 11.14.0 ""和url並存
windows 6.13.4 11.14.0 ""和url並存
初步結論

通過比對不同系統和npm及node版本在install npx這個包的情況:

1、mac下常用的node和npx版本在install之後,lock文件無差別,子依賴resolved字段內容爲false

2、windows下常用的node和npx版本在install之後,lock文件無差別,子依賴resolved字段內容爲“”或url地址。

可以初步得出,package-lock文件中存在的resolved的字段不一致,在同一系統和同一編輯器內不會出現,與常用的npm及node版本無關,可能是windows和mac系統下不同編輯器對resolved字段解析爲“”或false的方式不同。

另:

刪掉lock文件,後續的npx包install安裝時,子依賴沒有了resoleved字段(即爲“”,爲false,都是沒有這個字段,而是bundled: “true” . (表示在父依賴中已綁定安裝此子依賴),mac和windows統一。

三、解決方案

1、使用工具自動合併lock文件衝突

對於兩個不同install生成的lock文件,合併分支時發生衝突,npm官方做出了一定解釋並提供了一個專門用於自動合併lock文件衝突的工具:npm-merge-driver,這個工具設置的算法會合並兩個分支的所有依賴樹,綜合成一個新的lock文件。

此方法親測可行有效,在install時對於lock文件的衝突,會自動合併,能幫助開發者一鍵解決lock文件的衝突。

! 但此方式並沒有徹底解決mac和Windows(也可能是編輯器差異)導致的resolved:“”和false不同的問題。lock文件統一後,在mac中install,原本統一的resolved:""依舊會更新爲false。(不過“”和false起到的是一樣的作用,不影響代碼)

2、統一大版本node及npm,刪除原有resolved:false或“”的依賴包,重新install。

追本溯源,出現resolved:"false"和resolved: ''差異的依賴包,其實是子依賴已經bundled進父依賴的依賴包,從而子依賴的下載源爲false或“”,因而針對bundled的npm依賴包,如npx,可以刪除古早的這個npx依賴包,重新install。這樣,package-lock文件會重新更新,原有的resoleved字段不再展示,而是展示一個“bundled: “true”的字段”。

此方式更新過lock文件後在mac和windows下重新install都不會再出現衝突。由官網有關resoleved和bundled所述:對於bundled的依賴,不會再包含resolved字段和integrity字段,這可以完全解決當下的衝突問題。

考慮到npm和node版本不同,還有可能導致增加optional字段(true可選,false不可選),因而最好統一node和npm的大版本

總結

對於resoled的衝突,解決方式如下

  1. 統一配置項目.npmrc中的registry地址
  2. 對於bundled的依賴,如npx,最好重新安裝,避免resolved字段差異(推薦)
  3. 對於lock文件衝突,如一時難以手動確認合併方式,推薦使用npm-merge-driver
  4. 建議統一node及npm大版本,目前已測可行爲:node >10.15.3 npm >6.13.4

附錄:參考

npm官方文檔

簡書:registry統一

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章