自行开发 npm 库时,往往需要安装其他的依赖。应该把它放在哪里, dependencies / peerDependencies 还是 devDependencies?
一个库如果指定了 dependencies ,安装该库时,对应的依赖就会安装在该库的 node_modules 下。
如 a 依赖 b ,安装的层级如下:
src/index.js
node_modules/a
node_modules/a/node_modules/b
如果项目本身也依赖了 b ,这种情况,看他们的版本号分别是什么。
如果项目的 dependencies 能满足组件的 dependencies ,优先使用项目内的,如完全一致,或者组件库是 ^8.0.0 项目是 8.0.1 在其要求范围内的, package-lock 依赖关系中可以看到,组件库不会单独安装这个依赖。效果同上。
否则,就会单独安装需要版本的依赖(即项目的 b 跟组件依赖的 b 版本不一致时),层级如下:
src/index.js
node_modules/a
node_modules/a/node_modules/b
node_modules/b
在项目内,直接调用 b ,会执行 node_modules/b 的版本。如果是 a 中引用的 b ,会执行 node_modules/a/node_modules/b 的版本。
这样做也有优点,可以让我们的 npm 库始终使用准确的依赖包。
为了避免组件库依赖库的不稳定性,组件库的 dependencies 应该写死具体的版本号。这样不管外部组件引用是什么版本,最终组件调用的就是我们开发时的版本。
开发一个 npm 库时,有时需要另一个依赖,但不适合安装在库下时,就可以指定前置依赖。
比如 react-router 依赖 react ,而 react 的版本是随着项目来定的,不方便引进库中,不然版本不一致了。
可以在项目中指定 peerDependencies:
"b": ">= 3.0.0"
指定了之后,在组件开发时放到 devDependencies 中,依赖就不会加入到这个库了。
但要求使用方安装了符合条件 (大于等于 3.0.0) 的 b 依赖。
这样,项目的依赖关系层级就比较简洁清晰:
src/index.js
node_modules/a
node_modules/b
如果使用了 webpack 或者 rollup 等构建工具 ,无论依赖指定在哪里,都会被打包进构建的打包产物中。并且,构建后不再与 node_modules 下安装的内容有关。
所以,如果是需要构建进入打包产物中,安装在 devDependencies 比较合适,仅在开发时使用。
如果需要作为 peerDependencies 去依赖,应该放在构建工具对应的 external 中,不对其进行打包。