当我们打开package.json
文件时,会发现dependencies
和devDependencies
两个对象,那这两个对象有什么区别吗?
dependencies
当使用 npm install --save
时候,会将依赖的包版本信息加到dependencies
对象中。原则上来说这个字段的工具包只允许放生产环境中项目所使用的依赖,例如:Vue,React,axios 等相关代码缺失会导致项目运行错误的工具。
devDependencies
当使用 npm install --save-dev
时候,会将依赖的包版本信息加到devDependencies
对象中。例如:webpack,vue-cli相关依赖 等项目上线后不需依赖相关代码运行的工具。
使用npm install xxx
不加--save或 --save-dev
时npm 5 之后,--save
是作为默认参数添加.。
依赖混乱有什么后果?
什么是依赖混乱?依赖混乱就是将本应该在生产环境的包放进开发依赖,将开发环境的包放进生产依赖。
如使用了npm install --production
或作为npm包时,别人使用npm install xxx
只安装dependencies
对象下的依赖,忽略devDependencies
一般项目开发时,安装依赖使用npm install
,此时会安装 dependencies
和devDependencies
两个对象下的依赖。
- 生产环境的包放进开发依赖
具体就例如:将 Vue 放进 devDependencies,这样做的后果是什么?分两种情况:
- 下载项目源码,然后运行 npm install。这种情况无论 Vue 在哪个字段里都会被正确下载到 node_modules 里。
- 作为 npm 包发布,然后 npm install xxx 的形式下载。这种情况只会下载 dependencies 的依赖,其余依赖将会无视处理,这样别人下载你的 npm 包运行时,就会找不到 xxx 而出错。
- 开发环境的包放进生产依赖
具体就例如:将 fs-extra jest 放进 dependencies,这样做的后果是什么?分两种情况:
- 下载项目源码,然后运行 npm install。这种情况无论 fs-extra jest 在哪个字段里都会被正确下载到 node_modules 里。
- 作为 npm 包发布,然后 npm install xxx 的形式下载。这种情况只会下载 dependencies 的依赖,其余依赖将会无视处理,这样别人下载你的 npm 包运行时,就会包含有 fs-extra jest 代码,从而增加本地项目的体积。
其他 dependencies
其实 npm 还有更多种类的 dependencies 字段,例如:peerDependencies,bundledDependencies,optionalDependencies 等,那这些字段有什么用?平常在使用 npm 包时很少接触。
这些 dependencies 字段是给包开发者用的。
peerDependencies
这个字段的主要作用是可以让包依赖的控制权转交给用户。什么意思呢?
例如我们提供一个包,其中的 package.json 如下:
{
"name": "my-greate-express-middleware",
"version": "1.0.0",
"peerDependencies": {
"express": "^3.0.0"
}
}
这个 express 中间件依赖 ^3.0.0 版本的 express
- 如果用户此刻 node_modules 有 express 5.0.0,那么 npm 就会询问是否继续用这个安装包
- 如果用户此刻 node_modules 没有 express,那么 npm 就会告诉用户请自行安装 express
该字段的应用场景主要为工具库的制作,目的是为了让库的依赖尽可能少。
bundledDependencies
这个字段的主要作用是包作者希望以压缩包(tar.gz)的方式发布项目,即没有 publish 到 npm register 上的包。
该字段是一个数组:
{
"name": "awesome-web-framework",
"version": "1.0.0",
"bundledDependencies": [
"renderized", "super-streams"
]
}
optionalDependencies
这个字段的主要作用是希望下载一个不稳定的包,下载失败时,自己程序做处理。
除了一些特殊情况,这个字段极少会用。
其它
package-lock.json
package-lock.json 内部记录的是每一个依赖的实际安装信息,例如名字,安装的版本号,安装的地址 (npm registry 上的 tar 包地址)等等。额外的,它会把依赖的依赖也记录起来,因此整个文件是一个树形结构,保存依赖嵌套关系(类似以前版本的 node_modules 目录)。一个简单的例子如下
{
"name": "shkq",
"version": "3.2.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
"dev": true,
"requires": {
"@babel/highlight": "^7.10.4"
}
},
}
}
当项目首次执行npm install
如果发现根目录下只有 package.json 存在,就按照它的记录逐层递归安装依赖,并生成一个 package-lock.json 文件。如果发现根目录下两者皆有,则 npm 会比较两者。如果两者所示含义不同,则以 package.json 为准,并更新 package-lock.json;否则就直接按 package-lock 所示的版本号安装。
优点:
- 团队每个成员更新后依赖版本相同。
- 在安装过程中,npm 内部会检查 node_modules 目录中已有的依赖包,并和 package-lock.json 进行比较。如果重复,则跳过安装,能大大优化安装时间。
npm源设置
//查看当前npm源
npm config get registry
// 切换npm源使用淘宝镜像
npm config set registry=https://registry.npmmirror.com/
// 切回npm源
npm config set registry=http://registry.npmjs.org/
参考资料
https://www.yuque.com/alipay2088002421051737/gzaw4a/tvzzs7?
https://juejin.cn/post/6844903769403031565#heading-11