一、npm簡介:
npm全稱為Node Package Manager,是一個基於Node.js的包管理器,也是整個Node.js社區最流行、支持的第三方模塊最多的包管理器。
npm的初衷:JavaScript開發人員更容易分享和重用代碼。
npm的使用場景:
- 允許用戶獲取第三方包並使用。
- 允許用戶將自己編寫的包或命令行程序進行發布分享。
npm版本查詢:npm -v
npm安裝:
1、安裝nodejs
由於新版的nodejs已經集成了npm,所以可直接通過輸入npm -v來測試是否成功安裝。
2、使用npm命令來升級npm: npm install npm -g
二、npm的工作原理:
- 包和模塊:
- 什么是包(package)?
包是描述一個文件或一個目錄。一個包的配置通常由以下構成:
-
-
- 一個文件夾包含一個package.json配置文件。
- 包含(含有package.json文件的文件夾)的Gzip壓縮文件。
- 解析gzip的url
- 為注冊表添加<name>@<version>的url 信息
-
注意的是即使你從來沒有在注冊中心發布你的公共包,你可能仍然可以得到很多所有這些package, 使用npm的好處:
-
-
- 如果你只是計划想寫增加一個節點或/。
- 如果你安裝它也希望在其他地方分成一個tarball后進行包裝
-
Git url的形式:
2.什么是模塊(module)?
模板是通過配置文件中的一個dom節點進行包含一個或多個包。通常一般由包和配置文件以及相關模塊程序構成完成一個或多個業務功能操作。
一個模塊可以在node . js 程序中裝滿任何的require()任何。 以下是所有事物加載模塊的例子 :
-
-
- 一個文件夾
package.json文件包含一個main字段。 - 一個文件夾
index.js文件。 - 一個JavaScript文件。
- 一個文件夾
-
3.npm的包和模塊的關系:
一般來說在js程序中使用require加載它們的模塊在節點中進行配置npm包,一個模塊不一定是一個包。
例如,一些cli包, js程序節點中只包含一個可執行的 命令行界面,不提供main字段。 那么這些包不是模塊。
幾乎所有npm包(至少,那些節點計划)包含許多模塊在他們(因為每個文件加載require()是一個模塊)。
幾乎所有的npm包都關聯着多個模塊,因為每個文件都使用require()加載一個模塊。
從module加載文件中的上下文node節點。如:var req = require('request')。我們可能會說,“request模塊賦值給req這個變量”。
4.npm的生態系統:
package.json文件定義的是包。
node_modules文件夾是存儲模塊的地方。便於js查找模塊。
例如:
如果創建一個node_modules/foo.js文件,通過var f=require('foo.js')進行加載模塊。因為它沒有package.json文件所以foo.js不是一個包。
如果沒有創建index.js包或者package.json文件"main"字段,即使是在安裝node_modules,因為它沒有require()所以它不是一個模塊。
2.npm2的依賴分析:
現在,我們創建一個應用程序需要兩個模塊 模塊A和C。

復雜的關系:
需要一個模塊B的版本,在所有其他的node.js前運行時,我們在試想下包管理器中的js會做些什么?

然而事實不是這樣的,而是如下圖所示:

我們來看下終端所顯示的結構:

我們使用npm is命令來查看下它們的依賴關系:

我們使用npm ls --深度=0命令來看下主要依賴關系:

然而,npm這樣做是不夠的。盡管他們的嵌套的位置允許共存的兩個版本相同的模塊,大多數模塊加載器無法兩個不同版本的相同的模塊加載到內存中。幸運的是,這個節點。js模塊加載程序編寫的正是這種情況,
並可以很容易地加載模塊的兩個版本,他們不會互相沖突。
如NPM和Node.js模塊加載器相同部分使得Node.js唯一適合運行時依賴關系管理。
3.npm3的依賴分析:
npm2和npm3的不同點:
關鍵的主要區別是:
- 在目錄結構中的位置不再預測類型 (主要的,次要的等)的依賴
- 依賴分析取決於安裝順序將會改變
node_modules目錄樹狀結構
npm2:按照一個嵌套方式進行安裝所有依賴項。
npm3:試圖減輕樹的深度和冗余的嵌套。 嘗試通過安裝一些次要的依賴關系在一個平面,需要它作為主要的相同的目錄中依賴。
假設:我們需要一個模塊A依賴模塊B。

現在,讓我們創建一個應用程序,該應用程序依賴模塊A。
npm v2這將發生在一個嵌套的方式。

假設我們想依賴另一個模塊C . C依賴B另一個版本。

然而,由於模塊B v1.0已經是頂級dep,我們不能安裝模塊B v2.0頂級依賴。 npm v3通過違約處理 npm v2行為和嵌套新的,不同的,模塊B版本 依賴的模塊,需要它——在這種情況下,模塊C。

在終端,這看起來是這樣的:

你列表的依賴關系,還能看到他們的關系npm ls:

如果你想看看你的主要依賴關系,可以使用: npm ls -深度= 0

4.npm3的復制和刪除重復數據:
目前我們有一個應用程序 這依賴於兩個模塊:
- 模塊A依賴於模塊Bv1.0
- 模塊C依賴於模塊Bv2.0

現在我們問自己,如果我們安裝另一種依靠模塊B V1.0模塊時會發生什么?或模塊B V2.0?
例如:
假設我們要依賴另一個包,模塊D 依賴於模塊B v2.0,就像模塊C.

因為B v1.0已經是一個頂級的依賴,作為一個頂級的依賴,我們不能安裝版本v2.0 。 因此安裝模塊B v2.0嵌套 依賴的模塊D,即使我們已經安裝了一個副本,嵌套 在模塊C。

如果需要二次依賴通過2 +模塊,但沒有安裝作為一個頂級目錄層次結構中的依賴關系,它將被復制和嵌套在主要依賴。
然而,如果第二個依賴要求2 +模塊,但安裝作為一個頂級目錄層次結構中的依賴性,它不會被復制,並將由主要依賴共享要求。
舉個例子,假設我們現在想依賴模塊E,像模塊A依賴於模塊B v1.0。

因為B v1.0已經是一個頂級的依賴,我們不需要重復的操作。我們只是安裝模塊E,它與模塊A共享模塊B v1.0。

這樣出現在終端:

現在,如果我們更新模塊版本,它取決於模塊B v2.0,不是模塊v1.0嗎?

關鍵是要記住,安裝順序很重要。
即使模塊A是安裝第一個通過我們的package(v1.0).json(按字母順序),因為它是有序的,使用交互式npm意味着模塊A安裝命令v2.0是最后包安裝。
因此,npm3做下面的工作當我們運行npm安裝mod-a@2——保存:
- 它刪除模塊v1.0
- 它安裝模塊版本
- 它葉子模塊Bv1.0因為模塊E v1.0仍然依賴於它
- 它安裝模塊Bv2.0作為v2.0下嵌套依賴模塊, 模塊B v1.0已經占領的頂級目錄層次結構

這在終端看起來像這樣:

最后,讓我們也更新模塊E v2.0,也取決於模塊B v2.0代替模塊B v1.0,就像模塊A更新。
npm3執行以下事情:
- 它刪除模塊E v1.0
- 它安裝模塊版本
- 它刪除模塊B v1.0因為什么依賴於它
- 因為沒有模塊B其他版本,所以它安裝模塊B v2.0的頂級目錄

這在終端看起來像這樣:

現在,這顯然不是理想。 我們在幾乎每一個模塊B v2.0目錄。 去掉重復,我們可以運行: npm dedupe
這個命令解析所有的包依賴模塊B版本 重定向到頂層模塊B v2.0並刪除所有副本 嵌套的副本。

這在終端看起來像這樣:

5.npm3的不確定依賴關系:
例如:

在這個例子中,我們的應用程序有以下package.json:
假設我們有一個模塊A需要更新到2.0版本依賴模塊Bv2.0,而不是依賴模塊Bv1.0.

我們現在使用交互模式的安裝模塊A的新版本:npm install mod-a@2 --save
現在我們使用命令行來查看它們的依賴關系:

它們的關系結構為:

我們按功能要求的更新模塊版本進行配置新的package.json使用應用程序測試服務器運行npm安裝:
測試服務器的日志顯示:

我們看下它們的依賴結構關系:

這棵樹比那棵樹完全不同,它們的內部發生了什么事?
記住:安裝順序很重要。
我們的安裝順序:
npm安裝時首先開始着手項目,所有模塊中列出的包。json已經安裝在node_modules文件夾。
然后模塊版本更新安裝。
它們的變化:
因為此前,模塊A v1.0,模塊B v1.0,模塊E v1.0,模塊C v1.0,模塊D v1.0和模塊E v1.0是頂級依賴,
隨后根據模塊的版本更新,模塊B沒有其他版本可以繼續占據頂級依賴的位置就成為模塊A新版本的新依賴。
由於沒有建立node_modules目錄,我們通過package.json腳本的配置進行安裝依賴關系運行后這個項目會建立一個新目錄。
通過package.json的配置更新模塊A v2.0,按照字母的先后順序進行npm的安裝命令執行,
所以不是最后一次執行。
然后,
因為此前已有node_modules目錄,在更新模塊,首先安裝的是模塊A v2.0,其次是模塊B v2.0,模塊B v2.0迭代模塊B v1.0成為頂級依賴。最后執行模塊E v1.0時由於模塊B v1.0不存在頂級依賴,但有模塊B v1.0這個模塊所以模塊B v1.0無耐地嵌套在模塊E v1.0下。
不同的依賴關系樹結構不會影響我們的應用
即使依賴關系樹的不同,我們都能滿足所有依賴項指向對應的被依賴項進行安裝對應的模塊版本,它們都有各自的配置。
我們應怎么做才能保證node_modules目錄是一樣的?
我們使用npm安裝命令進行安裝,使用package.json,總是會建立相同的樹。這是因為按照package.json的配置進行按字母順序進行安裝。相同的安裝順序意味着你會得到相同的樹。
你可以在移除node_modules目錄並運行npm package.json進行配置你所需要的互相依賴關系樹。
三、npm相關常識:
package.json文件配置目錄:

三、npm的常用命令:
NPM提供了很多命令,例如install和publish,使用npm help可查看所有命令。
-
NPM提供了很多命令,例如
install和publish,使用npm help可查看所有命令。 -
使用
npm help <command>可查看某條命令的詳細幫助,例如npm help install。 -
在
package.json所在目錄下使用npm install . -g可先在本地安裝當前命令行程序,可用於發布前的本地測試。 -
使用
npm update <package>可以把當前目錄下node_modules子目錄里邊的對應模塊更新至最新版本。 -
使用
npm update <package> -g可以把全局安裝的對應命令行程序更新至最新版。 -
使用
npm cache clear可以清空NPM本地緩存,用於對付使用相同版本號發布新版本代碼的人。 -
使用
npm unpublish <package>@<version>可以撤銷發布自己發布過的某個版本代碼。
使用淘寶 NPM 鏡像: npm install -g cnpm --registry=https://registry.npm.taobao.org 詳情見:http://npm.taobao.org/。
使用cnpm來安裝模塊 cnpm install [name]
——
