輸入npm install 之後都幹了啥

npm是Node的模塊管理工具
正因爲有了npm我們只要執行一行命令,就可以安裝別人寫好的模塊

npm install

1、 從npm install說起
Npm install 命令用來安裝模塊到node_module目錄中
在安裝之前,npm install會先檢查,node_module目錄之中是不是已經存在指定的模塊,如果存在,就不再進行安裝,即使遠程倉庫已經有了新版本,也是如此
如果你希望,一個模塊不管是否安裝過都重新新安裝一遍,可以用-f 或者—force參數

npm install <packageName> --force

2、 更新現有模塊
如果想更新已安裝的模塊,可以使用npm-update命令,會先遠程倉庫更新到最新版本,如果本地版本不存在,或者遠程倉庫已經有最新版本就會安裝。

npm update

3、模塊的安裝進程

  1. 發出npm install命令
  2. Npm 向registry查詢模塊壓縮包的網址
  3. 下載壓縮包,放在~/.npm目錄
  4. 解壓壓縮包到當前項目的node_modules目錄

注意,一個模塊安裝後,本地其實保存了兩份,一份是~/.npm下的壓縮包,另一份是node_modules目錄下解壓後的代碼。在npm install運行的時候,只會檢查node_modules中的模塊,而不會檢查/.npm.也就是說,如果在/.npm中有壓縮包但是node_modules中沒有模塊,npm install會從遠程倉庫再下載一次壓縮包。

執行npm install之後的細節

1、 執行工程自身的preinstall
當前鉤子如果定義了preinstall會被執行

2、 定義首層依賴模塊
首先需要做的就是工程中的首層依賴,也就是dependencies和devDependencies屬性中直接指定的模塊。
工程本身是整顆依賴樹的根節點,每個首層依賴模塊都是根節點下面的一顆子樹,npm會開啓多進程從每個首層依賴模塊開始逐步尋找更深層級的節點。
獲取模塊
獲取模塊是一個遞歸的過程,分爲以下幾步:

  • 獲取模塊信息。在下載一個模塊之前,首先要確定其版本,這是因爲 package.json 中往往是 semantic version(semver,語義化版本)。此時如果版本描述文件(npm-shrinkwrap.json 或
    package-lock.json)中有該模塊信息直接拿即可,如果沒有則從倉庫獲取。如 packaeg.json 中某個包的版本是 ^1.1.0,npm 就會去倉庫中獲取符合 1.x.x 形式的最新版本。

  • 獲取模塊實體。上一步會獲取到模塊的壓縮包地址(resolved字段),npm
    會用此地址檢查本地緩存,緩存中有就直接拿,如果沒有則從倉庫下載。

  • 查找該模塊依賴,如果有依賴則回到第1步,如果沒有則停止。

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

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

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

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

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

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

node_modules
– foo
---- lodash@version1

– bar
---- lodash@version2

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

node_modules
– foo

– bar

– lodash(保留的版本爲兼容版本)

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

node_modules
– foo
– lodash@version1

– bar
---- lodash@version2

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

6、執行工程自身生命週期
當前 npm 工程如果定義了鉤子此時會被執行(按照 install、postinstall、prepublish、prepare 的順序)。
7、更新版本
最後一步是生成或更新版本描述文件,npm install 過程完成。

參考文檔:
http://www.ruanyifeng.com/blog/2016/01/npm-install.html
https://www.zhihu.com/question/66629910

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章