语义化版本

语义化版本是 Tom Preston-Werner 为了解决「Dependency Hell」而建立的一种定义版本号的方式,其提出了这样一种版本格式:主版本号.次版本号.修订号(MAJOR.MINOR.PATCH),版本号递增规则如下:

  1. 主版本号(MAJOR):做了不兼容的 API 修改。
  2. 次版本号(MINOR):做了向下兼容的功能性新增。
  3. 修订号(PATCH):做了向下兼容的问题修正。
  4. 先行版本号及版本编译信息可以加到「主版本号.次版本号.修订号」的后面,作为延伸,如 1.0.0-alpha

版本控制方式

前端依赖管理工具中 bower 以及 npm 都采用语义化的方式定义依赖包的版本,并在项目中采用配置文件进行版本管理。而在配置文件中通常有三种版本控制的方式:

  • 升级次版本号

    "dependencies": {
      "angular": "^1.5.8"
    }
    

    这种版本控制的方式会选择升级依赖到 angular 1.x.x 版本中的最高版本。

  • 升级修订号

    "dependencies": {
      "angular": "~1.5.8"
    }
    

    这种版本控制的方式会选择升级依赖到 angular 1.5.x 版本中的最高版本。

  • 不升级任何版本

    "dependencies": {
      "angular": "1.5.8"
    }
    

    这种版本控制的方式会固定依赖版本为 angular 1.5.8 而不做任何升级。

NPM 版本锁定

npm 5.0 及以上版本中提供了一个新特性,新增了一个 package-lock.json 文件来限制依赖包的版本。执行 npm install 为项目安装依赖的过程中,会根据 node_modules 中的依赖树生成 package-lock.json 来记录当前依赖树中各个依赖的具体版本及来源信息。

package-lock.json 的作用,也曾在 5.0.0 -> 5.1.0 -> 5.4.2 的版本变迁中发生过变化。在初始版本,即 5.0.x 系列版本中,在执行 npm install 时,package.json 中的改动会被忽略,而通过 package-lock.json 来下载或更新相应依赖。而在 5.1.0 -> 5.4.2 期间,这部分出现了一些 Bug,package-lock.json 不再生效,只有 package.json 会发挥作用。而在 5.4.2 后,该 Bug 被修复,逻辑也变得更加的合理。根据 package.json 的版本号和 package-lock.json 中版本兼容情况会不同的行为,兼容的判断和上文提到的版本控制方式相关,具体行为场景如下:

  • 如果 package.json 的版本号和 package-lock.json 中版本兼容,那么即使此时 package.json 中有新的版本,执行 npm install 也还是会根据 package-lock.json 下载,即 package.json 的改动会被忽略。

  • 如果 package.json 的版本号和 package-lock.json 中版本不兼容,执行 npm install 时会根据 package.json 中的版本号下载不兼容的依赖包,而 package-lock.json 中的版本号将会对应的被更新。