如何解决多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,从根源上避免文件名重复。
操作步骤
- 修改A包中构建钩子的输出文件名,将
dyLib改为A_dyLib,同步修改A包内引用该动态库的代码路径。 - 对B包执行同样操作,使用
B_dyLib作为文件名。 - 重新运行构建命令,两个动态库文件名不同,不会触发重复错误。
这种方案无需额外检查逻辑,适合依赖交集复杂、难以自动判断的场景。
方案3:统一由底层依赖包管理code_asset
如果A是B的直接依赖,让最底层的包(A)负责添加dyLib作为code_asset,上层包(B)不再重复添加,通过依赖传递直接使用该动态库。
操作步骤
- 移除B包构建钩子中添加
dyLib的代码。 - 确保A包的构建钩子正常添加
dyLib,且B包的pubspec正确依赖A包。 - B包中直接引用A包提供的动态库即可,无需重复注册。
若依赖链复杂,可通过pub deps命令梳理依赖关系,找到最适合统一管理动态库的底层包。
内容的提问来源于stack exchange,提问作者Jack Tjoeng
相关产品推荐
相关产品推荐

