上面写的。在正常的项目开发中,我们只需要知道dependencies和devDependencies的区别即可。环境依赖放在devDependencies中,非环境依赖放在dependencies中。但是在开发npm包的时候,我们需要深入了解package.json中依赖相关字段的区别。dependencies的翻译dependencies是依赖的意思。如果我们开发一个新的包,如果它根本不依赖任何第三方包,那么这个字段就可以省略。但事实上,这种情况很少见。我们新开发的包一般是指一些第三方的包,也就是内部需要或者导入一些第三方的包。这时候我们引用的这些第三方包应该在dependencies字段中,这是标准的位置。那么当别人安装我们的包时,npm将如何处理dependencies字段中的依赖包呢?首先,dependencies字段中的第三方包是我们包正常??运行所必需的。所以,为了保证我们的包能够正常运行,npm会检查确保这些第三方包必须可用。当引用我们包的项目的node_modules中我们包的dependencies字段中没有包时,npm会在安装我们包的时候在node_modules中我们包的dependencies字段中安装第三方包。(这也是为什么我们安装一个包的时候node_modules里面有一堆包的原因之一)当我们包的dependencies字段中的包存在于引用我们包的项目的node_modules中时,npm开始检查,检查版本,如果现有版本适合使用,则不会再安装。比如本地项目中的版本是1.0.0,但是我们包中的依赖要求是^1.0.0,这是合规的。当引用我们package的项目中的node_modules包含我们package的dependencies字段中的package,但是npm查到版本不匹配,比如本地项目中的版本是1.0.0,但是需要的版本在我们的package的dependencies中是^1.0.2,显然版本不匹配,因为一些第三方的package可能不同版本的api差异很大,所以npm会在我们的package中新建一个node_modules来保证我们的包可以正常运行,在里面安装依赖。好像会有node_modules的嵌套,如下:PS:有人会说存在两个版本有问题,就是有两个版本的第三方包和项目有数据交互的时候有时,因为两个包都会被导入和使用,所以会出现冲突或者数据覆盖。这是可能的,但我觉得这种情况很少见。我们发布的包中依赖的第三方包应该只为我们的包提供特定的功能。完成功能就好了,这是我们包的完整性的一部分。.如果真的涉及到数据,那我觉得不应该放到dependencies这个字段里。可以放在peerDependencies中。devDependenciesdevDependencies转化为开发环境依赖。我们在开发一个npm包的时候,会涉及到编译、打包等,这些操作依赖于一些开发环境包。根据标准,这些包应该放在devDependencies字段中。那么当别人安装我们的包时,npm将如何处理devDependencies字段中的依赖包呢?答案是,无视!npm不会管这个字段,因为这个字段的第三方包只是在它开发的时候用到的,不是我们npm包的一部分。这个字段只有在我们的包在本地开发的时候才会用到。peerDependenciespeerDependencies这个词不好翻译。直译过来就是平等依赖、平等依赖的意思。我觉得根据它的实际作用,翻译成“适应性依赖”其实更好。那么这个字段到底是做什么用的呢?是这样的,你想,我们开发第三方包的时候,会引用第三方包,那么我们开发的包会不会被其他第三方包引用呢?我们使用dependencies字段来向npm说明我们依赖的包,那么我们是不是也应该告诉npm我们当前版本适用于哪些第三方包呢?由于我们不知道在开发的时候会引用哪个第三方包,所以这种情况一般是基于第三方包具体开发会引用我们,常见的是插件开发。比如我们开发一个webpack插件,不同版本的webpack插件开发提供的规范和API是不一样的。如果我们开发一个webpack3的插件,那么我们要告诉npm,我们的插件只能适配webpack3。用webpack5。告诉什么?只需使用peerDependencies字段。比如babel-loader的package.json文件中peerDependencies字段中的第三方包,并不是我们npm包中使用的,也不是开发环境会用到的包,而是我们适配的包。那么当别人安装我们的包时,npm将如何处理peerDependencies字段中的依赖包呢?为了解释这个字段,npm着实纠结了很久。在npmv1-v2版本中,npm对这个字段的处理是自动帮你安装,但是后来大家觉得太混乱了,功能和dependencies字段太像了。为了不迷惑大家,npm在v3-v6的时候,我不会自动给大家安装这个字段。我会给你一个警告,提醒你必须自己安装这个依赖。后来不知道npm听了什么建议,在v7-v8(目前最新)版本又回到了自动帮你安装的状态。由于npmv1-v2版本太旧,不再研究。下面是npmv3-v6和npmv7-v8之间对peerDependencies字段的处理的比较。npmv3-v6当引用我们包的项目中的node_modules没有我们包的peerDependencies字段中的包时,npm会在安装我们的包时给出警告??,提示用户自行安装。当引用我们package的项目中的node_modules包含我们package的peerDependencies字段中的package,但是npm比较版本不匹配时,会给出warning??提示用户。当引用我们包的项目中的node_modules包含我们包的peerDependencies字段中的包时,npm检查发现版本匹配,没有警告,输出正常。npmv7-v8当引用我们包的项目的node_modules中我们包的peerDependencies字段中没有包时,npm会在安装我们的包时将我们包的peerDependencies字段中的第三方包压扁安装在node_modules中.当引用我们package的项目中的node_modules包含我们package的peerDependencies字段中的package,但是npm对比发现版本不匹配时,就会报错,安装失败。npm会让用户处理这个冲突错误。如果用户不处理,可以使用它的提示运行npmi--force或npmi--legacy-peer-deps。强制安装其中一个冲突版本。它可以解决错误报告,但用户对问题负责。当引用我们包的项目中的node_modules包含我们包的peerDependencies字段中的包时,npm对比发现版本匹配,没有报错,安装正常。PS:总结一下,peerDependencies和dependencies最大的区别就是dependencies字段会嵌套node_modules,而peerDependencies字段不会嵌套node_modules。后面写在上面的内容中,dependencies和devDependencies都很容易理解。也就是说,peerDependencies有点难理解。坦白说,包管理工具是处理包间依赖关系最麻烦的。当依赖包的版本有冲突时,按理说应该是不应该重复安装包,数据交互出现问题。处理包版本冲突。在v7-v8版本中,虽然npm恢复了peerDependencies自动为你安装的状态,但是新增了一个字段peerDependenciesMeta。该字段可以将peerDependencies中的包设置为optional状态,设置为optional状态是不会自动帮你安装,也不会报错。在一些复杂的情况下,必须综合考虑灵活使用这些字段。还有一个名为bundledDependencies的字段,它在某些时候也很有用。这些有空再说吧。
