標籤:

npm install 生成的package-lock.json是什麼文件?有什麼用?

前段時間升級了Node.js,現在執行`npm install`的時候,就會在當前目錄生成一個`package-lock.json`的文件。

但不知道這個文件是幹啥用的呢?


上面的答案把 package-lock.json 的作用寫的很明確了,我來說說不一樣的點。

npm 5.x 發布以來到現在的5.6.0 lock的作用變更過好多次,現在網上很多小白文都是停留在以前的文檔翻譯。

從npm3.x更新到了npm5,但是發現執行 `npm i ` 時的現象跟網路上的科普文不太一致。

有提到不管怎麼修改package.json文件,重複執行npm i,npm都會根據lock文件描述的版本信息進行下載。

也有提到重複npm i時,npm會不顧lock的信息,根據package.json中的包Semantic versioning 版本信息下載更新模塊(lock貌似沒啥用了)。

**查閱資料得知,自npm 5.0版本發布以來,npm i的規則發生了三次變化。**

1、npm 5.0.x 版本,不管package.json怎麼變,npm i 時都會根據lock文件下載

package-lock.json file not updated after package.json file is changed · Issue #16866 · npm/npm

這個 issue 控訴了這個問題,明明手動改了package.json,為啥不給我升級包!然後就導致了5.1.0的問題...

2、5.1.0版本後 npm install 會無視lock文件 去下載最新的npm

然後有人提了這個issue why is package-lock being ignored? · Issue #17979 · npm/npm

控訴這個問題,最後演變成5.4.2版本後的規則。

3、5.4.2版本後 why is package-lock being ignored? · Issue #17979 · npm/npm

大致意思是,如果改了package.json,且package.json和lock文件不同,那麼執行`npm i`時npm會根據package中的版本號以及語義含義去下載最新的包,並更新至lock。

如果兩者是同一狀態,那麼執行`npm i `都會根據lock下載,不會理會package實際包的版本是否有新。


package.json裡面定義的是版本範圍(比如^1.0.0),具體跑npm install的時候安的什麼版本,要解析後才能決定,這裡面定義的依賴關係樹,可以稱之為邏輯樹(logical tree)。

node_modules文件夾下才是npm實際安裝的確定版本的東西,這裡面的文件夾結構我們可以稱之為物理樹(physical tree)。

安裝過程中有一些去重演算法,所以你會發現邏輯樹結構和物理樹結構不完全一樣。

package-lock.json可以理解成對結合了邏輯樹和物理樹的一個快照(snapshot),裡面有明確的各依賴版本號,實際安裝的結構,也有邏輯樹的結構。

其最大的好處就是能獲得可重複的構建(repeatable build),當你在CI(持續集成)上重複build的時候,得到的artifact是一樣的,因為依賴的版本都被鎖住了。在npm5以後,其內容和npm-shrinkwrap.json一模一樣。

這些在npm官網文檔都有詳細解釋。


根據官方文檔,這個package-lock.json 是在 `npm install`時候生成一份文件,用以記錄當前狀態下實際安裝的各個npm package的具體來源和版本號。

它有什麼用呢?因為npm是一個用於管理package之間依賴關係的管理器,它允許開發者在pacakge.json中間標出自己項目對npm各庫包的依賴。你可以選擇以如下方式來標明自己所需要庫包的版本

這裡舉個例子:

"dependencies": {

"@types/node": "^8.0.33",

},

這裡面的 向上標號^是定義了向後(新)兼容依賴,指如果 types/node的版本是超過8.0.33,並在大版本號(8)上相同,就允許下載最新版本的 types/node庫包,例如實際上可能運行npm install時候下載的具體版本是8.0.35。波浪號

大多數情況這種向新兼容依賴下載最新庫包的時候都沒有問題,可是因為npm是開源世界,各庫包的版本語義可能並不相同,有的庫包開發者並不遵守嚴格這一原則:相同大版本號的同一個庫包,其介面符合兼容要求。這時候用戶就很頭疼了:在完全相同的一個nodejs的代碼庫,在不同時間或者不同npm下載源之下,下到的各依賴庫包版本可能有所不同,因此其依賴庫包行為特徵也不同有時候甚至完全不兼容。

因此npm最新的版本就開始提供自動生成package-lock.json功能,為的是讓開發者知道只要你保存了源文件,到一個新的機器上、或者新的下載源,只要按照這個package-lock.json所標示的具體版本下載依賴庫包,就能確保所有庫包與你上次安裝的完全一樣。


自問自答:

package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.

大概意思好像是:

package-lock.json是當 node_modules 或 package.json 發生變化時自動生成的文件。這個文件主要功能是確定當前安裝的包的依賴,以便後續重新安裝的時候生成相同的依賴,而忽略項目開發過程中有些依賴已經發生的更新。

對比之下,大概是想做類似 Yarn 的功能。

詳細內容,請自行查閱官方文檔:https://docs.npmjs.com/files/package-lock.json


推薦閱讀:

為什麼 npm 要為每個項目單獨安裝一遍 node_modules?

TAG:Nodejs | npm |