詳解package-lock.json
我們都知道package.json除了配置快捷的node script腳本
, 最主要的作用還是: 用於記錄下當前項目所應用到的依賴包, 但是既然都已經有了package.json文件了, 那么為什么項目中還需要一個package-lock.json呢? 本文就來為您詳細分析!
package-lock.json的作用
作用: 鎖定安裝時的包的版本號及包的依賴的版本號, 以保證其他所有人人在使用 npm install
時下載的依賴包都是一致的
比如說:
我下載了A依賴
的v1.0.0版本
, 同時A依賴
又是依賴與B依賴
的v1.3.2版本
和C依賴
的v2.0.3版本
開發的
那么對於package.json的話只會在dependencies
或者 devDependencies
中記錄類似下的內容:
{
"dependencies": {
"依賴A": "^1.0.0"
}
}
那么下次安裝依賴A或許會出現以下情況:
依賴A
的下載的版本為: 1.最新版.最新版, 導致項目出現bug依賴A
所依賴的B依賴
和C依賴
下載了別的版本, 導致依賴A出現bug
, 進而導致項目出現bug
packag.json只單純記錄本項目的依賴, 而沒有記錄下依賴的依賴, 並且依賴之間的版本號又沒有明確固定, 導致無法保證依賴環境一致
而package-lock.json的出現就是解決上述問題, 它會詳細的記錄項目依賴的版本號及依賴的依賴的版本號, 如以下所示:
{
"name": "test",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "test",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"依賴A": "^1.0.0"
}
},
"node_modules/依賴A": {
"dependencies": {
"B依賴": "^1.3.2",
"C依賴": "^2.0.3"
}
}
}
}
版本號的定義規則與前綴對安裝的影響
根據GNU中對版本號的定義規則:
中文版:
主版本號 . 子版本號 [ .修正版本號 [ .編譯版本號 ] ]
英文版:
Major_Version_Number . Minor_Version_Number [ .Revision_Number [ .Build_Number ] ]
英文簡化版:
Major . Minor . [ .Revision [.Build] ]
package.json中的前綴^符號
~符號
*符號
代表了對包安裝版本的不同策略, 下面的示例都通過下載vue2進行演示
-
^符號
的意思: 版本號中最左邊的非0數字的右側都用最新的版本數- 例如: package.json中包版本為
^2.1.0
, 則下次會下載的版本為2.6.14 (2.最新.最新) - 例如: package.json中包版本為
^0.7.1
, 則下次會下載的版本為0.7.6 (0.7.最新) - 例如: package.json中包版本為
^0.6.0
, 則下次會下載的版本為0.6.0 (0.6.最新)
- 例如: package.json中包版本為
-
~符號
的意思:Major
永遠准確安裝,Minor
給出的則准確安裝否則裝最新,Revision
永遠裝最新- 例如: package.json中包版本為
~2.0.3
, 則下次會下載的版本為2.0.8 (2.0.最新) - 例如: package.json中包版本為
~0
, 則下次會下載的版本為0.12.16 (0.最新.最新) - 例如: package.json中包版本為
~3.1
, 則下次會下載的版本為3.1.5 (3.1.最新)
- 例如: package.json中包版本為
-
*符號
的意思: 直接下載這個包的最新版本- 例如: package.json中包版本為
*
, 則下次會下載的版本為2.6.14 (vue2的最新版)
- 例如: package.json中包版本為
-
x符號
的意思: x占位開始, 全部使用最新- 例如: package.json中包版本為
"2.3.x"
, 則下次會下載的版本為2.3.4 (2.3.最新) - 例如: package.json中包版本為
"2.x.x"
, 則下次會下載的版本為2.6.14 (2.最新.最新) - 例如: package.json中包版本為
"x.x.x"
, 則下次會下載的版本為2.6.14 (最新.最新.最新) - 例如: package.json中包版本為
"x"
, 則下次會下載的版本為2.6.14 (最新.最新.最新)
- 例如: package.json中包版本為
-
精准版本號安裝
npm i vue@2.6.14 # 下載Vue的2.6.14版本
改動package.json后依舊能改變項目依賴的版本
網上有很多博文說在npm版本5之后, 不能直接修改package.json中依賴包的版本來改變項目的安裝, 因為項目版本已經被鎖定在package-lock.json, 因此只能通過npm i 依賴@版本號
的方法來改變版本
但是據我實際操作, 在npm版本為(v7.24.0), 直接修改package.json中依賴包的版本可以改變項目的安裝, 並且會更新到package-lock.json中
當前項目的真實版本號應該以package-lock.json為標准
示例:
我本地的項目1的package.json
{
"name": "project1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"less": "^3.8.0"
}
}
張三想在他那運行我的項目, 為此他只將package.json復制到他的機器上然后運行npm i
命令安裝項目運行所需的環境依賴
會出現以下情況: package.json中less編譯器的版本並沒變(還是 ^3.8.0), 但是less編譯器的實際版本卻是3.13.1
, 即3大版本中的最新版, 再看自動生成的package.lock.json就會發現版本為3.13.1, 與實際版本相同, 所以package-lock.json中的依賴版本才是最為真實的, 不能盲目相信package.json
張三 npm i
后項目1的package.json
{
"name": "project1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"less": "^3.8.0"
}
}
張三npm i后項目1的package.lock.json
{
"less": {
"version": "3.13.1" // 這才是真實版本號
}
}
package.lock.json的生成、更新、使用時機
- 生成時機:
- 當項目有package.json文件並首次執行
npm install
安裝后, 會自動生成一個package-lock.json文件, 該文件里面記錄了package.json依賴的模塊,以及依賴的依賴。並且給每個依賴標明了版本, 獲取地址和哈希值, 使得每次安裝都會出現相同的結果, 不管你在什么機器上面或什么時候安裝
- 當項目有package.json文件並首次執行
- 更新時機
- 使用命令重新安裝特定版本的包
npm i less@3.12.0
- 在package.json中修改依賴版本后, 執行
npm install
- 使用命令重新安裝特定版本的包
- 使用時機
- 執行
npm install
時, 與package.json共同確定依賴包及依賴包的依賴的精確的版本號
- 執行
總結
- package.json用於告訴npm項目運行需要哪些包, 但包的最終安裝的版本不能夠只依靠這個文件進行識別, 還需以package-lock.json為准
- package.json中修改版本號會影響package-lock.json, 並且package.json比package.lock.json的優先級高, 如果package.json中less版本為
^1.0.0
, package-lock.json中less版本為2.1.2
, 則最終安裝的less版本為1.7.5, package-lock.json中less即其依賴的包將被從
2.1.2退回到
1.7.5`的狀態 - 為了保證該項目的環境依賴一致, 在項目移動時需要同時復制 package.json 和 package.lock.json 兩個文件
- 不要輕易動package.json與package-lock.json
也許您最終還有疑問: 既然package.json會影響package-lock.json, 那后者lock的意義在哪?
我是這樣理解的:
- package.json確定了項目依賴的版本, 但是沒有lock住依賴的依賴的版本
- 而package-lock.json就是用來lock住項目依賴的依賴
全文到此結束, 希望對您有幫助~~~