You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Melos时build_runner跨包AssetNotFoundException问题排查

问题分析与解决

两种构建方式的核心差异

  • Melos默认执行逻辑:melos run build_runner会为每个包启动独立子进程执行build_runner,默认不清理旧缓存,也不会主动同步跨包的生成文件依赖状态。第一次执行时,app包的build_runner缓存可能还停留在sdk未生成代码的旧快照,就算sdk刚生成了.g.dart/.freezed.dart,app的构建进程也读不到。
  • 自定义bash脚本:先执行build_runner clean清空所有包的.dart_tool/build缓存,再按sdk→app的顺序构建。此时app的build_runner是从头解析依赖,能直接读取到sdk刚生成的文件,没有旧缓存干扰。

报错根源

  1. build_runner缓存过期:首次用Melos构建时,app包的build_runner缓存保留了旧的依赖元数据,认为sdk没有那些生成文件,即使本地文件已经存在,也会触发AssetNotFoundException。
  2. 子进程文件系统隔离:Melos给每个包开独立子进程,sdk生成文件后,app的子进程没及时感知到文件变化,Dart的包解析器也没刷新依赖状态。
  3. 依赖顺序未强制:如果Melos脚本没配置按依赖顺序执行,可能出现app先于sdk构建的情况(即使手动选了sdk,缓存问题依然存在)。

修复方案

方案1:修改Melos脚本,强制按依赖顺序+清理冲突文件

在根目录melos.yaml中更新build_runner脚本:

scripts:
  build_runner:
    run: melos exec -s "dependencies" -- "dart run build_runner build --delete-conflicting-outputs"
    description: 按依赖顺序执行build_runner,自动清理冲突的旧生成文件
  • -s "dependencies":强制按包的依赖层级执行(先构建被依赖的sdk,再构建依赖它的app)
  • --delete-conflicting-outputs:每次构建时自动清理旧的生成文件,避免缓存干扰

方案2:先统一清理缓存,再构建

如果方案1无效,先清理所有包的构建缓存,再按顺序执行:

scripts:
  build_runner_clean:
    run: melos exec -- "dart run build_runner clean"
    description: 清理所有包的build_runner缓存
  build_runner:
    run: |
      melos run build_runner_clean
      melos exec -s "dependencies" -- "dart run build_runner build"
    description: 先清理缓存,再按依赖顺序执行build_runner

方案3:手动刷新Dart包缓存

偶尔出现缓存未同步时,先执行以下命令再跑Melos构建:

dart pub get

确保所有包的依赖元数据是最新的。

验证步骤

  1. 删除所有包下的.dart_tool/build目录,模拟首次构建场景
  2. 执行修改后的melos run build_runner,确认sdk和app都能正常构建
  3. 重复执行多次,检查是否不再触发AssetNotFoundException

内容的提问来源于stack exchange,提问作者Marcin Kapusta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 10:34:02