鮮花總須要綠葉陪襯的,對比php, java, python的包依賴管理,頓時以爲nodejs包依賴機制真是漂亮。此文不吐槽python的包管理是如何難用和混亂,也不去抨擊php包管理的孱弱,僅僅討論如何優雅地使用npm進行包依賴管理。php
升級到3.x執行如下命令:java
npm install -g npm@3
先上圖node
圖中A和C都依賴了B,可是A依賴的是B v1.0,可是C依賴的是B v2.0,在npm2裏面直接就是把B的分別放在A的node_modules文件夾裏面,而npm3的處理方式是把B v1.0抽離出來做爲一個單獨的模塊,而C所依賴的B v2.0則單獨放到C中。
在實際項目中,npm2會產生了大量冗餘的引用,node_modules也會很大,npm3把結構扁平化了,實際上項目依賴的版本已經十分一致,像C單獨依賴Bv2.0這種狀況很少,因此npm3處理的node_modules體積小,效率更高。並且npm3.x是兼容npm2.x的,並沒有後顧之憂。python
深刻能夠閱讀文檔:http://www.alloyteam.com/2016...react
打開package.json這個文件,每每會看到dependencies中定義了一大堆的依賴,形式通常有如下幾種:npm
*: 任意版本
1.1.0: 指定版本
~1.1.0: >=1.1.0 && < 1.2.0
^1.1.0: >=1.1.0 && < 2.0.0json
上面的規則已經很清晰地表述了各類符號表明的意思。
那麼咱們回到使用場景中,何時咱們會鎖定版本,何時會用~,何時會用^?
個人理解以下:
(1)若是對依賴的包的穩定性要求極高,不但願有任何的更新,那麼就要鎖定版本。
1.1 項目中核心的包建議都鎖住某一穩定版本,例如react的項目中,react的版本就應該被鎖定。沒有通過完整的測試以前,不能隨意升級版本,即便是小版本升級也不容許。
1.2 若是明知道包的開發者不穩定,常常會更新一下不穩定的版本,那麼也須要鎖住版本,例如antd;
(2) 若是但願依賴包在小幅範圍內升級,而且確信不會影響穩定性,又能得益更新帶來的好處,那麼能夠用~符號
(3) 若是對包的穩定性要求不高,確信不是大版本更新都不會影響穩定性,那麼久能夠用^符號,不過要慎重;
開源項目通常都使用~或者^符號來管理版本antd
感興趣的同窗能夠閱讀如下文檔:
論版本號的正確打開方式:http://taobaofed.org/blog/201...測試
儘管npm3會兼容npm2,可是歷史遺留問題每每讓人防不勝防,最好的方式莫過於抹去舊的,放進新的。就譬如,昨天晚上留下了茶水,今天再把新泡的茶衝進去,味道也沒有新茶好,甚至會拉肚子。spa
上面的文字已經闡述了npm2和npm3的機制,看起來是沒有問題的,請注意C中引用Bv2,是把B v2放在C的node_modules文件夾中,新舊切換時就要考慮npm引用包的順序,若是一個包下面有node_modules文件夾,npm會優先查找node_modules裏面的包,而後再到外層,最後到全局。這是時候npm2的殘留是那麼頑固,由於它是把依賴放在本身node_modules文件夾下面的。對此,別無更好的辦法,除非刪掉,從新install。所以在發佈和構建是必定要注意npm的版本,要考慮2到3切換時可能帶來的風險。筆者已經吃過這方面的虧了。