npm install的實現原理?

本人剛接觸node與npm不久,想知道為什麼我在cmd中輸入npm install敲下回車之後,就能幫我裝上對應的模塊包,這是怎麼實現的呢?


輸入 npm install 命令並敲下回車後,會經歷如下幾個階段(以 npm 5.5.1 為例):

執行工程自身 preinstall

當前 npm 工程如果定義了 preinstall 鉤子此時會被執行。

確定首層依賴模塊

首先需要做的是確定工程中的首層依賴,也就是 dependencies 和 devDependencies 屬性中直接指定的模塊(假設此時沒有添加 npm install 參數)。

工程本身是整棵依賴樹的根節點,每個首層依賴模塊都是根節點下面的一棵子樹,npm 會開啟多進程從每個首層依賴模塊開始逐步尋找更深層級的節點。

獲取模塊

獲取模塊是一個遞歸的過程,分為以下幾步:

  1. 獲取模塊信息。在下載一個模塊之前,首先要確定其版本,這是因為 package.json 中往往是 semantic version(semver,語義化版本)。此時如果版本描述文件(npm-shrinkwrap.json 或 package-lock.json)中有該模塊信息直接拿即可,如果沒有則從倉庫獲取。如 packaeg.json 中某個包的版本是 ^1.1.0,npm 就會去倉庫中獲取符合 1.x.x 形式的最新版本。
  2. 獲取模塊實體。上一步會獲取到模塊的壓縮包地址(resolved 欄位),npm 會用此地址檢查本地緩存,緩存中有就直接拿,如果沒有則從倉庫下載。
  3. 查找該模塊依賴,如果有依賴則回到第1步,如果沒有則停止。

模塊扁平化(dedupe)

上一步獲取到的是一棵完整的依賴樹,其中可能包含大量重複模塊。比如 A 模塊依賴於 loadsh,B 模塊同樣依賴於 lodash。在 npm3 以前會嚴格按照依賴樹的結構進行安裝,因此會造成模塊冗餘。

從 npm3 開始默認加入了一個 dedupe 的過程。它會遍歷所有節點,逐個將模塊放在根節點下面,也就是 node-modules 的第一層。當發現有重複模塊時,則將其丟棄。

這裡需要對重複模塊進行一個定義,它指的是模塊名相同semver 兼容。每個 semver 都對應一段版本允許範圍,如果兩個模塊的版本允許範圍存在交集,那麼就可以得到一個兼容版本,而不必版本號完全一致,這可以使更多冗餘模塊在 dedupe 過程中被去掉。

比如 node-modules 下 foo 模塊依賴 lodash@^1.0.0,bar 模塊依賴 loader@^1.1.0,則 ^1.1.0 為兼容版本。

而當 foo 依賴 lodash@^2.0.0,bar 依賴 lodash@^1.1.0,則依據 semver 的規則,二者不存在兼容版本。會將一個版本放在 node_modules 中,另一個仍保留在依賴樹里。

舉個例子,假設一個依賴樹原本是這樣:

node_modules

-- foo

---- loadsh@version1

-- bar

---- loadsh@version2

假設 version1 和 version2 是兼容版本,則經過 dedupe 會成為下面的形式:

node_modules

-- foo

-- bar

-- lodash(保留的版本為兼容版本)

假設 version1 和 version2 為非兼容版本,則後面的版本保留在依賴樹中:

node_modules

-- foo

-- loadsh@version1

-- bar

---- loadsh@version2

安裝模塊

這一步將會更新工程中的 node_modules,並執行模塊中的生命周期函數(按照 preinstall、install、postinstall 的順序)。

執行工程自身生命周期

當前 npm 工程如果定義了鉤子此時會被執行(按照 install、postinstall、prepublish、prepare 的順序)。

最後一步是生成或更新版本描述文件,npm install 過程完成。

以上如有遺漏錯誤歡迎指正。


npm install 命令。默認會找到當前路徑下的package.json。然後安裝其中的依賴

By default, npm install will install all modules listed as dependencies in package.json.

可以看看這個 install | npm Documentation


npm install 根據 package.json 讀取依賴的信息並安裝,具體演算法參考:https://docs.npmjs.com/cli/install#algorithm

貼下主要步驟

1. load the existing node_modules tree from disk

2. clone the tree

3. fetch the package.json and assorted metadata and add it to the clone

4. walk the clone and add any missing dependencies

dependencies will be added as close to the top as is possible

without breaking any other modules

5. compare the original tree with the cloned tree and make a list of

6. actions to take to convert one to the other

7. execute all of the actions, deepest first

kinds of actions are install, update, remove and move


請問這個問題你搞明白了嗎,弄懂的話能不能分享下,我也迫切想知道


根據package.list 獲取需要安裝的包. 然後每一個npm源都會實現一個通過包名跟版本號獲取包的下載地址遠程下載並且獲取這個包的package.json判斷這個包的依賴並且判斷依賴是否有安裝如果沒安裝則先安裝如果安裝了就跳過然後下載安裝 這是一個遞歸的過程 類似爬蟲 直到一個數組裡面的包 全部安裝完之後 就完成 了


就和百度全家桶一樣,幫你下安裝包,幫你點安裝,幫你下一步。

看會小片片altab回來。

安裝完成!


推薦閱讀:

移動端前端開發與PC端比有哪些不同?
jQuery真的過時了嗎?
amaze ui和bootstrap有哪些差別?
有沒有適合HTML&CSS初學者模仿的靜態網頁?
使用哪一個電腦?

TAG:前端開發 | Nodejs | 命令提示符cmd | npm |