Dart 3:如何将build_runner生成文件指定到自定义文件夹
问题:build_runner生成的.entity.dart文件无法输出到指定目录
需求与现状
执行dart run build_runner build后,.entity.dart文件与原类文件同级,期望将这些文件输出到test_files/gen目录下。相关项目结构、代码及配置如下:
当前项目结构
├── lib │ ├── entity_generator.dart │ └── test_files │ ├── annotation │ │ └── annotation.dart │ ├── classes2.dart │ ├── classes2.entity.dart │ ├── classes.dart │ ├── classes.entity.dart │ └── gen ├── pubspec.lock └── pubspec.yaml
期望项目结构
├── lib │ ├── entity_generator.dart │ └── test_files │ ├── annotation │ │ └── annotation.dart │ ├── classes2.dart │ ├── classes.dart │ └── gen │ ├── classes.entity.dart │ └── classes2.entity.dart ├── pubspec.lock └── pubspec.yaml
生成器代码(entity_generator.dart)
class EntityGenerator extends GeneratorForAnnotation<Entity> { @override generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) { if (element is! ClassElement) { throw InvalidGenerationSourceError('`@Entity` can only be used on classes.', element: element); } final className = element.displayName; final buffer = StringBuffer(); // Generate the class with entity exports buffer.writeln('class $className extends Entity {}'); return buffer.toString(); } } Builder entityBuilder(BuilderOptions options) => LibraryBuilder(EntityGenerator(), generatedExtension: '.entity.dart');
当前build.yaml配置
targets: $default: builders: test_app|export_locating_builder: enabled: true builders: export_locating_builder: import: "package:test_app/entity_generator.dart" builder_factories: ["entityBuilder"] build_extensions: { '^lib/test_files/{{}}.dart': ['lib/test_files/gen/{{}}.entity.dart'] } auto_apply: dependents build_to: source
错误分析与修正方案
核心错误点
LibraryBuilder的generatedExtension参数与build.yaml配置冲突
代码中给LibraryBuilder指定了generatedExtension: '.entity.dart',这会直接覆盖build.yaml中定义的输出路径规则,导致生成文件始终与原文件同级。auto_apply配置不合理
当前设置auto_apply: dependents,该配置仅会将builder应用到依赖当前包的其他包,无法作用于当前包内的文件。
修正步骤
1. 修改生成器代码,移除冲突参数
编辑entity_generator.dart,删除LibraryBuilder中的generatedExtension参数,让build.yaml的路径配置生效:
class EntityGenerator extends GeneratorForAnnotation<Entity> { @override generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) { if (element is! ClassElement) { throw InvalidGenerationSourceError('`@Entity` can only be used on classes.', element: element); } final className = element.displayName; final buffer = StringBuffer(); buffer.writeln('class $className extends Entity {}'); return buffer.toString(); } } // 移除generatedExtension参数 Builder entityBuilder(BuilderOptions options) => LibraryBuilder(EntityGenerator());
2. 调整build.yaml配置
更新build.yaml,修正auto_apply并确保路径规则清晰:
targets: $default: builders: test_app|export_locating_builder: enabled: true # 明确指定输出路径,确保覆盖默认行为 build_extensions: '^lib/test_files/{{}}.dart': ['lib/test_files/gen/{{}}.entity.dart'] builders: export_locating_builder: import: "package:test_app/entity_generator.dart" builder_factories: ["entityBuilder"] build_extensions: '^lib/test_files/{{}}.dart': ['lib/test_files/gen/{{}}.entity.dart'] auto_apply: root_package # 应用到当前根包 build_to: source applies_builders: ["source_gen|combining_builder"] # 配合source_gen的合并构建器
3. 清理并重新构建
执行以下命令清理旧生成文件并重新构建:
dart run build_runner clean dart run build_runner build
内容的提问来源于stack exchange,提问作者Mircea
相关产品推荐
相关产品推荐

