有个npm包叫a,项目的dependencies有a和b两个依赖,a的版本是version1。b中也依赖了a这个包,版本是version2。在项目打包的时候,会把a的这两个版本都打进build文件中。本文主要分析对同一个包有多个版本依赖的状况。node
在npm 3.0版本以前,node_modules里面的依赖是一种树形的嵌套结构,这样会形成不少依赖重复安装,而且node_modules的层级会很是深。npm
在npm 3.0的版本中,会先分析全部的依赖关系,尽量的把依赖层级拍平。若是一个包没有被重复依赖,它会安装在node_modules的第一层。当同一个包出现版本冲突时,会根据就近原则,把对应的依赖安装在当前包的node_modules文件夹中。redux
SemVer的中文名称是语义化版本控制规范。npm默认使用SemVer来进行模块的版本控制。一个发布到npm的包要严格遵照SemVer的版本规范,否则会发布失败。bash
主版本号.次版本号.修订号,能够用x.y.z的写法来简单表示。ui
当要进行大版本迭代的时候,或者增长一些核心的功能,但又不能保证新版本百分之百正常,这个时候就能够发布先行版本。SemVer规范中使用alpha、beta和rc来修饰先行版本。spa
先行版本的版本号可使用:1.0.0-alpha、1.0.0-beta.一、1.0.0- rc.一、1.0.0-0.3.7等。版本控制
进行版本号比较时,x、y、z依次比较code
先行版本号的规则是rc > beta > alphaci
1.0.0 < 2.0.0 < 2.1.0 < 2.1.1
1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0- rc.1 < 1.0.0 复制代码
^符是npm安装依赖的默认方式。io
按照版本的语义,就是彻底信任包拥有者可以根据语义进行正确的包升级,不会引入具备破坏性的改变,而且作到对老版本的兼容。
^1.2.3 <=> >=1.2.3 <2.0.0
^0.2.3 <=> >=0.2.3 <0.3.0
^0.0.3 <=> >=0.0.3 <0.0.4
^1.2.x <=> >=1.2.0 <2.0.0
^0.0.x <=> >=0.0.0 <0.1.0
^0.0 <=> >=0.0.0 <0.1.0
^1.2.3-beta.2 <=> >=1.2.3-beta.2 <2.0.0
^0.0.3-beta <=> >=0.0.3-beta <0.0.
复制代码
~符是老版本npm的默认方式,它只会安装升级z位的版本,是一种很保守的依赖管理策略。
~1.2.3 <=> >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0
~1.2 <=> >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0 (Same as 1.2.x)
~1 <=> >=1.0.0 <(1+1).0.0 := >=1.0.0 <2.0.0 (Same as 1.x)
~0.2.3 <=> >=0.2.3 <0.(2+1).0 := >=0.2.3 <0.3.0
~0.2 <=> >=0.2.0 <0.(2+1).0 := >=0.2.0 <0.3.0 (Same as 0.2.x)
~0 <=> >=0.0.0 <(0+1).0.0 := >=0.0.0 <1.0.0 (Same as 0.x)
~1.2.3-beta.2 <=> >=1.2.3-beta.2 <1.3.0
复制代码
固定版本的依赖是肯定的,除非手动升级,否则每次都安装相同的版本。
当一个依赖包出现版本冲突时,会根据这个包不一样的升级策略来肯定版本号。若是最后的版本号相同,只会在项目的node_modules里面安装这个版本的依赖;若是版本号不一样,则两个版本号的依赖都会安装。
由于每一个npm包的版本更迭都不一样,因此并无一个固定的规则去适用全部的状况。当一个包被屡次依赖的时候,须要去npm的官网去查看这个包全部的版本,而后根据依赖的升级规则,去判断这个包是否会版本冲突。
下面是当前时间,redux latest这个tag下面的版本号
4.0.1
4.0.0
3.7.2
3.7.1
3.7.0
3.6.0
3.5.2
3.5.1
3.5.0
3.4.0
3.3.1
3.3.0
3.2.0
...
复制代码
~3.7.0 <=> ^3.6.0
3.7.2 <=> ^3.6.0
^3.3.0 <=> ^3.5.0
^3.6.0 <!=> ^4.0.0复制代码