1.npm是Node官方提供的包管理工具,他已經(jīng)成了Node包的標(biāo)準(zhǔn)發(fā)布平臺(tái),用于Node包的發(fā)布吧秕、傳播斋枢、依賴(lài)控制。npm提供了命令行工具杏头,使你可以方便地下載、安裝、升級(jí)办龄、刪除包,也可以讓你作為開(kāi)發(fā)者發(fā)布并維護(hù)包淋昭。隨著大前端技術(shù)React俐填,webpack,Vue等的發(fā)展翔忽,它的定義變成了廣義的包管理器英融,可以實(shí)現(xiàn)JavaScript盏檐,webpack,Vue驶悟,JQuery胡野,Gulp等包或者模塊管理,是目前開(kāi)源里最大生態(tài)最健全的包管理器
npm是隨同Node一起安裝的包管理工具撩银,能解決Node.js在模塊管理上的很多問(wèn)題给涕,常見(jiàn)的場(chǎng)景有以下幾種:
1.允許用戶(hù)從npm服務(wù)器下載別人編寫(xiě)的第三方包到本地使用。
2.允許用戶(hù)從npm服務(wù)器下載并安裝別人編寫(xiě)的命令行程序到本地使用额获。
3.允許用戶(hù)將自己編寫(xiě)的包或命令行程序上傳到npm服務(wù)器供別人使用够庙。
我們只要一行命令,就能安裝別人寫(xiě)好的模塊 抄邀。
安裝
安裝NPM
由于新版的nodejs已經(jīng)集成了npm耘眨,所以之前npm也一并安裝好了。
?"npm -v" ---查看NPM版本
npm install npm@latest -g.
npm install npm@next -g.
安裝指定版本:npm install npm@4.0.1 -g
NPM版本介紹
NPM v2:典型的樹(shù)形依賴(lài)境肾,層次深依賴(lài)重疊剔难,安裝時(shí)間長(zhǎng)(node V5以下)?
NPM v3:扁平化依賴(lài),將依賴(lài)移到了頂層奥喻,下載速度快不少偶宫,當(dāng)依賴(lài)多個(gè)版本時(shí)采用NPM v2的方式
npm必須首先遍歷所有的項(xiàng)目依賴(lài)關(guān)系,然后再?zèng)Q定如何生成扁平的node_modules目錄結(jié)構(gòu)环鲤。npm必須為所有使用到的模塊構(gòu)建一個(gè)完整的依賴(lài)關(guān)系樹(shù)纯趋,這是一個(gè)耗時(shí)的操作,是npm安裝速度慢的一個(gè)很重要的原因
圖------------------
NPM v5:自動(dòng)記錄依賴(lài)書(shū)冷离,下載使用強(qiáng)校驗(yàn)吵冒,重寫(xiě)緩存系統(tǒng),代表性的改動(dòng):新增了package-json.json用于記錄和鎖定依賴(lài)信息西剥,與Yarn類(lèi)似
將開(kāi)發(fā)者從繁瑣的包管理工作(版本痹栖、依賴(lài)等)中解放出來(lái),更加專(zhuān)注于功能的開(kāi)發(fā)瞭空。
NPM安裝模塊
$ npm install <Module Name>
npm install --選項(xiàng)
本地:
? ? 無(wú)選項(xiàng):不保存在packjson里
? ? --save-prod(--save或-P) :?package.json, Dependencies
? ? --save-dev:package.json,devDependencies(?為避免引用模塊消失揪阿,多人協(xié)同開(kāi)發(fā),保證依賴(lài)模塊出現(xiàn)在package.json里咆畏,--save是好習(xí)慣)
????本地使用:var?lodash?=?require('lodash'); 無(wú)需指定第三方包路徑
全局
?--global(-g)安裝的模塊是全局模塊图甜,如果是命令行模塊,會(huì)直接連接到環(huán)境變量里
兩者兼有:需要在兩個(gè)地方安裝它或使用?npm link
npm提供了一個(gè)有趣的命令npm link鳖眼,它的功能是在本地包和全局包之間創(chuàng)建符號(hào)鏈接。
我們說(shuō)過(guò)使用全局模式安裝的包不能直接通過(guò)require使用嚼摩。但通過(guò)npm link命令可以打破這一限制钦讳。
舉個(gè)例子矿瘦,我們已經(jīng)通過(guò)npm install -g express安裝了express,這時(shí)在工程的目錄下運(yùn)行命令:
npm link express ./node_modules/express ->/user/local/lib/node_modules/express
我們可以在node_modules子目錄中發(fā)現(xiàn)一個(gè)指向安裝到全局的包的符號(hào)鏈接愿卒。通過(guò)這種方法缚去,我們就可以把全局包當(dāng)做本地包來(lái)使用了。 除了將全局的包鏈接到本地以外琼开,使用npm link命令還可以將本地的包鏈接到全局易结。
使用方法是在包目錄(package.json所在目錄)中運(yùn)行npm link命令。如果我們要開(kāi)發(fā)一個(gè)包柜候,利用這種方法可以非常方便地在不同的工程間進(jìn)行測(cè)試搞动。
語(yǔ)義化的版本號(hào):
語(yǔ)義版本號(hào)分為X.Y.Z三位,分別代表主版本號(hào)渣刷、次版本號(hào)和補(bǔ)丁版本號(hào)鹦肿。當(dāng)代碼變更時(shí),版本號(hào)按以下原則更新辅柴。
補(bǔ)丁版本箩溃,解決了bug或者一些較小的更改,增加最后一位數(shù)字碌嘀,如:1.0.1
小版本涣旨,增加了新特性,同時(shí)不會(huì)影響之前的版本股冗,增加中間一位數(shù)據(jù)霹陡,如:1.1.0
大版本,大改版魁瞪,無(wú)法兼容之前的版本穆律,增加第一位數(shù)字,如:2.0.0
~會(huì)匹配最近的小版本依賴(lài)包导俘,比如~1.2.3會(huì)匹配所有1.2.x版本峦耘,但是不包括1.3.0
^會(huì)匹配最新的大版本依賴(lài)包,比如^1.2.3會(huì)匹配所有1.x.x的包旅薄,包括1.3.0辅髓,但是不包括2.0.0
*會(huì)安裝最新版本的依賴(lài)包
使用方案:
指定特定的版本號(hào),直接寫(xiě)1.2.3少梁,前面什么前綴都沒(méi)有洛口,這樣固然沒(méi)問(wèn)題,但是如果依賴(lài)包發(fā)布新版本修復(fù)了一些小bug凯沪,那么需要手動(dòng)修改package.json文件第焰;~和^則可以解決這個(gè)問(wèn)題。但是需要注意^版本更新可能比較大妨马,會(huì)造成項(xiàng)目代碼錯(cuò)誤挺举,所以建議使用~來(lái)標(biāo)記版本號(hào)杀赢,這樣可以保證項(xiàng)目不會(huì)出現(xiàn)大的問(wèn)題,也能保證包中的小bug可以得到修復(fù)湘纵。版本號(hào)寫(xiě)*脂崔,這意味著安裝最新版本的依賴(lài)包,但缺點(diǎn)同上梧喷,可能會(huì)造成版本不兼容砌左,慎用!
Working with package.json
npm init新建一個(gè)package.json:使用-f(代表force)铺敌、-y(代表yes)汇歹,則跳過(guò)提問(wèn)階段
或者使用
npm set
npm set用來(lái)設(shè)置環(huán)境變量
$ npmsetinit-author-name'Your name'
$ npmsetinit-author-email'Your email'
$ npmsetinit-author-url'http://yourdomain.com'$ npmsetinit-license'MIT'
上面命令等于為npm init設(shè)置了默認(rèn)值,以后執(zhí)行npm init的時(shí)候适刀,package.json的作者姓名秤朗、郵件、主頁(yè)笔喉、許可證字段就會(huì)自動(dòng)寫(xiě)入預(yù)設(shè)的值取视。這些信息會(huì)存放在用戶(hù)主目錄的~/.npmrc文件,使得用戶(hù)不用每個(gè)項(xiàng)目都輸入常挚。
dependencies:--save
應(yīng)用能夠正常運(yùn)行所依賴(lài)的包作谭。這種 dependencies 是最常見(jiàn)的,用戶(hù)在使用 npm install 安裝你的包時(shí)會(huì)自動(dòng)安裝這些依賴(lài)奄毡。
devDependencies:--save-dev
開(kāi)發(fā)應(yīng)用時(shí)所依賴(lài)的工具包折欠。通常是一些開(kāi)發(fā)、測(cè)試吼过、打包工具锐秦,例如 webpack、ESLint盗忱、Mocha酱床。應(yīng)用正常運(yùn)行并不依賴(lài)于這些包,用戶(hù)在使用 npm install 安裝你的包時(shí)也不會(huì)安裝這些依賴(lài)趟佃。
當(dāng)項(xiàng)目正式上線(xiàn)的時(shí)候扇谣,開(kāi)發(fā)依賴(lài)可以刪除,生產(chǎn)依賴(lài)不可以刪除闲昭。
npm不僅可以用于模塊管理罐寨,還可以用于執(zhí)行腳本。package.json文件有一個(gè)scripts字段序矩,可以用于指定腳本命令鸯绿,供npm直接調(diào)用
更新
npm outdated 查看有哪些過(guò)時(shí)的軟件包
npm update <packageName>(禁止不加packageName)
npm install 版本號(hào)
更新的原理:
NPM組成三部分中包括歐注冊(cè)表:?是一個(gè)巨大的數(shù)據(jù)庫(kù),保存了每個(gè)包(package)的信息
https://registry.npmjs.org/react/v0.14.6
返回的 JSON 對(duì)象里面,有一個(gè)dist.tarball屬性楞慈,是該版本壓縮包的網(wǎng)址幔烛。
模塊的安裝過(guò)程
發(fā)出npm install命令
npm 向 registry 查詢(xún)模塊壓縮包的網(wǎng)址
下載壓縮包,存放在~/.npm目錄
解壓壓縮包到當(dāng)前項(xiàng)目的node_modules目錄
卸載:
npm uninstall (-g)<packageName>
對(duì)比
NRM:
nrm(npm registry manager )是npm的鏡像源管理工具
npm install -g nrm
nrm ls? ? ? ? ? ? ? ?
nrm test 測(cè)速:國(guó)內(nèi)CNPM和taobao更有優(yōu)勢(shì)囊蓝,尤其在阿里云上部署時(shí)
nrm use taobao
npm yarn pnpm cnpm
nrm?add yourcompany http://registry.npm.yourcompany.com/
內(nèi)網(wǎng)部署NPM源的好處:
1.安裝速度快
2.私有模塊,僅供企業(yè)內(nèi)部使用令蛉,更安全
3.適合多團(tuán)隊(duì)開(kāi)發(fā)
CNPM?
cnpm跟npm用法完全一致聚霜,只是在執(zhí)行命令時(shí)將npm改為cnpm。
npm安裝插件是從國(guó)外服務(wù)器下載珠叔,受網(wǎng)絡(luò)影響大蝎宇,可能出現(xiàn)異常,如果npm的服務(wù)器在中國(guó)就好了祷安,于是淘寶團(tuán)隊(duì)干了這事姥芥。來(lái)自官網(wǎng):“這是一個(gè)完整 npmjs.org 鏡像,你可以用此代替官方版本(只讀)汇鞭,同步頻率目前為 10分鐘 一次以保證盡量與官方服務(wù)同步凉唐。”
NPM最大的問(wèn)題:::
即使不同的開(kāi)發(fā)人員使用了相同的package.json文件霍骄,在他們自己的機(jī)器上也可能會(huì)安裝同一個(gè)庫(kù)的不同種版本台囱,這樣就會(huì)存在潛在的難以調(diào)試的錯(cuò)誤和“在我的電腦上…”的情形。
大多數(shù)npm庫(kù)都嚴(yán)重依賴(lài)于其他npm庫(kù)读整,這會(huì)導(dǎo)致嵌套依賴(lài)關(guān)系簿训,并增加無(wú)法匹配相應(yīng)版本的幾率。
雖然可以通過(guò)npm config set save-exact true命令關(guān)閉在版本號(hào)前面使用^的默認(rèn)行為米间,但這個(gè)只會(huì)影響頂級(jí)依賴(lài)關(guān)系强品。由于每個(gè)依賴(lài)的庫(kù)都有自己的package.json文件,而在它們自己的依賴(lài)關(guān)系前面可能會(huì)有^符號(hào)屈糊,所以無(wú)法通過(guò)package.json文件為嵌套依賴(lài)的內(nèi)容提供保證的榛。
為了解決這個(gè)問(wèn)題,npm提供了shrinkwrap命令另玖。此命令將生成一個(gè)npm-shrinkwrap.json文件困曙,為所有庫(kù)和所有嵌套依賴(lài)的庫(kù)記錄確切的版本。
Yarn
Yarn發(fā)布于2016年10月
Yarn一開(kāi)始的主要目標(biāo)是解決上一節(jié)中描述的由于語(yǔ)義版本控制而導(dǎo)致的npm安裝的不確定性問(wèn)題谦去。雖然可以使用npm shrinkwrap來(lái)實(shí)現(xiàn)可預(yù)測(cè)的依賴(lài)關(guān)系樹(shù)慷丽,但它并不是默認(rèn)選項(xiàng),而是取決于所有的開(kāi)發(fā)人員知道并且啟用這個(gè)選項(xiàng)鳄哭。(npm5.0之前存在的問(wèn)題)
Yarn采取了不同的做法要糊。每個(gè)yarn安裝都會(huì)生成一個(gè)類(lèi)似于npm-shrinkwrap.json的yarn.lock文件,而且它是默認(rèn)創(chuàng)建的妆丘。除了常規(guī)信息之外锄俄,yarn.lock文件還包含要安裝的內(nèi)容的校驗(yàn)和局劲,以確保使用的庫(kù)的版本相同。
yarn是經(jīng)過(guò)重新設(shè)計(jì)的嶄新的npm客戶(hù)端奶赠,它能讓開(kāi)發(fā)人員并行處理所有必須的操作鱼填,并添加了一些其他改進(jìn)。
運(yùn)行速度得到了顯著的提升毅戈,整個(gè)安裝時(shí)間也變得更少
pnpm
可閱讀pnpm的作者Zoltan Kochan發(fā)表的“為什么要用pnpm苹丸?”
https://blog.csdn.net/cuk0051/article/details/108341552
pnpm采用了一種巧妙的方法,利用硬鏈接和符號(hào)鏈接來(lái)避免復(fù)制所有本地緩存源文件苇经,這是yarn的最大的性能弱點(diǎn)之一
使用鏈接并不容易赘理,會(huì)帶來(lái)一堆問(wèn)題需要考慮。
pnpm繼承了yarn的所有優(yōu)點(diǎn)扇单,包括離線(xiàn)模式和確定性安裝
創(chuàng)建NPM包
包是在模塊基礎(chǔ)上更深一步的抽象商模,Node的包類(lèi)似于C/C++的函數(shù)庫(kù)或者Java、.Net的類(lèi)庫(kù)蜘澜。它將某個(gè)獨(dú)立的功能封裝起來(lái)施流,用于發(fā)布、更新兼都、依賴(lài)管理和版本控制嫂沉。
Node根據(jù)CommonJS規(guī)范實(shí)現(xiàn)了包機(jī)制,開(kāi)發(fā)了npm來(lái)解決包的發(fā)布和獲取需求扮碧。
Node的包是一個(gè)目錄趟章,其中包含了一個(gè)JSON格式的包說(shuō)明文件package.json。
嚴(yán)格符合CommonJS規(guī)范的包應(yīng)該具備以下特征:
package.json必須在包的頂層目錄下慎王;
二進(jìn)制文件應(yīng)該在bin目錄下蚓土;
JavaScript代碼應(yīng)該在lib目錄下;
文檔應(yīng)該在doc目錄下赖淤;
單元測(cè)試應(yīng)該在test目錄下蜀漆。
Node對(duì)包的要求并沒(méi)有這么嚴(yán)格,只要頂層目錄下有package.json咱旱,并符合一些規(guī)范即可确丢。當(dāng)然為了提高兼容性,我們還是建議你在制作包的時(shí)候吐限,嚴(yán)格遵守CommonJS規(guī)范鲜侥。
我們也可以把文件夾封裝為一個(gè)模塊,即所謂的包诸典。包通常是一些模塊的集合描函,在模塊的基礎(chǔ)上提供了更高層的抽象,相當(dāng)于提供了一些固定接口的函數(shù)庫(kù)。通過(guò)定制package.json舀寓,我們可以創(chuàng)建更復(fù)雜胆数,更完善,更符合規(guī)范的包用于發(fā)布互墓。
Node在調(diào)用某個(gè)包時(shí)必尼,會(huì)首先檢查包中packgage.json文件的main字段,將其作為包的接口模塊轰豆,如果package.json或main字段不存在胰伍,會(huì)嘗試尋找 index.js 或 index.node 作為包的接口。
package.json是CommonJS規(guī)定的用來(lái)描述包的文件酸休,完全符合規(guī)范的package.json文件應(yīng)該含有以下字段: name: 包的名字,必須是唯一的祷杈,由小寫(xiě)英文字母斑司、數(shù)字和下劃線(xiàn)組成,不能包含空格但汞。
description: 包的簡(jiǎn)要說(shuō)明宿刮。
version: 符合語(yǔ)義化版本識(shí)別規(guī)范的版本字符串。
keywords: 關(guān)鍵字?jǐn)?shù)組私蕾,通常用于搜索僵缺。
maintainers: 維護(hù)者數(shù)組,每個(gè)元素要包含name踩叭、email(可選)磕潮、web(可選)字段。
contributors: 貢獻(xiàn)者數(shù)組容贝,格式與maintainers相同自脯。包的作者應(yīng)該是貢獻(xiàn)者數(shù)組的第一個(gè)元素。
bugs: 提交bug的地址斤富,可以是網(wǎng)址或者電子郵件地址膏潮。
licenses: 許可證數(shù)組,每個(gè)元素要包含type(許可證的名稱(chēng))和 url(鏈接到許可證文本的地址)字段满力。
repositories: 倉(cāng)庫(kù)托管地址數(shù)組焕参,每個(gè)元素要包含type(倉(cāng)庫(kù)的類(lèi)型,如 git)油额、URL(倉(cāng)庫(kù)的地址)和 path(相對(duì)于倉(cāng)庫(kù)的路徑叠纷,可選)字段。
dependencies: 包的依賴(lài)悔耘,一個(gè)關(guān)聯(lián)數(shù)組讲岁,由包名稱(chēng)和版本號(hào)組成。
包的發(fā)布
通過(guò)使用npm init可以根據(jù)交互式回答產(chǎn)生一個(gè)符合標(biāo)準(zhǔn)的package.json。創(chuàng)建一個(gè)index.js作為包的接口,一個(gè)簡(jiǎn)單的包就制作完成了缓艳。
在發(fā)布前,我們還需要獲得一個(gè)賬號(hào)用于今后維護(hù)自己的包,使用npm adduser根據(jù)提示完成賬號(hào)的創(chuàng)建 完成后可以使用npm whoami檢測(cè)是否已經(jīng)取得了賬號(hào)校摩。
接下來(lái),在package.json所在目錄下運(yùn)行npm publish,稍等片刻就可以完成發(fā)布了阶淘,
打開(kāi)瀏覽器衙吩,訪(fǎng)問(wèn)NPM搜索就可以找到自己剛剛發(fā)布的包了。
現(xiàn)在我們可以在世界的任意一臺(tái)計(jì)算機(jī)上使用npm install neveryumodule命令來(lái)安裝它溪窒。
如果你的包將來(lái)有更新,只需要在package.json文件中修改version字段,然后重新使用npm publish命令就行了坤塞。
如果你對(duì)已發(fā)布的包不滿(mǎn)意,可以使用npm unpublish命令來(lái)取消發(fā)布澈蚌。
使用