首頁 > web前端 > js教程 > npm的模組安裝機制詳細介紹

npm的模組安裝機制詳細介紹

零下一度
發布: 2017-06-26 10:54:07
原創
1216 人瀏覽過
 
依賴樹表面的邏輯結構與依賴樹真實的物理結構
依賴樹表面的邏輯結構與依賴樹真實的物理結構不一定相同!
這裡要先提到兩個指令:tree -d(linux)和npm ls(npm)
在一個npm專案下:
tree -d指令以樹狀圖的方式列出一個項目下所有依賴的物理結構
#npm ls指令以樹狀圖的方式列出一個項目下所有依賴的邏輯結構
 
以官方文件為範例:
專案example1有兩個依賴模組:mod-a模組和mod-c模組;
mod-a模組有一個依賴模組mod-b@1.0.0模組
#mod-c模組有一個依賴模組mod-b@2.0.0模組
tree -d 和npm ls運行結果如下:(注意npm版本為npm3而非npm2)
 
 
#先看看下面那個紅框的結果,這應該是「最符合我們理解」的依賴樹,首先項目下形成了一級依賴-mod-a模組和mod-b模組,然後以這兩個模組為父模組再追加二級依賴模組mod-b@1.0 .0和mod-b@2.0.0
 
但是! 這並不是物理上真實形成的依賴樹的模樣,物理上真實形成的依賴樹是上面的那個紅色框。 mod-a,mod-c和mod-b竟然同為同一級的依賴。
 
你可能會問,為什麼會形成這樣的依賴樹呢? 下面我就來解釋一番
 
#【注意】:下面的圖示全部為依賴樹的物理結構,而不是邏輯結構
 
#關於npm模組安裝機制的一點猜想
安裝模組時,可能的方式有兩種:平級式的安裝或嵌套式的安裝(這裡只是猜想和假設)

 

#能不能完全採取平階的安裝方式呢? ——不能
 
我們取和上面相似的一個例子:專案APP下有兩個依賴模組A和B;A又有一個依賴模組Cv1.0;而B也有一個依賴模組Cv2.0。顯然,它們並不能同時存在於同一個node_modules下,當安裝的時候,由於npm的作用機制,只能有一個版本的依賴模組被安裝,其中一個將覆蓋另外一個。

 

但如果我們只安裝一個版本的C依賴模組,將可能會導致A模組和B模組不相容
 
基於上述原因,npm2選擇了嵌套的安裝方式-
 
#npm2下的模組安裝機制
npm2安裝多層次的依賴模組採用巢狀的安裝方式: 
##  
優點與缺點
優點:
解決了版本單一時存在的存在的不相容問題,實現多版本相容
#弊端:可能造成相同模組大量冗餘
的問題,如下:
 
以上面例子為例,下面這種情況也是合理存在的:
#憑感覺也知道,這絕不是什麼好現象,那我們如何在實現依賴間多版本相容的前提下,減少這種模組冗餘呢?於是npm3做了改進 
#npm3下的模組安裝機制:
npm3和npm2的不同主要體現在二級模組的安裝上:#npm3會"盡量"##把邏輯上某個層級的模組在物理結構上"全部"放在專案的第一層級裡,具體我概括為以下三種情況:
1.在安裝某個二級模組時,若發現第##等級還沒有相同名稱的模組,便
把這第二層級的模組放在第一層級
2.在安裝某個二級模組時,若發現第層級有相同名稱,相同版本的模組,便
直接重複使用那個模組###############3.在安裝某個二級模組時,若發現第######一#####層級### ###有相同名稱,但版本不同的模組######,便###只能嵌套在自身的父模組下方#########
 
這開始可能有些難理解,所以讓我們看圖片說話吧!
 
#先說1:安裝某個二級模組時,若發現第一層級還沒有相同名稱的模組,便把這第二層級的模組放在第一層級
我們先簡化一下上面的範例:現在專案APP下只有一個一級依賴模組A,它下面有一個二級依賴模組C,但npm install的時候,項目下安裝依賴的

 

npm3中的二級模組(C v1.0),在專案的一級目錄(node_modules)下沒有相同名稱的模組時,會被安裝到一級目錄下,從而跟它的父模組A同級。 這就是本文一開始依賴樹的邏輯結構和物理結構不同的起因
 
也就是說:
在npm2中,依賴樹的邏輯結構和它的物理結構相同
#在npm3中,依賴樹的邏輯結構和它的物理結構可能不同
 
#再說2:在安裝某個二級模組時,若發現第一層級有相同名稱,相同版本的模組,便直接重複使用那個模組
在1的基礎上,我們把1的例子還原回之前的複雜一些的場景::專案APP下有兩個依賴模組A和B;A又有一個依賴模組Cv1.0;而B也有一個依賴模組C v1.0(兩個C模組版本相同)

 

#對npm2,兩個C套件是相同的,造成模組冗餘
在npm3中,因為A模組下的C模組被安裝到了第一級,這使得B模組能夠復用處在同一級下;且名稱,版本,均相同的C模組
npm3就是用這種方式,部分地解決了npm2的痛點(部分)
 
【從1,2到3的過渡】我在這一小節的開始說:「npm3會」盡量」把邏輯上某個層級的模組"全部"放在專案的第一層級」,我想你看完1,2後應該多少有些理解了「盡量」的含義了,但我說了「盡量」,也意味著npm3存在著不能把二級依賴放在第一層級的情況。對此,請看3:
 
#最後說3:在安裝某個二級模組時,若發現第一層層級有相同名稱,但版本不同的模組,只能嵌套在自身的父模組下方
在2中,A,B所依賴的兩個C模組是相同的,但如果兩個C模組的版本不同呢? ,項目npm install情況如下:

 

在npm3中,因為B和A所要求的依賴模組不同,(B下要求是v1.0的C,A下要求是v2.0的C )所以B不能像2中那樣複用A下的C v1.0模組
(看到這裡我想應該能解答你對文章開頭那個例子的疑惑了吧,這個例子和那個例子是幾乎完全一樣的哦)
看到這裡,你對npm2和npm3下的模組工作機制,以及npm3針對npm2的優化有個大體的了解了吧,但請思考一個問題:npm3是否已經把npm2的模組冗餘的缺陷優化到極致了呢? ———答案是沒有,請往下看:
 
##實際上:npm3中仍然可能出現模組冗餘的情況,因為一級目錄下已經有v1.0的C模組了,所以所有的v2.0只能作為二級依賴模組被安裝
,這樣你就會看到如下的情況

## 
 
並且在上圖所示的這種特殊情況裡,npm3和npm2表現得似乎並沒什麼區別
【過渡】那麼這有沒有解決的方式呢?當然是有的,當A模組下的C v1.0模組被更新到C v2.0的前提下,我們可以透過npm dedupe把所有C v2.0的二級依賴模組「重定向」到一級目錄下的那個C v1.0
 
#利用npm dedupe去除冗餘模組:
#npm dedupe做了什麼? 它能夠把凡是能夠去除的冗餘的二級依賴模組,「重定向」到名稱/版本相同的一級模組

 
參考資料 npm官方文件第二節(how npm works ): 
##【溫馨提醒】:任何一篇膾炙人口的博客,都比不上一本厚重的書籍和枯燥的文檔
 
【完】
#每天記10個小單字吧,重在累積哦!
memory:記憶體 Dependency:依賴 constraints:約束deploy:部署parameter:參數scope:作用域
#ecosystems:生態系統prefix:前綴Prior:優先/之前 revoke:撤銷
 ####
##

以上是npm的模組安裝機制詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板