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

如何解决多Dart包共享dynamic lib code_asset的重复添加错误

解决Dart包构建时动态库code_asset重复的问题

方案1:构建钩子中检查并避免重复添加

在构建钩子脚本中,添加code_asset前先检查是否已有同名的动态库存在,若存在则跳过添加操作。

具体实现代码

import 'package:build/build.dart';

class DyLibBuildHook extends Builder {
  @override
  Future<void> build(BuildStep buildStep) async {
    // 定义目标动态库的文件名
    const targetLibName = 'dyLib';
    // 搜索所有包中是否已存在该文件名的asset
    final existingLibs = await buildStep.findAssets(
      Glob('**/$targetLibName'),
    ).toList();

    // 仅当没有找到任何同名asset时,才添加当前包的动态库
    if (existingLibs.isEmpty) {
      // 读取当前包中的动态库文件(替换为你实际的文件路径)
      final libBytes = await buildStep.readBytes(
        AssetId(buildStep.inputId.package, 'lib/native/$targetLibName'),
      );
      // 写入到输出目录并标记为code_asset
      final outputAsset = AssetId(buildStep.inputId.package, targetLibName);
      await buildStep.writeAsBytes(outputAsset, libBytes);
      buildStep.addCodeAsset(outputAsset);
    }
  }

  @override
  Map<String, List<String>> get buildExtensions => {
        // 根据你的构建需求调整扩展,这里以触发dart文件构建为例
        '.dart': [],
      };
}

注意:如果你的动态库带有平台后缀(比如.so/.dll/.dylib),记得把后缀加入到搜索规则中,避免漏判。

方案2:为动态库添加包名前缀避免冲突

直接修改动态库的文件名,为不同包的动态库加上包名前缀,比如A包用A_dyLib,B包用B_dyLib,从根源上避免文件名重复。

操作步骤

  1. 修改A包中构建钩子的输出文件名,将dyLib改为A_dyLib,同步修改A包内引用该动态库的代码路径。
  2. 对B包执行同样操作,使用B_dyLib作为文件名。
  3. 重新运行构建命令,两个动态库文件名不同,不会触发重复错误。

这种方案无需额外检查逻辑,适合依赖交集复杂、难以自动判断的场景。

方案3:统一由底层依赖包管理code_asset

如果A是B的直接依赖,让最底层的包(A)负责添加dyLib作为code_asset,上层包(B)不再重复添加,通过依赖传递直接使用该动态库。

操作步骤

  1. 移除B包构建钩子中添加dyLib的代码。
  2. 确保A包的构建钩子正常添加dyLib,且B包的pubspec正确依赖A包。
  3. B包中直接引用A包提供的动态库即可,无需重复注册。

若依赖链复杂,可通过pub deps命令梳理依赖关系,找到最适合统一管理动态库的底层包。


内容的提问来源于stack exchange,提问作者Jack Tjoeng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 22:03:13