build 库的使用

Wuba2022年10月12日大约 2 分钟

Fair 源码中用到了 build 库,因此,本文主要介绍一下 build 库的使用。

1. build 库的介绍

定义用于创建 Builder 的接口,这是一种在构建系统(pub、bazel、standalone runner)之间兼容的代码生成方式。通常需要配合 build_runner 使用。

2. build 库的使用

2.1 添加 build 库依赖

dependencies:
  # ···
  build: ^2.3.0

2.2 创建 Builder

代码生成的业务逻辑。通常我们会创建 Builder 的自定义实现。

class CopyBuilder extends Builder {
  /// You can only output files that are configured here by suffix substitution.
  /// You are not required to output all of these files, but no other builder
  /// may declare the same outputs.
  @override
  Map<String, List<String>> get buildExtensions => const {
        ......
      };

  /// This is where you build and output files.
  @override
  FutureOr<void> build(BuildStep buildStep) async {
    ......
  }
}

介绍一下 Builder 中通常会使用到的工具。

BuildStep

BuildStep 是 Builder 与外部模块交互的方式。通过 BuildStep 可以读/写文件和解析 Dart 源代码。

通常我们会使用 buildStep#readAsString 和 buildStep#writeAsString 读取和写入文件信息而不是直接使用文件系统读取/写入文件。这样不仅可以便于实现增量编译,也不用自己判断适配运行环境。

Resolver

Dart Analyzer的接口,可以解析需要静态分析和/或代码生成的代码。

如果需要解析文件信息,可以使用BuildStep#resolver 。这样可以确保系统中的所有 Builder 共享相同的分析 context,从而在使用多个 Builder 解析时可以大大加快整个系统的速度。

2.3 配置 buildExtensions

buildExtensions 表示从输入扩展名到输出扩展名的映射。

  @override
  Map<String, List<String>> get buildExtensions => const {
        '.dart': ['.dart.copy']
  };

2.4 build() 开发

核心业务逻辑开发,比如下面代码,将所有 .dart 的文件拷贝,生成同名但是后缀是 .dart.copy 的文件。

  @override
  Future<void> build(BuildStep buildStep) async {
    // Each `buildStep` has a single input.
    var inputId = buildStep.inputId;

    // Create a new target `AssetId` based on the old one.
    var copy = inputId.addExtension('.copy');
    var contents = await buildStep.readAsString(inputId);

    // Write out the new asset.
    await buildStep.writeAsString(copy, contents);
  }

2.5 配置 build.yaml

build.yaml 文件配置如下:

builders:
  dart_copy_builder:
    import: 'package:dart_copy_helper/builder.dart'
    builder_factories: ['dartCpBuilder']
    build_extensions: { '.dart': ['.g.dart'] }
    auto_apply: root_package
    build_to: source

这样,一个简单的使用 build 的 demo 就开发完成了。可以使用如下命令运行。

flutter pub run build_runner build
上次编辑于:
贡献者: sunzhe03