在一个Node.js项目中,
package.json
几乎是一个必须的文件,它的主要做用就是管理项目中所使用到的外部依赖包,同时它也是npm
命令的入口文件。javascript
npm
目前支持如下几类依赖包管理:dependencies
devDependencies
peerDependencies
optionalDependencies
bundledDependencies
/ bundleDependencies
若是你想使用哪一种依赖管理,那么你能够将它放在package.json
中对应的依赖对象中,好比:java
"devDependencies": {
"fw2": "^0.3.2",
"grunt": "^1.0.1",
"webpack": "^3.6.0"
},
"dependencies": {
"gulp": "^3.9.1",
"hello-else": "^1.0.0"
},
"peerDependencies": { },
"optionalDependencies": { },
"bundledDependencies": []复制代码
下面咱们一一来看:webpack
应用依赖,或者叫作业务依赖,这是咱们最经常使用的依赖包管理对象!它用于指定应用依赖的外部包,这些依赖是应用发布后正常执行时所须要的,但不包含测试时或者本地打包时所使用的包。可以使用下面的命令来安装:git
npm install packageName --save复制代码
dependencies
是一个简单的JSON对象,包含包名
与包版本
,其中包版本
能够是版本号或者URL地址。好比:github
{
"dependencies" :{
"foo" : "1.0.0 - 2.9999.9999", // 指定版本范围
"bar" : ">=1.0.2 <2.1.2",
"baz" : ">1.0.2 <=2.3.4",
"boo" : "2.0.1", // 指定版本
"qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
"asd" : "http://asdf.com/asdf.tar.gz", // 指定包地址
"til" : "~1.2", // 最近可用版本
"elf" : "~1.2.3",
"elf" : "^1.2.3", // 兼容版本
"two" : "2.x", // 2.一、2.二、...、2.9皆可用
"thr" : "*", // 任意版本
"thr2": "", // 任意版本
"lat" : "latest", // 当前最新
"dyl" : "file:../dyl", // 本地地址
"xyz" : "git+ssh://git@github.com:npm/npm.git#v1.0.27", // git 地址
"fir" : "git+ssh://git@github.com:npm/npm#semver:^5.0",
"wdy" : "git+https://isaacs@github.com/npm/npm.git",
"xxy" : "git://github.com/npm/npm.git#v1.0.27",
}
}复制代码
开发环境依赖,仅次于dependencies的使用频率!它的对象定义和dependencies
同样,只不过它里面的包只用于开发环境,不用于生产环境,这些包一般是单元测试或者打包工具等,例如gulp, grunt, webpack, moca, coffee
等,可以使用如下命令来安装:web
npm install packageName --save-dev复制代码
举个栗子:shell
{ "name": "ethopia-waza",
"description": "a delightfully fruity coffee varietal",
"version": "1.2.3",
"devDependencies": {
"coffee-script": "~1.6.3"
},
"scripts": {
"prepare": "coffee -o lib/ -c src/waza.coffee"
},
"main": "lib/waza.js"
}复制代码
prepare
脚本会在发布前运行,所以使用者在编译项目时不用依赖它。在开发模式下,运行npm install
, 同时也会执行prepare
脚本,开发时能够很容易的测试。npm
至此,你理解了
--save
和--save-dev
的区别了吗?json
同等依赖,或者叫同伴依赖,用于指定当前包(也就是你写的包)兼容的宿主版本。如何理解呢? 试想一下,咱们编写一个gulp的插件,而gulp却有多个主版本,咱们只想兼容最新的版本,此时就能够用同等依赖(peerDependencies
)来指定:gulp
{
"name": "gulp-my-plugin",
"version": "0.0.1",
"peerDependencies": {
"gulp": "3.x"
}
}复制代码
当别人使用咱们的插件时,peerDependencies
就会告诉明确告诉使用方,你须要安装该插件哪一个宿主版本。
一般状况下,咱们会在一个项目里使用一个宿主(好比gulp
)的不少插件,若是相互之间存在宿主不兼容,在执行npm install
时,cli
会抛出错误信息来告诉咱们,好比:
npm ERR! peerinvalid The package gulp does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer gulp-cli-config@0.1.3 wants gulp@~3.1.9
npm ERR! peerinvalid Peer gulp-cli-users@0.1.4 wants gulp@~2.3.0复制代码
运行命令npm install gulp-my-plugin --save-dev
来安装咱们插件,咱们来看下依赖图谱:
├── gulp-my-plugin@0.0.1
└── gulp@3.9.1复制代码
OK, Nice!
注意,npm 1 与 npm 2 会自动安装同等依赖,npm 3 再也不自动安装,会产生警告!手动在
package.json
文件中添加依赖项能够解决。
可选依赖,若是有一些依赖包即便安装失败,项目仍然可以运行或者但愿npm
继续运行,就可使用optionalDependencies
。另外optionalDependencies
会覆盖dependencies
中的同名依赖包,因此不要在两个地方都写。
举个栗子,可选依赖包就像程序的插件同样,若是存在就执行存在的逻辑,不存在就执行另外一个逻辑。
try {
var foo = require('foo')
var fooVersion = require('foo/package.json').version
} catch (er) {
foo = null
}
if ( notGoodFooVersion(fooVersion) ) {
foo = null
}
// .. then later in your program ..
if (foo) {
foo.doFooThings()
}复制代码
打包依赖,bundledDependencies
是一个包含依赖包名的数组对象,在发布时会将这个对象中的包打包到最终的发布包里。如:
{
"name": "fe-weekly",
"description": "ELSE 周刊",
"version": "1.0.0",
"main": "index.js",
"devDependencies": {
"fw2": "^0.3.2",
"grunt": "^1.0.1",
"webpack": "^3.6.0"
},
"dependencies": {
"gulp": "^3.9.1",
"hello-else": "^1.0.0"
},
"bundledDependencies": [
"fw2",
"hello-else"
]
}复制代码
执行打包命令npm pack
, 在生成的fe-weekly-1.0.0.tgz
包中,将包含fw2
和hello-else
。 可是值得注意的是,这两个包必须先在devDependencies
或dependencies
声明过,不然打包会报错。
以上就是目前npm支持的依赖管理,若有不明白或者错误之处,请在评论区留言。
欢迎关注咱们专栏:ELSE