国内的前端开发人或多或少都了解过 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 生态内的包管理器,各位读者有兴趣能够作更多探索。
相关项目: