有個npm包叫a,項目的dependencies有a和b兩個依賴,a的版本是version1。b中也依賴了a這個包,版本是version2。在項目打包的時候,會把a的這兩個版本都打進build文件中。本文主要分析對同一個包有多個版本依賴的狀況。node
在npm 3.0版本以前,node_modules裏面的依賴是一種樹形的嵌套結構,這樣會形成不少依賴重複安裝,而且node_modules的層級會很是深。npm
在npm 3.0的版本中,會先分析全部的依賴關係,儘量的把依賴層級拍平。若是一個包沒有被重複依賴,它會安裝在node_modules的第一層。當同一個包出現版本衝突時,會根據就近原則,把對應的依賴安裝在當前包的node_modules文件夾中。redux
SemVer的中文名稱是語義化版本控制規範。npm默認使用SemVer來進行模塊的版本控制。一個發佈到npm的包要嚴格遵照SemVer的版本規範,否則會發布失敗。bash
主版本號.次版本號.修訂號,能夠用x.y.z的寫法來簡單表示。ui
當要進行大版本迭代的時候,或者增長一些核心的功能,但又不能保證新版本百分之百正常,這個時候就能夠發佈先行版本。SemVer規範中使用alpha、beta和rc來修飾先行版本。spa
先行版本的版本號可使用:1.0.0-alpha、1.0.0-beta.一、1.0.0- rc.一、1.0.0-0.3.7等。版本控制
進行版本號比較時,x、y、z依次比較code
先行版本號的規則是rc > beta > alphaci
1.0.0 < 2.0.0 < 2.1.0 < 2.1.1
1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0- rc.1 < 1.0.0 複製代碼
^符是npm安裝依賴的默認方式。io
按照版本的語義,就是徹底信任包擁有者可以根據語義進行正確的包升級,不會引入具備破壞性的改變,而且作到對老版本的兼容。
^1.2.3 <=> >=1.2.3 <2.0.0
^0.2.3 <=> >=0.2.3 <0.3.0
^0.0.3 <=> >=0.0.3 <0.0.4
^1.2.x <=> >=1.2.0 <2.0.0
^0.0.x <=> >=0.0.0 <0.1.0
^0.0 <=> >=0.0.0 <0.1.0
^1.2.3-beta.2 <=> >=1.2.3-beta.2 <2.0.0
^0.0.3-beta <=> >=0.0.3-beta <0.0.
複製代碼
~符是老版本npm的默認方式,它只會安裝升級z位的版本,是一種很保守的依賴管理策略。
~1.2.3 <=> >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0
~1.2 <=> >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0 (Same as 1.2.x)
~1 <=> >=1.0.0 <(1+1).0.0 := >=1.0.0 <2.0.0 (Same as 1.x)
~0.2.3 <=> >=0.2.3 <0.(2+1).0 := >=0.2.3 <0.3.0
~0.2 <=> >=0.2.0 <0.(2+1).0 := >=0.2.0 <0.3.0 (Same as 0.2.x)
~0 <=> >=0.0.0 <(0+1).0.0 := >=0.0.0 <1.0.0 (Same as 0.x)
~1.2.3-beta.2 <=> >=1.2.3-beta.2 <1.3.0
複製代碼
固定版本的依賴是肯定的,除非手動升級,否則每次都安裝相同的版本。
當一個依賴包出現版本衝突時,會根據這個包不一樣的升級策略來肯定版本號。若是最後的版本號相同,只會在項目的node_modules裏面安裝這個版本的依賴;若是版本號不一樣,則兩個版本號的依賴都會安裝。
由於每一個npm包的版本更迭都不一樣,因此並無一個固定的規則去適用全部的狀況。當一個包被屢次依賴的時候,須要去npm的官網去查看這個包全部的版本,而後根據依賴的升級規則,去判斷這個包是否會版本衝突。
下面是當前時間,redux latest這個tag下面的版本號
4.0.1
4.0.0
3.7.2
3.7.1
3.7.0
3.6.0
3.5.2
3.5.1
3.5.0
3.4.0
3.3.1
3.3.0
3.2.0
...
複製代碼
~3.7.0 <=> ^3.6.0
3.7.2 <=> ^3.6.0
^3.3.0 <=> ^3.5.0
^3.6.0 <!=> ^4.0.0複製代碼