如果你对NodeJs系列感兴趣,欢迎关注微信公众号:前端神盾局或 github NodeJs系列文章
日常开发中,我们常见到各种dependency,今日得空整理了一下
dependency 与 devDependency
几乎在每个应用中我们都会见到dependency
和devDependency
的身影。dependency
定义的是代码所需要的依赖包,而devDependency
给定的是编译/测试等开发时所需依赖包。举个例子:
{
"name": "project",
"script": {
// 代码打包
"build": "./node_modules/.bin/webpack ..."
},
"dependency": {
"react": "^16.6.3",
...
},
"devDependency": {
"webpack": "4.19.1",
"url-loader": "1.1.1",
...
}
}
理想情况下,当运行npm run build
后应该只包含react
相关代码而不包括devDependency
中的无用代码。当然,在这里dependency
和devDependency
只是一个规范,最终生成什么代码取决于你引入了什么,比如improt 'url-loader'
会把url-loader
囊括进你的生产代码,不论它是否定义在dependency
中。
现在考虑另外一个场景,我们开发了一个npm(package-a
)包,我们希望所有依赖package-a
的应用都能有效的运行。这时dependency
和devDependency
并不仅仅是一个我们可以随意遵守的规范而已,因为项目依赖的devDependency 不会被安装。比如:
├── project
├── package-a (dependency)
│ └── package-a-1 (devDependency)
└── package-b (devDependency)
在project下执行npm install
之后,package-a和package-b 都会被安装,但package-a-1不会被安装,所以你在project的 node_modules文件夹下找不到package-c。
综上所述,在开发一个应用时,我们应该把生产需要的依赖放在dependency
中,把单元测试/编译/打包等这些生产无关依赖放在devDependency
中
peerDependencies
我们以babel-loader
为例子,运行npm install babel-loader -D
时,控制台会有两条警告:
npm WARN [email protected] requires a peer of @babel/core@^7.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of webpack@>=2 but none is installed. You must install peer dependencies yourself.
提示babel-loader
需要依赖@babel/core@^7.0.0
和webpack@>=2
。这是因为peerDependencies
指定了当前包需要安装的依赖:
"peerDependencies": {
"@babel/core": "^7.0.0",
"webpack": ">=2"
}
那应该在什么情况下使用呢?
一般的,如果我们需要开发针对于某个库的插件而又不需要在代码中引用这个库的时候。就比如babel-loader
是webpack的一个插件,但代码中又无需引用webpack,为了保证插件能够运行在webpack环境中,故而使用了peerDependencies
。
bundledDependencies
又可称为:bundleDependencies
再以一个例子阐述:
{
"name": "project",
"dependencies": {
"react": "^16.6.3",
"react-dom": "^16.6.3"
},
"bundleDependencies": [
"react",
"react-dom"
],
"version": "1.0.0"
}
当我们需要使用npm pack
打包这个应用时,其最终生成的文件结构如下:
project-1.0.0.tgz
├── node_modules
| └── react
| └── react-dom
└── package.json
如果不使用bundleDependencies
,文件结构如下:
project-1.0.0.tgz
├── project-1.0.0.tgz
| └── node_modules
| └── react
| └── react-dom
└── package.json
so,bundleDependencies
的作用是将指定依赖归置于当前项目下,这样你就可以快速的运行你pack后的项目。
optionalDependencies
如果你的应用中依赖了optional-a
,而这个依赖又是可有可无的,也就是说如果optional-a
找不到或者安装失败,你希望程序依旧运行。这时候optionalDependencies
就能很好的满足你的要求。
注意:optionalDependencies会覆盖dependencies中的同名包
try {
let optionalA = require('optional-a');
} catch (er) {
optionalA = null
}
参考
- What's the difference between dependencies, devDependencies and peerDependencies in npm package.json file?
- Peer Dependencies
- Package.json