以水果和蔬菜為例,理解package-lock.json是您最好的朋友

為什麼要保留它們以及何時要拋棄它們?

以水果和蔬菜為例,理解package-lock.json是您最好的朋友

本文目錄:

  • 你是不是遇到和思考過下面的問題?
  • 將第三方包視為一等公民
  • 什麼是 package lock 文件?水果和蔬菜的比喻
  • 包鎖定文件使提交保持不變
  • 刪除程序包鎖定是否安全?
  • 總結

你是不是遇到和思考過下面的問題?

  • 什麼是package-lock.json(或yarn.lock)?
  • 我們為什麼需要它?
  • 我的package-lock.json文件中有衝突
  • 我提交時會忽略它
  • 我要把它刪掉

更糟糕的是,您可能已經刪除了它,並提交了您的 PR 或 push

到master!

如果是這種情況,那麼您已經修改了比預期大得多的源代碼。

您可以控制自己的源代碼,但package-lock.json和yarn.lock文件可確保您的第三方代碼在兩次提交之間不會發生變化

將第三方包視為一等公民

在解開包鎖文件(package lock)的秘密時,理解這一點至關重要。許多開發人員只考慮更改自己的源代碼,但是通過軟件包管理器(如npm和yarn)安裝的第三方代碼也同樣重要,甚至更多。

為什麼?因為它們會導致很難追蹤的bug。

換句話說,如果沒有包鎖文件,您就不知道代碼中發生了什麼變化,從而產生了您可能觀察到的bug。您可能會盯著提交之間的代碼差異,花上幾個小時思考這些更改不可能導致這個問題。

你是對的,這是你看不到的代碼導致問題。

給予您的第三方軟件包應有的尊重,並將他們視為您自己的代碼。

將您的包看作是由多個開發人員提交給您的項目的二進制代碼,就好像它是開源的一樣

讓我們解決以上幾點。


什麼是 package lock 文件?水果和蔬菜的比喻

以水果和蔬菜為例,理解package-lock.json是您最好的朋友

這樣想吧,你喜歡吃水果和蔬菜。每週您都需要購買水果和蔬菜,因此您有一個標準的購物清單,很少更改:

<code>每週購物清單:

水果
蔬菜/<code>

現在,您實際上喜歡某些種類的水果和蔬菜,因此您想使列表更具體:

<code>每週購物清單:

水果
蘋果
葡萄
番茄
蔬菜
洋蔥
土豆
南瓜/<code>

你知道你的口味比這個好一點,所以你添加了一些關於每種水果和蔬菜的細節:

<code>每週購物清單:

水果
蘋果:紅色
葡萄:綠色
番茄:紅色
蔬菜
洋蔥:白色,紅色或棕色

土豆:洗乾淨的或刨皮了的
南瓜:任何一種/<code>

好的,我們有清單,而且相當詳細,但是我們的一些水果和蔬菜還有一些變動的空間。所以我們出去買了清單上的東西,最後得到了一張收據:

<code>收據 - 01/01/2020
蘋果 - 富士
番茄 - 紅色
葡萄 - 綠的
洋蔥 - 棕色
土豆 - 洗淨
南瓜 - 湖南牌/<code>

看到這裡發生了什麼嗎?儘管我們沒有具體說明一些水果和蔬菜的確切類型,但我們不得不購買確切的類型。

現在,當我們回到家,吃了我們的蘋果,煮了我們所有的蔬菜,我們對我們的選擇非常滿意,所以我們保留著收據,下次帶著它去購物,連同我們的清單。

因為我們有收據,上面列出了我們上週購買的商品,所以本週我們購買的商品完全相同。

這可能會一直持續下去,但是假設我們對蘋果的口味發生了變化,所以我們寫了一個新的清單:

<code>每週購物清單

水果:
蘋果:綠的
葡萄:白的
番茄:紅色
蔬菜:
洋蔥:白的紅的或者棕色的
土豆:洗乾淨的或刨皮了的
南瓜:任何一種/<code>

現在,當我們去購物時,我們將不得不購買某種綠色蘋果。結算時,我們得到了如下的收據:

<code>收據- 02/01/2020
蘋果 - 南方青蘋果
番茄 - 紅色
葡萄 - 綠的
洋蔥 - 棕色
土豆 - 洗淨
南瓜 - 湖南牌/<code>

我們已經購買了與上週完全相同的東西,除了我們的蘋果換成了南方青蘋果!

因為我們保留了收據,所以我們能夠記住我們喜歡的所有水果和蔬菜,並繼續購買相同的水果和蔬菜。

但是,如果我們扔掉收據怎麼辦?我們必須從頭開始,並可能最終得到我們不喜歡的水果和蔬菜。

得到了購物清單、收據、水果和蔬菜,但這是一篇有關軟件工程的文章?

讓我們重新回到軟件角度:

  1. 購物清單代表您的 package.json 文件
  2. 每個水果和蔬菜代表一個package
  3. 水果或蔬菜的類型代表該package的確切版本或可接受版本的範圍
  4. 收據代表您的 package-lock.jsonyarn.lock 文件

當我們保存收據,也就是我們的 package lock(包鎖定) 文件時,我們能夠確保獲得相同package的版本,直到我們的購物清單,也就是我們的 package.json 文件發生了變化。

如果我們丟掉包鎖定文件,很可能最終得到的包不是我們期望的。


包鎖定文件使提交保持不變

如果在所選的版本控制工具中打開提交圖,則圖上的每個尖點都代表一個版本的代碼,如果該代碼的版本被檢索(pull)是不可變的,則無論誰以及何時檢索它都應該是相同的。

如果您的代碼庫包含具有依賴性的package.json文件,而不是package-lock.jsonyarn.lock文件(或其他軟件包管理器用來鎖定軟件包版本的另一個文件),則不是這種情況。如果在不同的時間訪問提交,我們可以得到不同版本的軟件包。

這是因為包的新版本一直都在發佈,而且我們已經允許在一些我們將接受的版本中存在差異。例如:

<code>{
"name": "my-angular-app",
"version": "1.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,

"dependencies": {
"@angular/animations": "^8.2.1",
"@angular/common": "^8.2.1",
"@angular/compiler": "^8.2.1",
"@angular/core": "^8.2.1",
"@angular/forms": "^8.2.1",
"@angular/http": "^8.0.0-beta.10",
"@angular/platform-browser": "^8.2.1",
"@angular/platform-browser-dynamic": "^8.2.1",
"@angular/router": "^8.2.1",
"core-js": "^2.5.4",
"csstype": "^2.5.8",
"ng2-file-upload": "^1.3.0",
"rxjs": "~6.5.3",
"zone.js": "~0.9.1",
"typescript": "~3.5.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.803.19",
"@angular/cli": "^8.3.19",
"@angular/compiler-cli": "^8.2.1",
"@angular/language-service": "^8.2.1",
"@nguniversal/express-engine": "^7.0.2",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0"
}
}/<code>

注意所有的 〜 和 ^ 嗎?如果在不同的時間安裝這些軟件包,則可能會導致下載這些軟件包的不同版本。

儘管package.json

文件中存在差異,但保留package-lock.jsonyarn.lock文件將鎖定這些版本。

我將讓一些數字來說話,yarn初始安裝後,node_modules文件夾中文件的大小和數量

以水果和蔬菜為例,理解package-lock.json是您最好的朋友

刪除node_modules

並重新安裝後的文件大小和數量,保持yarn.lock

以水果和蔬菜為例,理解package-lock.json是您最好的朋友

刪除node_modules並重新安裝,刪除yarn.lock之後的文件大小和數量

以水果和蔬菜為例,理解package-lock.json是您最好的朋友

上述明細表面,在刪除node_modules並重新安裝包之後,node_modules文件夾沒有發生任何變化。

但是,在刪除了node_modules文件夾和yarn.lock文件之後,又有了1507個文件,它們的大小總計超過7mb

這些多餘的文件到底是什麼,其中一些會進入我們應用程序的運行代碼中嗎?可怕的是我們可能永遠不會知道。

刪除或不提交您的package-lock.json 或 yarn.lock 就像說"提交我的代碼並隨機修改我們源代碼其餘部分的 X%"


刪除程序包鎖定是否安全?

您是否曾經在代碼庫上做過跨越大量不相關的功能的重大重構?也許你有意更新了主要庫,例如前端框架,你不確定什麼,如果有什麼可能會壞掉,所以你在你的應用程序上運行了一個完整的迴歸測試?

好吧,如果您要刪除軟件包鎖定文件,我可能會建議您執行相同的步驟。

如果更改代碼的一個大的橫截面會導致您運行一個完整的迴歸測試,那麼也應該更改您的第三方代碼的一個大的比例。

如果您確實想根據 package.json 文件獲取最新最好的軟件包(所有〜 和 ^ 都可以更新為最新的補丁程序和次要版本),則可以刪除軟件包鎖定文件。

刪除程序包鎖定文件可能是利用package.json文件的強大功能的一種好方法,但請準備運行完整的迴歸測試或解決任何意外行為


總結

除了在某些極端情況下,npm包不會被刪除,任何給定的版本也不會被修改,他們是不可變的。

對於任何給定的提交,您自己的代碼也應該是不可變的,如果對於 Yarn 用戶使用 npm 或 yarn.lock,則允許這樣做的機制稱為package-lock.json 文件。

此文件的存在可確保針對給定的提交安裝相同的軟件包版本,因此無論誰使用它,何時使用它,您自己的源代碼和第三方打包的代碼都是相同的。

刪除或不提交這些文件可能會導致應用程序發生不可預測的行為,因為對於同一次提交,軟件包的實際安裝版本可能會隨著時間而變化,如果發現錯誤是由錯誤的程序包引起的,則可能很難追蹤到它們。

因此,建議您提交不刪除這些文件,除非您打算根據 package.json 規範更新軟件包,並且準備進行徹底的測試或快速修復生產中發現的所有錯誤。

感謝您的閱讀,我希望這能解釋 package-lock.json 和 yarn-lock.json 文件。

相關鏈接:

  • package-lock:https://docs.npmjs.com/configuring-npm/package-lock-json.html
  • yarn-lock:https://classic.yarnpkg.com/en/docs/yarn-lock/

本頭條號聚焦大前端技術和程序員成長,如果對你有所啟發和幫助,可以點個關注、收藏。

作者簡介:同名微信公眾號作者,Web前端工程師,全棧開發工程師、持續學習者。

現在關注做同名微信公眾號,送精品視頻視頻教程大禮包!


分享到:


相關文章: