npm的版本管理
一个依赖包的package.json
是对一个项目的描述,其中dependencies
和devDependencies
表示依赖包所需的依赖列表。
dependencies与devDependencies的区别
安装依赖包可以使用
// 安装在dependencies下
npm install xxx --save | npminstall -S
// 安装在devDependencies下
npm install xxx --save-dev | npm install -D
一句话概括就是:dependencies
安装生产模式下所需的依赖,devDependencies
安装开发模式下所需的依赖。
比如:
lodash,jquery,element-ui等,在我们生产环境上需要,所以要安装在dependencies
下。
而eslint,webpack,sass-loader等,只在开发环境中使用,生产环境并不需要这些东西,所以就放在devDependencies
下。
但是,作为前端的打包,devDependencies
下安装的lodash等也会被打包到bundle中,也就是说在线上也是可以使用的。而nodejs的依赖,由于没有打包的概念,所以生产环境去install依赖时,就不会安装devDependencies
下的依赖包,这一点十分重要。
版本语义化 semver
版本号
一个包的版本遵循主版本号
、次版本号
,修订号
,并且版本号递增的原则。
- 主版本号:当你做了不兼容的API修改时(破坏性修改)
- 次版本号:当你做了向下兼容的功能性新增/修改
- 修订号: 当你做了向下兼容的问题修正
先行版本
- alpha: 是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试人员使用。
- beta: 也是测试版,这个阶段的版本会一直加入新的功能。在Alpha版之后推出
- rc: Release Candidate) 系统平台上就是发行候选版本。RC版不会再加入新的功能了,主要着重于除错。
依赖版本号
- ^:表示同一主版本号中,不小于指定版本号的版本号。
`^2.2.1` 对应主版本号为 2,不小于 `2.2.1` 的版本号,比如 `2.2.1`、`2.2.2`、`2.3.0` ,主版本号固定
// 当该依赖有最新版本时(eg:2.3.3),npm install 会安装最新的依赖
- ~:表示同一主版本号和次版本号中,不小于指定版本号的版本号
`~2.2.1` 对应主版本号为 2,次版本号为 2,不小于 `2.2.1` 的版本号,比如 `2.2.1、2.2.2`,主版本号和次版本号固定
- >、<、=,>=,<=,-用来指定一个版本号范围
>2.1
//注意使用 `-` 的时候,必须两边都有空格。
1.0.0 - 1.2.0
- ||:表示或
^2 < 2.2 || > 2.3
- x、X、* 表示通配符
*`对应所有版本号
3.x`对应所有主版本号为 3 的版本号
node_modules依赖历史变迁
嵌套式结构
在npm早期版本,npm处理依赖的方式是以递归的形式,严格按照package.json结构来安装各自的node_modules。直到子依赖包不存在依赖其他模块才停止。
image.png
优点:
这种方式的结构清晰且一一对应。
缺点:
- 而且不同层级的以来中,可能引用的是同以模块却被安装多次,导致大量冗余。
- 层级嵌套非常之深,在windows系统下,文件路径长度最大限制为260个字符,层级嵌套过深可能导致不可预知的问题。
扁平化结构
为了解决以上问题,npm在3.x版本将结构优化为扁平结构。
即安装模块时,不管其是直接依赖还是子依赖的依赖,优先将其安装在 node_modules 根目录。
image.png
依赖模块查找流程:
- 在当前模块路径下搜索
- 在当前模块的node_modules下搜索
- 在上级模块的node_modules下搜索
.... -
直到搜索到根路径中的node_modules
如果版本发生冲突,比如my-app依赖c@1.0,0版本,a模块依赖c@2.0.0版本,而b模块依赖了c@3.0.0版本。
image.png
packge-lock.json
为了解决 npm install 的不确定性问题,在 npm 5.x 版本新增了 package-lock.json 文件,而安装方式还沿用了 npm 3.x 的扁平化的方式。
package-lock.json的requires
与dependencies
并不是所有的子依赖都有 dependencies 属性,只有子依赖的依赖和当前已安装在根目录的 node_modules 中的依赖冲突之后,才会有这个属性。
- requires 与package.json中的版本一致
-
dependencies 实际安装在node_modules中的版本。
image.png