bundledDependencies

Build

由于 semver 的设计,在使用 npm 对项目依赖进行管理的时候,很容易遇到安装版本不完全一致的情况。而一旦开发版本和线上编译版本使用的版本不能保证一致,就非常容易出现意料之外且难于测试的问题,造成线上代码的不稳定。Yarn 和后来的 npm 都分别通过 yarn.lock 以及 package-lock.json 文件来锁定版本,保证开发和线上编译依赖的一致性。

但是,这种保证只是针对最终使用者的。具体来说,使用某个依赖的开发者可以通过 yarn.lock 文件来保证所有同组的开发者一定都使用了相同版本号的依赖;但是这个依赖的开发者没法通过 yarn.lock 来保证当用户使用自己开发的库的时候,可以使用和自己一样的依赖。

举个简单的例子:在 react-resize-detector 这个库(v4.2.0)里,附带了一份 yarn.lock 文件,指明了使用的 lodash 版本(lodash ^4.17.11)为 4.17.11。然而通过下面的命令在新的一个项目中安装,可以看到实际安装的版本会是 4.17.15:

yarn add lodash@4.17.15 react-resize-decector@4.2.0

也就是说,yarn 在安装的时候并没有参考项目内自身携带的 yarn.lock 的配置。

为此,npm 在 package.json 中设计了 bundledDependencies 这个字段来满足上述的需求。根据 npm 给出的说明,当 package.json 中指定了 bundledDependencies 字段后,这些指定的包也将在发布的时候一并被打包。这样,当其他人使用这个包的时候,就可以直接使用打包在项目内的依赖,而不需要在通过包管理器去下载了。

具体定义的方法如下:

{
  "name": "awesome-web-framework",
  "version": "1.0.0",
  "bundledDependencies": [
    "renderized", "super-streams"
  ]
}

如此定义后,renderizedsuper-streams 这两个依赖就会被一并打包发布。

bundle-dependencies 这个包为例,项目的 package.json 中写明了需要将 yargs 打包。因此,在下载到的包中可以看到,yargs 是作为 node_modules 的一个部分,连带其所有 dependencies(包括 dependencies 的 dependencies)全部都打包在内的(因而体积也比较大,tgz 有 237 kB)。

通过下面的命令也可以进一步验证,有了 bundledDependencies 之后,就可以锁定安装的依赖的 dependencies 版本号了:

yarn add yargs@4.8.1 bundle-dependencies@1.0.2

上述命令安装完毕后,bundle-dependencies 需要的 yargs v4.1.0 版本依然存放在其 node_modules 内,最外层有一个 yargs 4.8.1 版本,供其他模块使用。

需要注意的一点是,如果有了 bundledDependencies,那么即使其他地方使用到了相同版本的库,yarn 也不会将内部 node_modules 中的内容提升出来。举个例子:

yarn add yargs@4.1.0 bundle-dependencies@1.0.2

上述命令最终会安装两个 4.1.0 版本的 yargs,一个在最外层的 node_modules 内,一个在 bundle-dependencies 的 node_modules 内,两者互不干扰。