package-lock.json解決依賴的版本管理使用詳解
前言
上篇文章我們了解了package.json ,一般與它同時(shí)出現(xiàn)的還有一個(gè)package-lock.json
,這兩者又有什么關(guān)系呢?下面一起來(lái)了解吧。
介紹
package-lock.json
它會(huì)在 npm 更改 node_modules 目錄樹(shù) 或者 package.json 時(shí)自動(dòng)生成的 ,它準(zhǔn)確的描述了當(dāng)前項(xiàng)目npm包的依賴樹(shù),并且在隨后的安裝中會(huì)根據(jù) package-lock.json 來(lái)安裝,保證是相同的一個(gè)依賴樹(shù),不考慮這個(gè)過(guò)程中是否有某個(gè)依賴有小版本的更新。
為什么需要package-lock.json
相信跟多人跟我一樣會(huì)有一個(gè)疑問(wèn):為什么有了package.json
還需要package-lock.json
?實(shí)際上兩者并不是同一時(shí)期提出來(lái)的,package-lock.json
是在npm5
之后才提出來(lái)的,從上面MDN的介紹來(lái)看,它的出現(xiàn)主要是為了解決依賴的版本管理問(wèn)題。
npm install
執(zhí)行后,會(huì)生成一個(gè)node_modules
樹(shù),在理想情況下, 希望對(duì)于同一個(gè) package.json
總是生成完全相同 node_modules
樹(shù)。在某些情況下,確實(shí)如此。但在多數(shù)情況下,npm
無(wú)法做到這一點(diǎn)。有以下兩個(gè)原因:
- 某些依賴項(xiàng)自上次安裝以來(lái),可能已發(fā)布了新版本 。比如:A 包在團(tuán)隊(duì)中第一個(gè)人安裝的時(shí)候是
1.0.5
版本,package.json
中的配置項(xiàng)為A: '^1.0.5'
,團(tuán)隊(duì)中第二個(gè)人把代碼拉下來(lái)的時(shí)候,A 包的版本已經(jīng)升級(jí)成了1.0.8
,根據(jù)package.json
中的semver-range version
規(guī)范,此時(shí)第二個(gè)人npm install
后 A 的版本為1.0.8
,可能會(huì)造成因?yàn)橐蕾嚢姹静煌鴮?dǎo)致的 bug - 針對(duì)上面的問(wèn)題,可能有的小伙伴會(huì)覺(jué)得把 A 的版本號(hào)固定為
A: '1.0.5'
不就可以了嗎?但是這樣的做法其實(shí)并沒(méi)有解決問(wèn)題, 比如 A 的某個(gè)依賴在第一個(gè)人下載的時(shí)候是2.1.3
版本,但是第二個(gè)人下載的時(shí)候已經(jīng)升級(jí)到了2.2.5
版本,此時(shí)生成的node_modules
樹(shù)依舊不完全相同 ,固定版本只是固定來(lái)自身的版本,依賴的版本無(wú)法固定
關(guān)于依賴的版本
我們可以先來(lái)了解依賴的版本
{ ? "dependencies": { ? ?"@nestjs/common": "^10.0.0", ? ?"@nestjs/core": "^10.0.0", ? } }
比如我們常見(jiàn)的依賴版本一般長(zhǎng)這樣,它一般由三部分組成:major.minor.patch
,依次為主版本號(hào)、次版本號(hào)、修補(bǔ)版本號(hào)。
主要版本
的更改代表了一個(gè)破壞兼容性的大變化。 如果用戶不適應(yīng)主要版本更改,則內(nèi)容將無(wú)法正常工作。次要版本
的更改表示不會(huì)破壞任何內(nèi)容的新功能。修補(bǔ)版本
的更改表示不會(huì)破壞任何內(nèi)容的錯(cuò)誤修復(fù)。
比如上面我們看到的^10.0.0
,主版本號(hào)為10、次版本號(hào)為0、修補(bǔ)版本號(hào)為0,那^
表示什么呢?
版本號(hào)指定標(biāo)識(shí)符
這個(gè)符號(hào)其實(shí)是用來(lái)指定版本范圍的,與之對(duì)應(yīng)的有以下符號(hào):
^
會(huì)匹配最新的大版本依賴包,比如^1.2.3
會(huì)匹配所有>=1.1.2 <2.0.0
的版本,包括1.3.0
,但是不包括2.0.0
~
會(huì)匹配最近的小版本依賴包,比如~1.2.3
會(huì)匹配所有>=1.1.2 <1.2.0
的版本,但是不包括1.3.0
*
安裝最新版本的依賴包,比如*1.2.3
會(huì)匹配x.x.x
- 無(wú)符號(hào)時(shí),比如
1.2.3
,那就是將要使用的確切版本,總是會(huì)下載這個(gè)版本的依賴包
認(rèn)識(shí)package-lock.json
這個(gè)文件看起來(lái)比package.json
又大有復(fù)雜,動(dòng)不動(dòng)就是上萬(wàn)行代碼。
我們可以只安裝某一個(gè)依賴看看它內(nèi)部長(zhǎng)啥樣,比如axios
:
{ ?"name": "demo", ?"version": "1.0.0", ?"lockfileVersion": 1, ?"requires": true, ?"dependencies": { ? ?"asynckit": { ? ? ?"version": "0.4.0", ? ? ?"resolved": "https://mirrors.tencent.com/npm/asynckit/-/asynckit-0.4.0.tgz", ? ? ?"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" ? }, ? ?"axios": { ? ? ?"version": "1.4.0", ? ? ?"resolved": "https://mirrors.tencent.com/npm/axios/-/axios-1.4.0.tgz", ? ? ?"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", ? ? ?"requires": { ? ? ? ?"follow-redirects": "^1.15.0", ? ? ? ?"form-data": "^4.0.0", ? ? ? ?"proxy-from-env": "^1.1.0" ? ? } ? }, ? ?"combined-stream": { ? ? ?"version": "1.0.8", ? ? ?"resolved": "https://mirrors.tencent.com/npm/combined-stream/-/combined-stream-1.0.8.tgz", ? ? ?"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", ? ? ?"requires": { ? ? ? ?"delayed-stream": "~1.0.0" ? ? } ? }, ? ?"delayed-stream": { ? ? ?"version": "1.0.0", ? ? ?"resolved": "https://mirrors.tencent.com/npm/delayed-stream/-/delayed-stream-1.0.0.tgz", ? ? ?"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" ? }, ? ?"follow-redirects": { ? ? ?"version": "1.15.2", ? ? ?"resolved": "https://mirrors.tencent.com/npm/follow-redirects/-/follow-redirects-1.15.2.tgz", ? ? ?"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" ? }, ? ?"form-data": { ? ? ?"version": "4.0.0", ? ? ?"resolved": "https://mirrors.tencent.com/npm/form-data/-/form-data-4.0.0.tgz", ? ? ?"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", ? ? ?"requires": { ? ? ? ?"asynckit": "^0.4.0", ? ? ? ?"combined-stream": "^1.0.8", ? ? ? ?"mime-types": "^2.1.12" ? ? } ? }, ? ?"mime-db": { ? ? ?"version": "1.52.0", ? ? ?"resolved": "https://mirrors.tencent.com/npm/mime-db/-/mime-db-1.52.0.tgz", ? ? ?"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" ? }, ? ?"mime-types": { ? ? ?"version": "2.1.35", ? ? ?"resolved": "https://mirrors.tencent.com/npm/mime-types/-/mime-types-2.1.35.tgz", ? ? ?"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", ? ? ?"requires": { ? ? ? ?"mime-db": "1.52.0" ? ? } ? }, ? ?"proxy-from-env": { ? ? ?"version": "1.1.0", ? ? ?"resolved": "https://mirrors.tencent.com/npm/proxy-from-env/-/proxy-from-env-1.1.0.tgz", ? ? ?"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" ? } } }
從這里我們可以發(fā)現(xiàn),它的dependencies
與package.json
不一樣,它除了axios
之外還包含了一些其它的依賴,實(shí)際上這些其它的依賴都是axios
的依賴或者是它依賴的依賴...
從上面的介紹中我們也能知道,它實(shí)際上描述的是當(dāng)前項(xiàng)目的依賴樹(shù)
它有一些與package.json
文件中不同的屬性,比如:
lockfileVersion
一個(gè)整數(shù)版本,從1開(kāi)始,該文檔的版本號(hào)
resolved
依賴的安裝地址,其實(shí)就是一個(gè)包下載地址
intergrity
表示解壓的完整性 Hash 值
dev
表示該模塊是否為頂級(jí)模塊的開(kāi)發(fā)依賴或者是一個(gè)的傳遞依賴關(guān)系
requires
依賴包所需要的所有依賴項(xiàng),對(duì)應(yīng)依賴包 package.json 里 dependencices
中的依賴項(xiàng)
npm install策略
當(dāng)我們每次使用npm install
進(jìn)行依賴安裝的時(shí)候,它到底是按照什么規(guī)則去幫我們下載依賴的呢?
這里其實(shí)有好幾個(gè)版本,但我們只需要了解最新版本就行了。
先看有無(wú)lock
文件:
如果有,則對(duì)比package.json和package-lock.json
- 如果
package-lock.json
里包版本號(hào)符合package.json
要求,則直接獲取包信息(如果是從遠(yuǎn)程拉取,則按照package-lock.json
,否則以實(shí)際緩存的為準(zhǔn)),構(gòu)建依賴樹(shù),(注意這一步只是確定邏輯上的依賴樹(shù),并非真正的安裝,后面會(huì)根據(jù)這個(gè)依賴結(jié)構(gòu)去下載或拿到緩存中的依賴包);那么接下來(lái)就看.npmrc
里有沒(méi)有緩存,如果有緩存文件,則從緩存文件中拉取內(nèi)容,否則從遠(yuǎn)程拉??;并更改package-lock。json
版本號(hào) - 如果版本號(hào)不符合要求,則直接從遠(yuǎn)程拉取,并更新
package-lock.json
中的版本號(hào)
如果沒(méi)有,則:
- 根據(jù)
package.json
構(gòu)建依賴樹(shù)(注意這一步只是確定邏輯上的依賴樹(shù),并非真正的安裝,后面會(huì)根據(jù)這個(gè)依賴結(jié)構(gòu)去下載或拿到緩存中的依賴包) - 如果緩存中
(.npmrc)
有,則優(yōu)先從緩存中讀取,否則從遠(yuǎn)程讀??;注意:(如果是從遠(yuǎn)程拉取,則按照package.json
,否則以實(shí)際緩存的為準(zhǔn))
需要注意的是,在使用cnpm install
時(shí)候,并不會(huì)生成 package-lock.json
文件,也不會(huì)根據(jù) package-lock.json
來(lái)安裝依賴,它只會(huì)根據(jù) package.json
來(lái)安裝依賴
場(chǎng)景一
// package.json "dependencies": { "vue": "^2.0.0" } ? // package-lock.json "dependencies": { "vue": { ? ? ?"version": "2.7.14", ? ? ?"resolved": "https://mirrors.tencent.com/npm/vue/-/vue-2.7.14.tgz", ? ? ?"integrity": "sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==", ? ? ?"requires": { ? ? ? ?"@vue/compiler-sfc": "2.7.14", ? ? ? ?"csstype": "^3.1.0" ? ? } ? } } ?
這種情況下package-lock.json
指定的2.7.14
在^2.0.0
指定的范圍內(nèi),npm install
會(huì)安裝vue2.7.14
版本。
場(chǎng)景二
// package.json "dependencies": { "vue": "^2.2.0" } ? // package-lock.json "dependencies": { "vue": { "version": "2.1.0", "resolved": "https://mirrors.tencent.com/npm/vue/-/vue-2.1.0.tgz", "integrity": "sha1-KTuj76rKhGqmvL+sRc+FJMxZfj0=" } } ?
這種情況下package-lock.json
指定的2.1.0
不在^2.2.0
指定的范圍內(nèi),npm install
會(huì)按照^2.2.0
的規(guī)則去安裝最新的2.7.14
版本,并且將package-lock.json
的版本更新為2.7.14
。
現(xiàn)在應(yīng)該能夠理解package.json
文件是如何做到對(duì)依賴進(jìn)行版本鎖定的吧,我們一般在安裝依賴時(shí)如果不指定版本,那么安裝的版本號(hào)并不是固定的而是一個(gè)最優(yōu)版本,最優(yōu)版本會(huì)在版本前多了一個(gè)^
或者~
符號(hào)
"dependencies": { ? ?"vue": "^2.0.0" }
但我們的lock
文件中肯定是會(huì)指定一個(gè)固定版本進(jìn)行安裝的,一般是改依賴的符合版本范圍的最新版本
"dependencies": { "vue": { "version": "2.1.0", "resolved": "https://mirrors.tencent.com/npm/vue/-/vue-2.1.0.tgz", "integrity": "sha1-KTuj76rKhGqmvL+sRc+FJMxZfj0=" } }
至于為什么不直接在package.json
中將版本鎖定,那是因?yàn)槟阒荒苤付惆惭b的依賴的版本,但不能指定你依賴的依賴的版本
package-lock.json什么時(shí)候會(huì)變?
開(kāi)發(fā)過(guò)程中是不是經(jīng)常遇到這個(gè)文件沖突的,自己明明沒(méi)改這個(gè)文件為啥會(huì)沖突?那是因?yàn)槲覀兊囊恍┎僮鲿?huì)影響到該文件的內(nèi)容,比如:
package-lock.json
在npm install
的時(shí)候會(huì)自動(dòng)生成- 當(dāng)我們修改依賴位置,比如將部分依賴從
開(kāi)發(fā)依賴改
成生產(chǎn)依賴
,雖然整體上的依賴并未改變,但是也會(huì)影響package-lock.json
中依賴的dev
字段 - 如果我們切換
npm鏡像
時(shí),執(zhí)行npm install
時(shí)也會(huì)修改package-lock.json
,因?yàn)樗菚?huì)記錄我們的依賴包地址的(resolved) - 當(dāng)我們使用
npm install
添加或npm uninstall
移除包的時(shí)候,也會(huì)修改package-lock.json
- 當(dāng)我們更新某個(gè)包的版本的時(shí)候,也會(huì)修改
package-lock.json
package-lock.json需要提交到倉(cāng)庫(kù)嗎?
npm 官網(wǎng)建議:把 package-lock.json
一起提交到代碼庫(kù)中,不要 ignore。但是在執(zhí)行 npm publish 的時(shí)候,它會(huì)被忽略而不會(huì)發(fā)布出去。
如何查看依賴安裝的版本?
上面我們已經(jīng)了解到,package.json
中保存的依賴版本一般不是一個(gè)具體版本,而是一個(gè)帶有^
或~
的最優(yōu)版本,那我們?cè)趺床拍苤喇?dāng)前項(xiàng)目依賴安裝的具體版本呢?
- 查看
package-lock.json
文件,這里保存的是依賴的具體版本 - 從
node_modules
文件夾中找到對(duì)應(yīng)依賴的package.json
文件,里面的version
字段就是該依賴的版本 - 使用
npm list --depth 0
查看項(xiàng)目所有的依賴版本
以上就是package-lock.json解決依賴的版本管理使用詳解的詳細(xì)內(nèi)容,更多關(guān)于package-lock.json版本依賴的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- package.json與package-lock.json創(chuàng)建及使用詳解
- npm script和package-lock.json使用示例詳解
- package.json與package-lock.json的區(qū)別及詳細(xì)解釋
- 前端必會(huì)的package.json創(chuàng)建及常見(jiàn)屬性用法示例詳解
- package.json中browser?module?main字段優(yōu)先級(jí)對(duì)比
- 詳解npm與package.json之間的聯(lián)系
- package.json的版本號(hào)更新優(yōu)化方法
- npm?start運(yùn)行項(xiàng)目過(guò)程package.json字段詳解
相關(guān)文章
Nodejs爬蟲(chóng)進(jìn)階教程之異步并發(fā)控制
這篇文章主要介紹了Nodejs爬蟲(chóng)進(jìn)階教程之異步并發(fā)控制的相關(guān)資料,需要的朋友可以參考下2016-02-02Node.js學(xué)習(xí)之內(nèi)置模塊fs用法示例
這篇文章主要介紹了Node.js學(xué)習(xí)之內(nèi)置模塊fs用法,結(jié)合實(shí)例形式詳細(xì)分析了node.js內(nèi)置模塊fs的基本功能、用法與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-01-01基于websocket實(shí)現(xiàn)簡(jiǎn)單聊天室對(duì)話
這篇文章主要為大家詳細(xì)介紹了基于websocket實(shí)現(xiàn)簡(jiǎn)單聊天室對(duì)話,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07Node.js中文件操作模塊File System的詳細(xì)介紹
FileSystem模塊是類似UNIX(POSIX)標(biāo)準(zhǔn)的文件操作API,用于操作文件系統(tǒng)——讀寫(xiě)目錄、讀寫(xiě)文件——Node.js底層使用C程序來(lái)實(shí)現(xiàn),這些功能是客戶端JS所不具備的。下面這篇文章就給大家詳細(xì)介紹了Node.js中的文件操作模塊File System,有需要的朋友們可以參考借鑒。2017-01-01NodeJS之優(yōu)缺點(diǎn)及適用場(chǎng)景討論
這篇文章主要介紹了NodeJS之優(yōu)缺點(diǎn)及適用場(chǎng)景討論,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10