跳到内容

开源社区遵循了一套约定叫语义化版本(SemVer):版本号 MAJOR.MINOR.PATCH,比如 2.15.2

变化时你的代码会怎样
MAJOR1.0.0 → 2.0.0不兼容 API 变更旧代码可能跑不起来
MINOR2.14.0 → 2.15.0加新功能,向后兼容旧代码照跑
PATCH2.15.1 → 2.15.2修 bug,向后兼容放心升级

看到 MAJOR 变化就要读 changelog


版本范围符号

json
{
  "lodash": "^4.17.21",   // 4.x.x 内随便升级
  "express": "~4.18.2",   // 4.18.x 内升级
  "debug": "4.3.4"        // 锁死
}
写法含义实际范围
^2.15.2主版本内随便升>=2.15.2 <3.0.0
~2.15.2次版本内随便升>=2.15.2 <2.16.0
2.15.2锁定只装 2.15.2

传递依赖与冲突

一个库依赖别的库——比如 Jackson → jackson-core。包管理器自动处理这个链条。

但如果两个依赖要不同版本的同个库?Lib A 要 jackson-core 2.14,Lib B 要 2.15——这就是依赖冲突

不同工具的策略:

  • Maven:"最近优先"
  • Gradle:选最高版本
  • npm/pip:各自装独立副本(可共存)

用 dependency:tree 排查

bash
mvn dependency:tree

输出示例:

+- jackson-databind:jar:2.15.2:compile
|  \- jackson-core:jar:2.15.2:compile
\- lib-b:jar:1.0:compile
   \- jackson-core:jar:2.14.0:compile

jackson-core 出现两个版本。Maven 选 2.15.2(路径更短)。万一出事,用 <exclusions>

xml
<dependency>
  <groupId>com.example</groupId>
  <artifactId>lib-b</artifactId>
  <version>1.0</version>
  <exclusions>
    <exclusion>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>

快速自查

场景动作
依赖更新后项目崩了检查 MAJOR 版更;读 changelog
两个库要不同版本的同一依赖mvn dependency:tree
想彻底锁死版本写死版本号
装了库但没生效看是不是被冲突策略排除了

→ 下一章

动手练习 + 排障走一遍。

第5章:练习与排障

Built with VitePress | Software Systems Atlas