次要探索不同 dependencies 配置对我的项目的影响
一、devDependencies
增加 devDependencies 依赖的形式
npm install <package-name> --save-dev// 缩写npm i <package-name> -D
该配置项搁置本地开发过程中须要应用到的编译、打包、测试、格式化模块等
装置依赖的时候,不会装置依赖的 devDependencies
二、dependencies
增加 dependencies 依赖的形式
npm install <package-name>// 缩写npm i <package-name>
我的项目中理论运行须要用到的代码,没有的话会出错
1. 惟一依赖
例如:faker-project 我的项目依赖了 sdk-a
// faker-project{ "name": "faker-project", "dependencies": { "sdk-a": "1.0.0" }}
而 sdk-a 的 dependencies 中蕴含了 sdk-core
// sdk-a{ "name": "sdk-a", "version":"1.0.0", "dependencies": { "sdk-core": "0.0.1" }}
则 faker-project 执行 npm install 之后,目录构造如下
faker project|├── node_modules | ├── sdk-a| └── sdk-core|└── package.json
所有依赖会平级设置
2. 反复依赖
2.1 不兼容
假如 faker-project 我的项目又依赖了 sdk-b
// faker-project{ "name": "faker-project", "dependencies": { "sdk-a": "1.0.0",+ "sdk-b": "1.0.0" }}
而 sdk-b 恰好也依赖了 sdk-core,然而 sdk-core 版本不同
// sdk-b{ "name": "sdk-b", "version":"1.0.0", "dependencies": { "sdk-core": "0.0.2" }}
则 faker-project 执行 npm install 之后,目录构造如下
faker project | ├── node_modules | ├── sdk-a+ | ├── sdk-b+ | | └── node_modules+ | | └── sdk-core // 0.0.2+ | | | └── sdk-core // 0.0.1 | └── package.json
依赖会在本人的 node_modules 中独自装置一份,防止抵触
2.2 兼容
如果 sdk-core 的版本可能兼容
// sdk-a{ "name": "sdk-a", "version":"1.0.1", "dependencies": {- "sdk-core": "0.0.1"+ "sdk-core": "^0.0.1" }}
则两者会共用一份依赖(如果先装置一个,再装置另一个。最初目录构造也会和不兼容的状况体现统一)
faker project | ├── node_modules | ├── sdk-a | ├── sdk-b | └── sdk-core // 0.0.2 | └── package.json
3. 历史
在 npm 3 之前,node_modules 不会平级设置。依赖的依赖都会间接嵌套
三、peerDependencies
一了解为「同级依赖」
用在公布的代码库当中,示意须要宿主环境提供该配置下的模块依赖,与宿主环境非亲非故。npm(3.x 版本之后,7.x 之前)、yarn 不会主动装置该配置下的依赖模块,会告警提醒。
工夫节点:
npm 3 - 2015 年 5 月
npm 5 - 2017 年 5 月
yarn 1 - 2017 年 9 月
yarn 2 - 2020 年 1 月
npm 7 - 2021 年 3 月
PS:为了便于了解,下文中:
- 新版:npm 7 及其以上的版本,会主动装置 peerDependencies
- 旧版:npm 3.x ~ 6.x 和 yarn,不会主动装置 peerDependencies
1. 惟一依赖
// sdk-a{ "name": "sdk-a", "version":"1.0.2", "peerDependencies": { "sdk-core": "^0.0.1" }}
1.1 旧版
不会主动装置该配置下的依赖模块,会告警提醒。须要用户自行装置
warning " > sdk-a@1.0.3" has unmet peer dependency "sdk-core@^0.0.1".
faker project | ├── node_modules | └── sdk-a | └── package.json
1.2 新版
会主动装置,并始终只存在一个。间接位于 node_modules 之下
1.3 区别
不论主动还是手动,最初的后果都是。peerDependencies 中的依赖都会被间接装置在 node_modules 之下
最大区别是,旧版通过本人的手动装置。会体现在我的项目的 dependencies 中,而新版不会
// faker-project{ "name": "faker-project", "dependencies": { "sdk-a": "1.0.3", "sdk-core": "^0.0.1" // 最大区别 }}
2. 反复依赖
2.1 不兼容
2.1.1 旧版
只会在装置时提醒不同版本的 peer dependency 信息
warning " > sdk-a@1.0.4" has unmet peer dependency "sdk-core@0.0.1".warning " > sdk-b@1.0.2" has unmet peer dependency "sdk-core@0.0.2".
2.1.2 新版
对于版本不兼容的依赖,装置时候会间接报错
能够通过 --legacy-peer-deps
让 peerDependencies 不主动装置
2.1.3 如何解决不兼容的 peerDependencies
目前没有让不兼容的 peerDependencies 各自失效的办法。所以真碰到了这种状况,个别解决办法是批改其中一个带有 peerDependencies 依赖的包版本。让其依赖另一版本的 peerDependencies 和其余版本的兼容
2.2 兼容
// sdk-b{ "name": "sdk-b", "version":"1.0.3", "peerDependencies": { "sdk-core": "^0.0.1" }}
// faker-project{ "name": "faker-project", "dependencies": { "sdk-a": "1.0.4", "sdk-b": "1.0.3" }}
多个我的项目存在兼容 peerDependencies 的状况
2.2.1 旧版
不主动装置,仅提醒
2.2.2 新版
主动装置,和惟一依赖行为一样
2.3 非凡状况
如果 sdk-core,同时存在 peerDependencies 和 dependencies 时
2.3.1 旧版
不会被装置,等同于只有 peerDependencies
2.3.2 新版
会主动装置,等同于只有 dependencies
两种状况均不判断版本兼容
2.4 嵌套依赖
还有更极其的状况,比方 dependencies 里如果有 peerDependencies。详情见上面的文章
四、总结
- 运行时用不到的依赖,放在 devDependencies 中
- 插件类的依赖(比方 sdk-core 是一个依赖,在此基础上开发的依赖 sdk-a、sdk-b)才应用 peerDependencies
- 要求运行时时单例的依赖(vue、react 等同时只能存在一个实例)应用 peerDependencies
- 其余状况都应用 dependencies
五、其余 dependencies
其余比拟少见的 dependencies
1. optionalDependencies
optionalDependencies 可选依赖,如果有一些依赖包即便装置失败,我的项目依然可能运行或者心愿 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()}
2. bundledDependencies / bundleDependencies
打包依赖,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 依赖包治理 - https://zhuanlan.zhihu.com/p/29855253