一、npm簡介: npm全稱為Node Package Manager,是一個(gè)基于Node.js的包管理器,也是整個(gè)Node.js社區(qū)最流行、支持的第三方模塊最多的包管理器。 npm的初衷:JavaScript開發(fā)人員更容易分享和重用代碼。 npm的使用場(chǎng)景:
npm版本查詢:npm -v npm安裝: 1、安裝nodejs 由于新版的nodejs已經(jīng)集成了npm,所以可直接通過輸入npm -v來測(cè)試是否成功安裝。 2、使用npm命令來升級(jí)npm: npm install npm -g 二、npm的工作原理:
包是描述一個(gè)文件或一個(gè)目錄。一個(gè)包的配置通常由以下構(gòu)成:
注意的是即使你從來沒有在注冊(cè)中心發(fā)布你的公共包,你可能仍然可以得到很多所有這些
Git url的形式: git:/ /github.com/user/project.git # commit-ish
git + ssh:/ / user@hostname:project.git # commit-ish
git +http://user@hostname項(xiàng)目/ blah.git # commit-ish
git +https://user@hostname項(xiàng)目/ blah.git # commit-ish
可以撿出commit-ish的一個(gè)git任何標(biāo)簽和master分支、安全哈希算法。
2.什么是模塊(module)? 模板是通過配置文件中的一個(gè)dom節(jié)點(diǎn)進(jìn)行包含一個(gè)或多個(gè)包。通常一般由包和配置文件以及相關(guān)模塊程序構(gòu)成完成一個(gè)或多個(gè)業(yè)務(wù)功能操作。 一個(gè)模塊可以在node . js 程序中裝滿任何的
3.npm的包和模塊的關(guān)系: 一般來說在js程序中使用require加載它們的模塊在節(jié)點(diǎn)中進(jìn)行配置npm包,一個(gè)模塊不一定是一個(gè)包。 例如,一些 幾乎所有npm包(至少,那些節(jié)點(diǎn)計(jì)劃)包含許多模塊在他們(因?yàn)槊總€(gè)文件加載 幾乎所有的npm包都關(guān)聯(lián)著多個(gè)模塊,因?yàn)槊總€(gè)文件都使用require()加載一個(gè)模塊。 從module加載文件中的上下文node節(jié)點(diǎn)。如:var req = require('request')。我們可能會(huì)說,“ 4.npm的生態(tài)系統(tǒng): 例如: 如果創(chuàng)建一個(gè)node_modules/foo.js文件,通過var f=require('foo.js')進(jìn)行加載模塊。因?yàn)樗鼪]有package.json文件所以foo.js不是一個(gè)包。 如果沒有創(chuàng)建 2.npm2的依賴分析: 現(xiàn)在,我們創(chuàng)建一個(gè)應(yīng)用程序需要兩個(gè)模塊 模塊A和C。 復(fù)雜的關(guān)系: 需要一個(gè)模塊B的版本,在所有其他的node.js前運(yùn)行時(shí),我們?cè)谠囅胂掳芾砥髦械膉s會(huì)做些什么? 然而事實(shí)不是這樣的,而是如下圖所示: 我們來看下終端所顯示的結(jié)構(gòu): 我們使用npm is命令來查看下它們的依賴關(guān)系: 我們使用npm ls --深度=0命令來看下主要依賴關(guān)系: 然而,npm這樣做是不夠的。盡管他們的嵌套的位置允許共存的兩個(gè)版本相同的模塊,大多數(shù)模塊加載器無法兩個(gè)不同版本的相同的模塊加載到內(nèi)存中。幸運(yùn)的是,這個(gè)節(jié)點(diǎn)。js模塊加載程序編寫的正是這種情況, 并可以很容易地加載模塊的兩個(gè)版本,他們不會(huì)互相沖突。 如NPM和Node.js模塊加載器相同部分使得Node.js唯一適合運(yùn)行時(shí)依賴關(guān)系管理。 3.npm3的依賴分析: npm2和npm3的不同點(diǎn): 關(guān)鍵的主要區(qū)別是:
npm2:按照一個(gè)嵌套方式進(jìn)行安裝所有依賴項(xiàng)。 npm3:試圖減輕樹的深度和冗余的嵌套。 嘗試通過安裝一些次要的依賴關(guān)系在一個(gè)平面,需要它作為主要的相同的目錄中依賴。 假設(shè):我們需要一個(gè)模塊A依賴模塊B。 現(xiàn)在,讓我們創(chuàng)建一個(gè)應(yīng)用程序,該應(yīng)用程序依賴模塊A。 npm v2這將發(fā)生在一個(gè)嵌套的方式。 假設(shè)我們想依賴另一個(gè)模塊C . C依賴B另一個(gè)版本。 然而,由于模塊B v1.0已經(jīng)是頂級(jí)dep,我們不能安裝模塊B v2.0頂級(jí)依賴。 npm v3通過違約處理 npm v2行為和嵌套新的,不同的,模塊B版本 依賴的模塊,需要它——在這種情況下,模塊C。 在終端,這看起來是這樣的: 你列表的依賴關(guān)系,還能看到他們的關(guān)系npm ls: 如果你想看看你的主要依賴關(guān)系,可以使用: npm ls -深度= 0 4.npm3的復(fù)制和刪除重復(fù)數(shù)據(jù): 目前我們有一個(gè)應(yīng)用程序 這依賴于兩個(gè)模塊:
現(xiàn)在我們問自己,如果我們安裝另一種依靠模塊B V1.0模塊時(shí)會(huì)發(fā)生什么?或模塊B V2.0? 例如: 假設(shè)我們要依賴另一個(gè)包,模塊D 依賴于模塊B v2.0,就像模塊C. 因?yàn)锽 v1.0已經(jīng)是一個(gè)頂級(jí)的依賴,作為一個(gè)頂級(jí)的依賴,我們不能安裝版本v2.0 。 因此安裝模塊B v2.0嵌套 依賴的模塊D,即使我們已經(jīng)安裝了一個(gè)副本,嵌套 在模塊C。 如果需要二次依賴通過2 +模塊,但沒有安裝作為一個(gè)頂級(jí)目錄層次結(jié)構(gòu)中的依賴關(guān)系,它將被復(fù)制和嵌套在主要依賴。 然而,如果第二個(gè)依賴要求2 +模塊,但安裝作為一個(gè)頂級(jí)目錄層次結(jié)構(gòu)中的依賴性,它不會(huì)被復(fù)制,并將由主要依賴共享要求。 舉個(gè)例子,假設(shè)我們現(xiàn)在想依賴模塊E,像模塊A依賴于模塊B v1.0。 因?yàn)锽 v1.0已經(jīng)是一個(gè)頂級(jí)的依賴,我們不需要重復(fù)的操作。我們只是安裝模塊E,它與模塊A共享模塊B v1.0。 這樣出現(xiàn)在終端: 現(xiàn)在,如果我們更新模塊版本,它取決于模塊B v2.0,不是模塊v1.0嗎? 關(guān)鍵是要記住,安裝順序很重要。 即使模塊A是安裝第一個(gè)通過我們的package(v1.0).json(按字母順序),因?yàn)樗怯行虻?使用交互式npm意味著模塊A安裝命令v2.0是最后包安裝。 因此,npm3做下面的工作當(dāng)我們運(yùn)行npm安裝mod-a@2——保存:
這在終端看起來像這樣: 最后,讓我們也更新模塊E v2.0,也取決于模塊B v2.0代替模塊B v1.0,就像模塊A更新。 npm3執(zhí)行以下事情:
這在終端看起來像這樣: 現(xiàn)在,這顯然不是理想。 我們?cè)趲缀趺恳粋€(gè)模塊B v2.0目錄。 去掉重復(fù),我們可以運(yùn)行: npm dedupe 這個(gè)命令解析所有的包依賴模塊B版本 重定向到頂層模塊B v2.0并刪除所有副本 嵌套的副本。 這在終端看起來像這樣: 5.npm3的不確定依賴關(guān)系: 例如: 在這個(gè)例子中,我們的應(yīng)用程序有以下 {
"name": "example3", //名稱
"version": "1.0.0", //版本
"description": "", //描述
"main": "index.js", //主要入口
"scripts": { //腳本
"test": "echo \"Error: no test specified\" && exit 1" //測(cè)試路徑
},
"keywords": [], //關(guān)鍵字
"author": "", //作者
"license": "ISC", //許可證
"dependencies": { //依賴模塊
"mod-a": "^1.0.0",
"mod-c": "^1.0.0",
"mod-d": "^1.0.0",
"mod-e": "^1.0.0"
}
}
使用npm install命令查看依賴關(guān)系:
![]() 假設(shè)我們有一個(gè)模塊A需要更新到2.0版本依賴模塊Bv2.0,而不是依賴模塊Bv1.0. 我們現(xiàn)在使用交互模式的安裝模塊A的新版本:npm install mod-a@2 --save 現(xiàn)在我們使用命令行來查看它們的依賴關(guān)系: 它們的關(guān)系結(jié)構(gòu)為: 我們按功能要求的更新模塊版本進(jìn)行配置新的package.json使用應(yīng)用程序測(cè)試服務(wù)器運(yùn)行npm安裝: {
"name": "example3",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"mod-a": "^2.0.0",
"mod-c": "^1.0.0",
"mod-d": "^1.0.0",
"mod-e": "^1.0.0"
}
}
測(cè)試服務(wù)器的日志顯示: 我們看下它們的依賴結(jié)構(gòu)關(guān)系: 這棵樹比那棵樹完全不同,它們的內(nèi)部發(fā)生了什么事? 記住:安裝順序很重要。 我們的安裝順序: npm安裝時(shí)首先開始著手項(xiàng)目,所有模塊中列出的包。json已經(jīng)安裝在node_modules文件夾。 然后模塊版本更新安裝。 它們的變化: 因?yàn)榇饲?模塊A v1.0,模塊B v1.0,模塊E v1.0,模塊C v1.0,模塊D v1.0和模塊E v1.0是頂級(jí)依賴, 隨后根據(jù)模塊的版本更新,模塊B沒有其他版本可以繼續(xù)占據(jù)頂級(jí)依賴的位置就成為模塊A新版本的新依賴。 由于沒有建立node_modules目錄,我們通過package.json腳本的配置進(jìn)行安裝依賴關(guān)系運(yùn)行后這個(gè)項(xiàng)目會(huì)建立一個(gè)新目錄。 通過package.json的配置更新模塊A v2.0,按照字母的先后順序進(jìn)行npm的安裝命令執(zhí)行, 所以不是最后一次執(zhí)行。 然后, 因?yàn)榇饲耙延?/span>node_modules目錄,在更新模塊,首先安裝的是模塊A v2.0,其次是模塊B v2.0,模塊B v2.0迭代模塊B v1.0成為頂級(jí)依賴。最后執(zhí)行模塊E v1.0時(shí)由于模塊B v1.0不存在頂級(jí)依賴,但有模塊B v1.0這個(gè)模塊所以模塊B v1.0無耐地嵌套在模塊E v1.0下。 不同的依賴關(guān)系樹結(jié)構(gòu)不會(huì)影響我們的應(yīng)用 即使依賴關(guān)系樹的不同,我們都能滿足所有依賴項(xiàng)指向?qū)?yīng)的被依賴項(xiàng)進(jìn)行安裝對(duì)應(yīng)的模塊版本,它們都有各自的配置。 我們應(yīng)怎么做才能保證node_modules目錄是一樣的? 我們使用npm安裝命令進(jìn)行安裝,使用package.json,總是會(huì)建立相同的樹。這是因?yàn)榘凑誴ackage.json的配置進(jìn)行按字母順序進(jìn)行安裝。相同的安裝順序意味著你會(huì)得到相同的樹。 你可以在移除node_modules目錄并運(yùn)行npm package.json進(jìn)行配置你所需要的互相依賴關(guān)系樹。 三、npm相關(guān)常識(shí): package.json文件配置目錄: 三、npm的常用命令: NPM提供了很多命令,例如install和publish,使用npm help可查看所有命令。
使用淘寶 NPM 鏡像: npm install -g cnpm --registry=https://registry.npm. 詳情見:http://npm./。 使用cnpm來安裝模塊 cnpm install [name]
—— |
|