如何让 YARN 支持 CNPM 的完整加速

国内的前端开发人或多或少都了解过 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

关于 CNPM 的那些事

reactvue 引领的前端工程化开发在国内大规模流行以来,前端项目的依赖安装成为了平常工做的重要组成部分。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 和 YARN 使用镜像加速

这个部分不是什么新鲜内容了,全部的包管理器均可以设置仓库地址。具体的细节建议阅读 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/

phantomjselectron 等一样可使用此方法加速,由于他们都容许使用环境变量设置镜像 url。咱们能够在 https://npm.taobao.org/mirrors 上查看全部可用的镜像。

网络上绝大多数的文章也就到此为止了,然而这还不是所有。

使用 bin-wrapper-china

imagemin 是一系列基于 C++ 实现的图片压缩模块,其中包含了 pngquantmozjpeg 等知名库,和 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 作了三件事:

  • 使用淘宝 npm 镜像仓库加速常规模块的安装。
  • 可配置的二进制文件,提早注入环境变量进行加速。
  • 不可配置的二进制文件,强行替换 url 加速下载。

这也是咱们要作的三件事(一般配置在项目中):

  • 经过 .npmrc 文件配置 npm 仓库地址为国内镜像地址。
  • 经过 .npmrc 文件配置环境变量,或经过 bin-wrapper-chinachina-bin-env 命令注入环境变量。
  • 配置 yarn resolutions, 用 bin-wrapper-china 冒充 bin-wrapper 实现 url 替换。

固然了,若是你下定决心使用 cnpm ,或者所处的工做网络可以畅通无阻,或者项目不须要安装含二进制文件的模块(例如笔者在项目中用 sass 替换 node-sass),就不须要考虑这问题了。本文虽然推荐使用 yarn ,但其核心流程适用于大多数 Node.js 生态内的包管理器,各位读者有兴趣能够作更多探索。

相关项目:

相关文章
相关标签/搜索