基础与工程篇-pubspec 依赖管理与版本锁定实践

5 阅读2分钟

pubspec 依赖管理与版本锁定实践

Flutter 实战系列第 4 篇。
目标:把依赖从“能跑就行”升级到“可追踪、可回滚、可团队协作”。

1. 问题背景:业务场景 + 现象

随着项目变大,依赖会越来越多:网络、状态管理、音视频、支付、广告、埋点、图片、工具链……
如果 pubspec.yaml 管理松散,常见问题会很快出现:

  • 新同学拉代码后 pub get 结果和你不一致
  • 某个插件升级后,iOS/Android 其中一端突然崩
  • 线上包和本地包依赖版本不一致,问题无法复现
  • 间接依赖(transitive dependency)升级导致隐形行为变化
  • 私有 Git 包引用分支,今天可用明天不可用

2. 原因分析:核心原理 + 排查过程

2.1 核心原理

Flutter 依赖解析是“约束求解”:

  • pubspec.yaml 写的是版本约束(如 ^2.0.0
  • pubspec.lock 才是当前解析后的“确定版本
  • 团队协作要稳定,核心是:声明约束 + 锁定结果 + 变更可审计

2.2 常见反模式

  1. 所有依赖都写 any 或过于宽松的 ^
  2. 私有 git 依赖只写 ref: dev,不锁 commit
  3. 不提交 pubspec.lock
  4. 一次性升级十几个依赖,问题定位困难
  5. 线上紧急修复时没有“版本回滚”策略

3. 解决方案:方案对比 + 最终选择

3.1 方案对比

  • 松散管理(不锁定)
    优点:升级快
    缺点:不可复现、风险不可控

  • 严格锁定(推荐)
    优点:可复现、可回滚、可审计
    缺点:需要建立升级流程

3.2 最终选择(团队实践)

  1. 主工程依赖按“稳定约束”声明
  2. pubspec.lock 必须提交到仓库
  3. 私有 git 包固定 resolved-ref(commit)
  4. 依赖升级遵循“小步快跑,一次一类”
  5. CI 增加依赖一致性检查

4. 关键代码:最小必要代码片段

4.1 pubspec.yaml(推荐写法)

dependencies:
  flutter:
    sdk: flutter
  flutter_riverpod: ^2.6.1
  dio: ^5.7.0
  # 私有包建议锁分支并在 lock 中固定 commit
  in_app_purchase:
    git:
      url: http://example.com/flutter_components/in_app_purchase.git
      ref: apple