前端得包管理你有過幾個?前端
一位用很差包管理器的前端,是一個入門級前端,一個用很差webpack
的前端,是一個初級前端node
三個包管理器是能夠一塊兒用的,只要你夠膽大心細,就沒任何問題!webpack
在javeScript
編寫中, 咱們儘可能不要定義全局變量,封裝函數儘可能不要有反作用, 由於所有變量的查詢時間會比局部變量的查詢慢, 更是考慮在 Node 的環境中沒法被垃圾回收的問題程序員
npm
是 Node.js
可以如此成功的主要緣由之一。npm
團隊作了不少的工做,以確保 npm 保持向後兼容,並在不一樣的環境中保持一致。web
npm 是圍繞着 語義版本控制(semver)的思想而設計。算法
給定一個版本號:主版本號. 次版本號. 補丁版本號, 如下這三種狀況須要增長相應的版本號:npm
主版本號:當 API 發生改變,並與以前的版本不兼容的時候json
次版本號:當增長了功能,可是向後兼容的時候segmentfault
補丁版本號:當作了向後兼容的缺陷修復的時候設計模式
npm 2
會安裝每個包所依賴的全部依賴項。若是咱們有這麼一個項目,它依賴項目 A,項目 A 依賴項目 B,項目 B 依賴項目 C,那麼依賴樹將以下所示:
這個結構可能會很長。這對於基於 Unix 的操做系統來講只不過是一個小煩惱,但對於 Windows 來講倒是個破壞性的東西,由於有不少程序沒法處理超過 260 個字符的文件路徑名。
npm 3
採用了扁平依賴關係樹來解決這個問題,因此咱們的 3 個項目結構如今看起來以下所示:
存了已經下載的每一個版本的壓縮包。本地緩存的內容能夠經過 npm cache ls 命令進行查看。本地緩存的設計有助於減小安裝時間。
這樣,一個原來很長的文件路徑名就從./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
。
這種方法的缺點是,npm
必須首先遍歷全部的項目依賴關係,而後再決定如何生成扁平的 node_modules 目錄結構。npm 必須爲全部使用到的模塊構建一個完整的依賴關係樹,這是一個耗時的操做,是 npm 安裝速度慢的一個很重要的緣由。
想固然的覺得每次運行npm install
命令時,NPM
都得從互聯網上下載全部內容。
可是,npm
是有本地緩存的,它保存了已經下載的每一個版本的壓縮包。本地緩存的內容能夠經過npm cache ls
命令進行查看。本地緩存的設計有助於減小安裝時間。
cnpm
跟npm
用法徹底一致,只是在執行命令時將npm
改成cnpm
。
npm
安裝插件是從國外服務器下載,受網絡影響大,可能出現異常,若是 npm 的服務器在中國就行了,因而淘寶團隊幹了這事。來自官網:「這是一個完整 npmjs.org
鏡像,你能夠用此代替官方版本 (只讀),同步頻率目前爲 10 分鐘 一次以保證儘可能與官方服務同步。」
官方地址:http://npm.taobao.org
安裝: npm install -g cnpm --registry=https://registry.npm.taobao.org
Yarn
一開始的主要目標是解決上一節中描述的因爲語義版本控制而致使的 npm 安裝的不肯定性問題。雖然可使用npm shrinkwrap
來實現可預測的依賴關係樹,但它並非默認選項,而是取決於全部的開發人員知道而且啓用這個選項。
Yarn
採起了不一樣的作法。每一個 yarn 安裝都會生成一個相似於 npm-shrinkwrap.json 的 yarn.lock 文件,並且它是默認建立的。除了常規信息以外,yarn.lock
文件還包含要安裝的內容的校驗和,以確保使用的庫的版本相同。
yarn 是通過從新設計的嶄新的 npm 客戶端,它能讓開發人員並行處理全部必須的操做,並添加了一些其餘改進。
運行速度獲得了顯著的提高,整個安裝時間也變得更少
像 npm 同樣,yarn 使用本地緩存。`與npm不一樣的是,yarn無需互聯網鏈接就能安裝本地緩存的依賴項,它提供了離線模式`。
容許合併項目中使用到的全部的包的許可證
一般狀況下不建議經過 npm 進行安裝。npm 安裝是非肯定性的,程序包沒有簽名,而且 npm 除了作了基本的 SHA1 哈希以外不執行任何完整性檢查,這給安裝系統程序帶來了安全風險。(做者曾經在一個上百個依賴包的項目中使用npm
丟包過,代價很是大,淚水不自覺掉下來)
首先看一次很是失敗的包下載 居然是從全局讀取的資源 (不配置webpack
別名是由於就這一個路徑這麼長)
首先咱們從原理入手 ,咱們使用 npm init
, yarn init
,cnpm init
的時候 發生了什麼 ?
生成package.json
文件
json
文件內部聲明初始的版本信息、做者信息等,若是你是須要上傳到 npm 上做爲命令行工具,應該配置bin
等聲明入口字段
那麼當咱們使用npm i
, yarn add
,cnpm i
操做時候會發生什麼 ?
首先會根據你的命令行後綴是否加了 -g
或者global
判斷,下載的包是放在全局的環境,仍是當前package.json
文件對應的node_module
文件夾目錄下 (這點尤爲重要,有人出 BUG,就是由於在用npm
, cnpm
時候沒有註明添加的是全局依賴仍是本地依賴,致使json
文件上沒有對應的包名,項目永遠起不來)
而後根據你的指令--save
或者-D
、--save -dev
判斷是開發依賴仍是線上依賴,其實這點在yarn
上沒有問題,由於yarn
有本身的一套檢查包完整性的機制,不會丟包,還會自動判斷添加依賴,出bug
通常是cnpm
和npm
,沒有明確-g
或者--save
,npm
只有檢查程序員簽名的機制,沒有檢查包完整性的機制,也不會自動添加依賴到json
文件,那麼就會出現丟包的假象,因此建議主要使用`yarn`
同一個項目,安裝的時候沒法保持一致性。因爲 package.json 文件中版本號的特色,下面三個版本號在安裝的時候表明不一樣的含義。
"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 中最新的版本。這就麻煩了,經常會出現同一個項目,有的同事是 OK 的,有的同事會因爲安裝的版本不一致出現bug
。
安裝的時候,包會在同一時間下載和安裝,中途某個時候,一個包拋出了一個錯誤,可是 npm 會繼續下載和安裝包。由於 npm 會把全部的日誌輸出到終端,有關錯誤包的錯誤信息就會在一大堆npm
打印的警告中丟失掉,而且你甚至永遠不會注意到實際發生的錯誤。
速度快 。速度快主要來自如下兩個方面:
並行安裝:不管 npm
仍是 Yarn
在執行包的安裝時,都會執行一系列任務。npm
是按照隊列執行每一個 package
,也就是說必需要等到當前 package
安裝完成以後,才能繼續後面的安裝。而 Yarn
是並行執行全部任務,提升了性能。
離線模式:若是以前已經安裝過一個軟件包,用Yarn再次安裝時之間從緩存中獲取,就不用像npm那樣再從網絡下載了
。
安裝版本統一:爲了防止拉取到不一樣的版本,Yarn
有一個鎖定文件 (lock file)
記錄了被確切安裝上的模塊的版本號。每次只要新增了一個模塊,Yarn
就會建立(或更新)yarn.lock 這個文件。這麼作就保證了,每一次拉取同一個項目依賴時,使用的都是同樣的模塊版本。npm 其實也有辦法實現到處使用相同版本的 packages,但須要開發者執行 npm shrinkwrap
命令。這個命令將會生成一個鎖定文件,在執行 npm install
的時候,該鎖定文件會先被讀取,和 Yarn 讀取 yarn.lock 文件一個道理。npm
和 Yarn
二者的不一樣之處在於,Yarn
默認會生成這樣的鎖定文件,而 npm 要經過 shrinkwrap
命令生成 npm-shrinkwrap.json
文件,只有當這個文件存在的時候,packages
版本信息纔會被記錄和更新。
更簡潔的輸出:npm
的輸出信息比較冗長。在執行 npm install
的時候,命令行裏會不斷地打印出全部被安裝上的依賴。相比之下,Yarn 簡潔太多:默認狀況下,結合了 emoji
直觀且直接地打印出必要的信息,也提供了一些命令供開發者查詢額外的安裝信息。
多註冊來源處理:全部的依賴包,無論他被不一樣的庫間接關聯引用多少次,安裝這個包時,只會從一個註冊來源去裝,要麼是 npm 要麼是 bower, 防止出現混亂不一致。
更好的語義化: yarn
改變了一些npm
命令的名稱,好比 yarn add/remove,
感受上比 npm
本來的 install/uninstall
要更清晰。
那不是標題黨? 說了yarn
這麼多優勢,咱們爲何還要npm
呢?
你不用npm publish
,你怎麼上傳包到npm
? 你不用cnpm
,是下載不了一些包的
搞清楚三者下載包(依賴)的本質結果:
首先向對應的node_module
文件夾下面下載包(若是你非要下到全局,那麼再見)
再而後是json
文件中添加對應的依賴字段, 肯定是線上依賴仍是開發依賴
只要作到這二者 你就下包成功
總結就是 只要結果 過程管你是啥
使用yarn
下載過的包,再使用npm cnpm
下載 會重複下載,刪除以前的包
puppeteer
這個包所依賴的mini
版谷歌瀏覽器使用cnpm
下載就能夠完美解決
prerender-spa-plugin
這個包依賴上面的木偶戲 puppeteer
這個包,也能夠用cnpm
下載
混合使用包管理器切記,不要重複下載依賴,npm cnpm
下載依賴,必定要添加註明是什麼依賴,是否全局安裝
yarn
和npm i
二者,選擇前者,緣由在上面有提到,整體來講,yarn
是不二選擇,可是其餘二者也不可缺乏,好比electron
這個依賴,使用cnpm
就能夠完美一鍵安裝
只要膽大心細,就能夠把三者用得如魚得水,否則就會被按在地上摩擦,實踐過程踩坑也是正常 以爲寫得好別忘了關注個人專欄,給個贊再走~
原文做者:Peter譚金傑
地址:https://segmentfault.com/a/1190000019299845
▼
原創系列推薦
▼
7. 59篇原創系列彙總
點這,與你們一塊兒分享本文吧