一位用不好包管理器的前端,是一個(gè)入門級(jí)前端,一個(gè)用不好webpack
的前端,是一個(gè)初級(jí)前端
三個(gè)包管理器是可以一起用的,只要你夠膽大心細(xì),就沒任何問(wèn)題!
在javeScript
編寫中,我們盡量不要定義全局變量,封裝函數(shù)盡量不要有副作用,因?yàn)槿孔兞康牟樵儠r(shí)間會(huì)比局部變量的查詢慢,更是考慮在Node的環(huán)境中無(wú)法被垃圾回收的問(wèn)題
老規(guī)矩 先看原理
npm
npm
是Node.js
能夠如此成功的主要原因之一。npm
團(tuán)隊(duì)做了很多的工作,以確保 npm 保持向后兼容,并在不同的環(huán)境中保持一致。npm是圍繞著 語(yǔ)義版本控制(semver)的思想而設(shè)計(jì)。
給定一個(gè)版本號(hào):主版本號(hào).次版本號(hào).補(bǔ)丁版本號(hào), 以下這三種情況需要增加相應(yīng)的版本號(hào):
主版本號(hào): 當(dāng)API發(fā)生改變,并與之前的版本不兼容的時(shí)候
次版本號(hào): 當(dāng)增加了功能,但是向后兼容的時(shí)候
補(bǔ)丁版本號(hào):當(dāng)做了向后兼容的缺陷修復(fù)的時(shí)候
npm 2
會(huì)安裝每一個(gè)包所依賴的所有依賴項(xiàng)。如果我們有這么一個(gè)項(xiàng)目,它依賴項(xiàng)目A,項(xiàng)目A依賴項(xiàng)目B,項(xiàng)目B依賴項(xiàng)目C,那么依賴樹將如下所示:這個(gè)結(jié)構(gòu)可能會(huì)很長(zhǎng)。這對(duì)于基于Unix的操作系統(tǒng)來(lái)說(shuō)只不過(guò)是一個(gè)小煩惱,但對(duì)于Windows來(lái)說(shuō)卻是個(gè)破壞性的東西,因?yàn)橛泻芏喑绦驘o(wú)法處理超過(guò)260個(gè)字符的文件路徑名。
npm 3
采用了扁平依賴關(guān)系樹來(lái)解決這個(gè)問(wèn)題,所以我們的3個(gè)項(xiàng)目結(jié)構(gòu)現(xiàn)在看起來(lái)如下所示:
存了已經(jīng)下載的每個(gè)版本的壓縮包。本地緩存的內(nèi)容可以通過(guò)npm cache ls命令進(jìn)行查看。本地緩存的設(shè)計(jì)有助于減少安裝時(shí)間。
[圖片上傳失敗...(image-5457e5-1559035973365)]
- 這樣,一個(gè)原來(lái)很長(zhǎng)的文件路徑名就從
./node_modules/package-A/node_modules/package-B/node-modules/some-file-name-in-package-c.js
變成了/node_modules/some-file-name-in-package-c.js
。 - 這種方法的缺點(diǎn)是,
npm
必須首先遍歷所有的項(xiàng)目依賴關(guān)系,然后再?zèng)Q定如何生成扁平的node_modules目錄結(jié)構(gòu)。npm必須為所有使用到的模塊構(gòu)建一個(gè)完整的依賴關(guān)系樹,這是一個(gè)耗時(shí)的操作,是npm安裝速度慢的一個(gè)很重要的原因。 - 想當(dāng)然的以為每次運(yùn)行
npm install
命令時(shí),NPM
都得從互聯(lián)網(wǎng)上下載所有內(nèi)容。 - 但是,
npm
是有本地緩存的,它保存了已經(jīng)下載的每個(gè)版本的壓縮包。本地緩存的內(nèi)容可以通過(guò)npm cache ls
命令進(jìn)行查看。本地緩存的設(shè)計(jì)有助于減少安裝時(shí)間。
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ù)同步。” - 官方地址:
http://npm.taobao.org
- 安裝:
npm install -g cnpm --registry=https://registry.npm.taobao.org
Yarn
-
Yarn
一開始的主要目標(biāo)是解決上一節(jié)中描述的由于語(yǔ)義版本控制而導(dǎo)致的npm安裝的不確定性問(wèn)題。雖然可以使用npm shrinkwrap
來(lái)實(shí)現(xiàn)可預(yù)測(cè)的依賴關(guān)系樹,但它并不是默認(rèn)選項(xiàng),而是取決于所有的開發(fā)人員知道并且啟用這個(gè)選項(xiàng)。 -
Yarn
采取了不同的做法。每個(gè)yarn安裝都會(huì)生成一個(gè)類似于npm-shrinkwrap.json的yarn.lock文件,而且它是默認(rèn)創(chuàng)建的。除了常規(guī)信息之外,yarn.lock
文件還包含要安裝的內(nèi)容的校驗(yàn)和,以確保使用的庫(kù)的版本相同。 - yarn是經(jīng)過(guò)重新設(shè)計(jì)的嶄新的npm客戶端,它能讓開發(fā)人員并行處理所有必須的操作,并添加了一些其他改進(jìn)。
- 運(yùn)行速度得到了顯著的提升,整個(gè)安裝時(shí)間也變得更少
- 像npm一樣,yarn使用本地緩存。
與npm不同的是,yarn無(wú)需互聯(lián)網(wǎng)連接就能安裝本地緩存的依賴項(xiàng),它提供了離線模式
。 - 允許合并項(xiàng)目中使用到的所有的包的許可證
- 通常情況下不建議通過(guò)npm進(jìn)行安裝。npm安裝是非確定性的,程序包沒有簽名,并且npm除了做了基本的SHA1哈希之外不執(zhí)行任何完整性檢查,這給安裝系統(tǒng)程序帶來(lái)了安全風(fēng)險(xiǎn)。(作者曾經(jīng)在一個(gè)上百個(gè)依賴包的項(xiàng)目中使用
npm
丟包過(guò),代價(jià)非常大,淚水不自覺掉下來(lái))
首先看一次非常失敗的包下載 竟然是從全局讀取的資源(不配置
webpack
別名是因?yàn)榫瓦@一個(gè)路徑這么長(zhǎng))
[圖片上傳失敗...(image-5e86ef-1559035973365)]
首先我們從原理入手 ,我們使用
npm init
,yarn init
,cnpm init
的時(shí)候 發(fā)生了什么 ?
- 生成
package.json
文件 -
json
文件內(nèi)部聲明初始的版本信息、作者信息等,如果你是需要上傳到npm上作為命令行工具,應(yīng)該配置bin
等聲明入口字段
那么當(dāng)我們使用
npm i
,yarn add
,cnpm i
操作時(shí)候會(huì)發(fā)生什么 ?
- 首先會(huì)根據(jù)你的命令行后綴是否加了
-g
或者global
判斷,下載的包是放在全局的環(huán)境,還是當(dāng)前package.json
文件對(duì)應(yīng)的node_module
文件夾目錄下(這點(diǎn)尤其重要,有人出BUG,就是因?yàn)樵谟?code>npm,cnpm
時(shí)候沒有注明添加的是全局依賴還是本地依賴,導(dǎo)致json
文件上沒有對(duì)應(yīng)的包名,項(xiàng)目永遠(yuǎn)起不來(lái)) - 然后根據(jù)你的指令
--save
或者-D
、--save -dev
判斷是開發(fā)依賴還是線上依賴,其實(shí)這點(diǎn)在yarn
上沒有問(wèn)題,因?yàn)?code>yarn有自己的一套檢查包完整性的機(jī)制,不會(huì)丟包,還會(huì)自動(dòng)判斷添加依賴,出bug
一般是cnpm
和npm
,沒有明確-g
或者--save
,npm
只有檢查程序員簽名的機(jī)制,沒有檢查包完整性的機(jī)制,也不會(huì)自動(dòng)添加依賴到json
文件,那么就會(huì)出現(xiàn)丟包的假象,所以建議主要使用yarn
yarn
和npm
對(duì)比
[圖片上傳失敗...(image-d6d78b-1559035973364)]
npm
的缺點(diǎn)匯總:
- 同一個(gè)項(xiàng)目,安裝的時(shí)候無(wú)法保持一致性。由于package.json文件中版本號(hào)的特點(diǎn),下面三個(gè)版本號(hào)在安裝的時(shí)候代表不同的含義。
"5.0.3",
"~5.0.3",
"^5.0.3"
- “5.0.3”表示安裝指定的5.0.3版本,“~5.0.3”表示安裝5.0.X中最新的版本,“^5.0.3”表示安裝5.X.X中最新的版本。這就麻煩了,常常會(huì)出現(xiàn)同一個(gè)項(xiàng)目,有的同事是OK的,有的同事會(huì)由于安裝的版本不一致出現(xiàn)
bug
。 - 安裝的時(shí)候,包會(huì)在同一時(shí)間下載和安裝,中途某個(gè)時(shí)候,一個(gè)包拋出了一個(gè)錯(cuò)誤,但是npm會(huì)繼續(xù)下載和安裝包。因?yàn)閚pm會(huì)把所有的日志輸出到終端,有關(guān)錯(cuò)誤包的錯(cuò)誤信息就會(huì)在一大堆
npm
打印的警告中丟失掉,并且你甚至永遠(yuǎn)不會(huì)注意到實(shí)際發(fā)生的錯(cuò)誤。
yarn
的優(yōu)點(diǎn)
- 速度快 。速度快主要來(lái)自以下兩個(gè)方面:
- 并行安裝:無(wú)論
npm
還是Yarn
在執(zhí)行包的安裝時(shí),都會(huì)執(zhí)行一系列任務(wù)。npm
是按照隊(duì)列執(zhí)行每個(gè)package
,也就是說(shuō)必須要等到當(dāng)前package
安裝完成之后,才能繼續(xù)后面的安裝。而Yarn
是并行執(zhí)行所有任務(wù),提高了性能。
離線模式:如果之前已經(jīng)安裝過(guò)一個(gè)軟件包,用Yarn再次安裝時(shí)之間從緩存中獲取,就不用像npm那樣再?gòu)木W(wǎng)絡(luò)下載了
。
- 安裝版本統(tǒng)一:為了防止拉取到不同的版本,
Yarn
有一個(gè)鎖定文件(lock file)
記錄了被確切安裝上的模塊的版本號(hào)。每次只要新增了一個(gè)模塊,Yarn
就會(huì)創(chuàng)建(或更新)yarn.lock 這個(gè)文件。這么做就保證了,每一次拉取同一個(gè)項(xiàng)目依賴時(shí),使用的都是一樣的模塊版本。npm 其實(shí)也有辦法實(shí)現(xiàn)處處使用相同版本的 packages,但需要開發(fā)者執(zhí)行npm shrinkwrap
命令。這個(gè)命令將會(huì)生成一個(gè)鎖定文件,在執(zhí)行npm install
的時(shí)候,該鎖定文件會(huì)先被讀取,和 Yarn 讀取 yarn.lock 文件一個(gè)道理。npm
和Yarn
兩者的不同之處在于,Yarn
默認(rèn)會(huì)生成這樣的鎖定文件,而 npm 要通過(guò)shrinkwrap
命令生成npm-shrinkwrap.json
文件,只有當(dāng)這個(gè)文件存在的時(shí)候,packages
版本信息才會(huì)被記錄和更新。 - 更簡(jiǎn)潔的輸出:
npm
的輸出信息比較冗長(zhǎng)。在執(zhí)行npm install <package>
的時(shí)候,命令行里會(huì)不斷地打印出所有被安裝上的依賴。相比之下,Yarn 簡(jiǎn)潔太多:默認(rèn)情況下,結(jié)合了emoji
直觀且直接地打印出必要的信息,也提供了一些命令供開發(fā)者查詢額外的安裝信息。 - 多注冊(cè)來(lái)源處理:所有的依賴包,不管他被不同的庫(kù)間接關(guān)聯(lián)引用多少次,安裝這個(gè)包時(shí),只會(huì)從一個(gè)注冊(cè)來(lái)源去裝,要么是 npm 要么是 bower, 防止出現(xiàn)混亂不一致。
- 更好的語(yǔ)義化:
yarn
改變了一些npm
命令的名稱,比如yarn add/remove,
感覺上比npm
原本的install/uninstall
要更清晰。
那不是標(biāo)題黨? 說(shuō)了
yarn
這么多優(yōu)點(diǎn),我們?yōu)槭裁催€要npm
呢?
你不用npm publish
,你怎么上傳包到npm
? 你不用cnpm
,是下載不了一些包的
搞清楚三者下載包(依賴)的本質(zhì)結(jié)果:
- 首先向?qū)?yīng)的
node_module
文件夾下面下載包(如果你非要下到全局,那么再見) - 再然后是
json
文件中添加對(duì)應(yīng)的依賴字段,確定是線上依賴還是開發(fā)依賴 - 只要做到這兩者 你就下包成功
- 總結(jié)就是 只要結(jié)果 過(guò)程管你是啥
使用
yarn
下載過(guò)的包,再使用npm cnpm
下載 會(huì)重復(fù)下載,刪除之前的包
-
puppeteer
這個(gè)包所依賴的mini
版谷歌瀏覽器使用cnpm
下載就可以完美解決 -
prerender-spa-plugin
這個(gè)包依賴上面的木偶戲 puppeteer
這個(gè)包,也可以用cnpm
下載 - 混合使用包管理器切記,不要重復(fù)下載依賴,
npm cnpm
下載依賴,一定要添加注明是什么依賴,是否全局安裝 -
yarn
和npm i
兩者,選擇前者,原因在上面有提到,總體來(lái)說(shuō),yarn
是不二選擇,但是其他兩者也不可缺少,比如electron
這個(gè)依賴,使用cnpm
就可以完美一鍵安裝
只要膽大心細(xì),就可以把三者用得如魚得水,不然就會(huì)被按在地上摩擦,實(shí)踐過(guò)程踩坑也是正常 覺得寫得好別忘了關(guān)注我的專欄,給個(gè)贊再走~