// https://www.jianshu.com/p/818833b2dd5anode
npm的版本號管理
一個版本號分爲三個部分:
X,
Y,
Z.
X表示主版本號,
X爲主版本號,
Y爲次版本號,
Z爲更新補丁號,
若是作稍微改動、
修復功能,
沒有添加新功能,
更新Z,
若是添加新功能,
更新版本號Y,
若是有大的功能須要改動,
更新版本號X
~
會匹配最近的小版本依賴包,
好比~
1.2.3
會匹配全部1.2.
x版本,
可是不包括1.
3.0
^
會匹配最新的大版本依賴包,
好比 ^
1.2.3
會匹配全部1.
x.
x的包,
包括1.
3.0,
可是不包括2.
0.0
使用場景
運行同一個項目,
補丁的版本更新,
使用不一樣項目的人npminstall,
二個不一樣的版本運行的結果可能不同
這時候
package -
lock.
json
爲了解決這個問題,(
npm
版本在5以上),
內容處理和安裝依賴,
他代表了
版本號,
獲取地址和哈希值,
是的每次安裝都是相同的結果
//https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/22
// npm 模塊安裝機制:
發送npm
install的命令
查詢node_modules目錄是否有指定模塊,
若是存在,
不須要從新安裝
若是不存在
npm向registry查詢壓縮包的網址
下載壓縮包,
存放在根目錄下的.
npm的目錄裏
解壓壓縮包到當前項目node_modules目錄下
// npm 實現的原理
當輸入npm
install會經歷以下幾個階段
1,
執行工程自身preinstall
2,
肯定首層依賴模塊
首先須要作的是肯定工程中的首層依賴,
也就是
dependencies
和
devDependencies
屬性中直接指定的模塊(
假設此時沒有添加
npm
install
參數)。
工程自己是整棵依賴樹的根節點,
每一個首層依賴模塊都是根節點下面的一棵子樹,
npm
會開啓多進程從每一個首層依賴模塊開始逐步尋找更深層級的節點。
3,
獲取模塊
獲取模塊的信息
在下載一個模塊以前,
首先要肯定其版本,
這是由於
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
過程當中被去
5,
安裝模塊
這一步將會更新工程中的
node_modules,
並執行模塊中的生命週期函數(
按照
preinstall、
install、
postinstall
的順序)。
6,
執行工程中自身生命週期
當前
npm
工程若是定義了鉤子此時會被執行(
按照
install、
postinstall、
prepublish、
prepare
的順序)。
最後一步是生成或更新版本描述文件,
npm
install
過程完成。