國內的前端開發人或多或少都瞭解過 cnpm ,但項目開發因人而異,不少時候不會或不能使用 cnpm ,不可勝數的項目在使用 yarn 或者其餘包管理器安裝依賴。本文將介紹這樣的狀況下如何加速二進制文件下載。
在前一段時間發佈的 Github Octoverse 2019 報告中,JavaScript 繼續蟬聯最受歡迎編程語言。JavaScript 生態的保持繁榮,與 Node.js 的流行密不可分。而說到 JavaScript 生態,不得不提到 npm,npm 不只是前端開發首選的包管理器,也是除了 Github 以外最重要的代碼共享途徑。Snyk 2019 開源安整年報中指出,npm 生態的包數量遠超其餘包管理器。前端
現階段,主流的前端開源項目在發佈時都會使用 npm 的在線託管服務 https://www.npmjs.com/。但開發者可以使用的包管理器卻不止 npm 一個,來自開源社區的 yarn 和 pnpm 正在被愈來愈多人使用,它們最顯著的優勢就是加快依賴的安裝速度。對於中國開發者,由阿里巴巴開源的 cnpm 也是一個重要的選擇。vue
由 react
和 vue
引領的前端工程化開發在國內大規模流行以來,前端項目的依賴安裝成爲了平常工做的重要組成部分。cnpm 的出現解決了因爲網絡環境形成的安裝速度慢問題,受到了大量國內開發者的歡迎。node
cnpm 的誕生早於 yarn 和 pnpm ,它使用 npminstall
模塊執行安裝。由淘寶開發團隊維護的 npm 倉庫鏡像,會定時同步 npm 官方的全部模塊 。cnpm 無需任何配置就會默認從淘寶鏡像下載全部的包,從而達到國內加速的目的。具體的使用方式能夠查看官方文檔 https://npm.taobao.org/。react
雖然目前 cnpm 的速度一如既往得快,但對比其餘競品它卻再也不像剛誕生時那樣有優點了,加上實際開發時莫名其妙的報錯也難以解決,還有各類各樣的其餘因素。愈來愈多的團隊又切換回了 npm ,或者轉而使用具有更多功能的 yarn 或 pnpm 。git
yarn 是 Facebook 團隊開源的包管理器,它能建立更扁平的依賴樹,只會安裝變動的模塊,使用並行下載,用本機緩存加速安裝。而 pnpm 做爲黑馬,其口碑甚至優於 yarn ,但因爲筆者沒有使用經驗,因此不會在本文中介紹它的使用方式。
我想確定有讀者想吐槽,爲何不用 cnpm ,非要折騰?但這並無具體的答案,每一個團隊,每一個人都有各自的狀況,無須妄加批評。終歸都是發現問題解決問題。接下來會介紹怎麼用最低限度的配置讓 yarn 也得到 cnpm 的國內加速能力。github
這個部分不是什麼新鮮內容了,全部的包管理器均可以設置倉庫地址。具體的細節建議閱讀 npm 的官方文檔。npm
除了「衆所周知的命令行配置法」之外,也能夠在項目中建立 .npmrc
文件。若是將該文件一併提交到 Git 就能與全部環境共享該配置,利於多人協做,也能夠被 CI 和其餘第三方工具使用。所以也是筆者推薦使用的方法。編程
# .npmrc registry = https://registry.npm.taobao.org
yarn 一樣也會讀取這個文件,除非你在 .yarnrc 中覆蓋了這一配置。json
# .yarnrc registry "https://registry.npm.taobao.org"
單純的使用國內 npm 鏡像並不能解決全部問題。最知名的例子:前端工程化
爲了簡化 CSS 的編寫,許多項目都會使用預處理器。在國內,預處理器less
比生態更加完整的 sass
處理器流行的緣由之一,即是由於 sass
的編譯工具 node-sass
的安裝曾經十分困難,許多公司、團隊和我的開發者所以決定了選型使用 less
。
node-sass
之因此難以安裝,是它在 npm 安裝流程以後,還會觸發一個而外的編譯流程。其中使用了 C++ 編譯的二進制文件,該文件根據版本託管在 https://github.com/sass/node-... 。Github 使用了亞馬遜的 AWS 服務做爲 CDN,因爲某些衆所周知的緣由,在中國大陸有時會沒法訪問。因而乎在該文件下載失敗後,就會觸發本機編譯以生成替代的二進制文件,這一過程每每以失敗了結(尤爲是在 Windows 7 系統)。不少網絡教程這時候會建議安裝 C++ 相關的編譯環境,也有人會說 「用 Linux 保平安」。
但實際上只要能解決二進制文件的下載問題就能大大提升成功率。淘寶鏡像上也提供了相應的二進制包,經過設置環境變量使用國內加速。cnpm 內置了這一過程,因此能夠自動解決這一狀況。
不使用 cnpm 的話,則經過命令行設置環境變量:
# 全局配置,單臺設備上永久生效 yarn config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/ # 針對單次安裝 SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/ && yarn add node-sass # or yarn add node-sass --sass_binary_site https://npm.taobao.org/mirrors/node-sass/
或者一樣將其配置在 .npmrc
文件中達到分享配置的效果:
# .npmrc sass_binary_site = https://npm.taobao.org/mirrors/node-sass/ electron_mirror = https://npm.taobao.org/mirrors/electron/
phantomjs
和 electron
等一樣可使用此方法加速,由於他們都容許使用環境變量設置鏡像 url。咱們能夠在 https://npm.taobao.org/mirrors 上查看全部可用的鏡像。
網絡上絕大多數的文章也就到此爲止了,然而這還不是所有。
imagemin
是一系列基於 C++ 實現的圖片壓縮模塊,其中包含了 pngquant
和 mozjpeg
等知名庫,和 node-sass
同樣須要下載二進制文件。然而它卻沒有不支持使用環境變量配置鏡像倉庫 url,自主編譯的成功率也要低得多。這時候不管是 npm 仍是 yarn 都只能聽天由命祈禱網絡暢通。
沒錯,cnpm 經過內置的處理也解決了這種狀況,那是否是要吃回頭草用 cnpm 呢?
固然不用,查看源碼能夠發現,至關一部分使用了二進制文件的模塊,都會經過 bin-wrapper
執行下載和編譯。因而乎只要能在下載以前將 bin-wrapper
內使用的下載連接替換成鏡像倉庫的 url,問題便迎刃而解。
筆者爲此建立了一個工具 bin-wrapper-china,該工具 fork 了原版的 bin-wrapper
,並讀取了 cnpm 所使用的 binary-mirror-config 獲取全部可用的鏡像淘寶鏡像 url,替換下載文件的連接。這樣就能夠愉快地使用加速功能。那麼問題來了,怎樣用 bin-wrapper-china
代替 bin-wrapper
執行下載呢?
答案是使用 yarn 的殺手級功能 resolutions
(npm 不支持),它容許咱們用 yarn 執行安裝時,用指定的模塊替換另外一個模塊,具體的配置方法以下:
// package.json with yarn { "resolutions": { "bin-wrapper": "npm:bin-wrapper-china" } }
bin-wrapper-china
的「冒名頂替」發生在安裝過程之中,bin-wrapper
的運行發生在安裝以後 ,因此可以無縫的運行。這樣一來 imagemin
系列的安裝成功率便能大爲提升,關於 resolutions
的相關說明,詳見:
對於支持環境變量的模塊,例如 node-sass
等,bin-wrapper-china
也能提供了 china-bin-env
命令代替手動環境變量的支持。但因爲咱們不建議注入 yarn 或 npm 自己,而環境變量的注入必須在安裝以前執行,故在有須要的狀況下在項目內手動設置 preinstall
命令:
// package.json { "scripts": { // Use npm "preinstall": "npm install bin-wrapper-china -D && china-bin-env", // Use yarn "preinstall": "yarn add bin-wrapper-china -D && china-bin-env" } }
基於 preinstall
的操做須要 bin-wrapper-china
的提早安裝,筆者也但願後續有更好的解決方案。
因爲 cnpm 的一些功能缺失,咱們可能會決定棄用它,可是它的加速能力又是咱們所須要的。
總結起來,cnpm 作了三件事:
這也是咱們要作的三件事(一般配置在項目中):
bin-wrapper-china
的 china-bin-env
命令注入環境變量。bin-wrapper-china
冒充 bin-wrapper
實現 url 替換。固然了,若是你下定決心使用 cnpm ,或者所處的工做網絡可以暢通無阻,或者項目不須要安裝含二進制文件的模塊(例如筆者在項目中用 sass 替換 node-sass),就不須要考慮這問題了。本文雖然推薦使用 yarn ,但其核心流程適用於大多數 Node.js 生態內的包管理器,各位讀者有興趣能夠作更多探索。
相關項目: