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

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

错误分析与修正方案

核心错误点

  1. LibraryBuilder的generatedExtension参数与build.yaml配置冲突
    代码中给LibraryBuilder指定了generatedExtension: '.entity.dart',这会直接覆盖build.yaml中定义的输出路径规则,导致生成文件始终与原文件同级。

  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:16:22