Conquering Code Generation in Dart (Video Series)

Conquering Code Generation in Dart (Video Series)

Code Generation describes the process of automatically generating code that one would otherwise write by hand. In this new series we will be exploring the tooling made available for Code Generation in Dart projects.

This has been one of the least covered and understood topics due to the lack of documentation on it. We will conquer this tooling beast and grow your confidence in its usage.

Watch Part 1 on YouTube

Get the source code

How to get started

Code Generation is available through a package called build. This package exposes a set of interfaces for creating what are known as Builders. A Builder is where you define the business logic to instruct the build process on how to generate code.

Although we encapsulate our logic inside a Builder class, we need a way to run this builder, and that’s where build_runner comes in. It runs the build process based on configuration defined inside a build.yaml file. In order for it to understand this build.yaml configuration, the build_config package is used to parse the instructions defined therein. Therefore the build_runner package uses build_config behind the scenes.

To create the files for the project, use the stagehand tool to scaffold a console application:

$ mkdir code_generators && cd code_generators
$ stagehand console-full

Open the pubspec.yaml file and update dependencies and dev_dependencies:

...
dependencies:
  build: ^1.1.6
  path: ^1.6.0
  markdown: ^2.0.3

dev_dependencies:
  build_config: ^0.4.1+1
  build_runner: ^1.6.6
  pedantic: ^1.7.0
  test: ^1.5.0

Update all your dependencies by running pub get.

Configuring the build.yaml file

The build.yaml file contains configuration for targets, builders, and post process builders. The builders configuration allows you to register the builders you have implemented, as well as the top-level function to invoke in order to run the build process for the builder in question. You would also set the build_extensions key with the same value as was set in the buildExtensions member of your Builder class the configuration relates to. The targets config allows you to configure your builder to run on a subset of files in your project, as well as specify if they are enabled or not.

Here’s a typical example registering our CopyBuilder and configuring a target for it:

targets:
  $default:
    builders:
      code_generators|copyBuilder:
        generate_for:
         - lib/*
        enabled: True

builders:
  copyBuilder:
    import: 'package:code_generators/code_generators.dart'
    builder_factories: ['copyBuilder']
    build_extensions:
      .txt:
        - .copy.txt
    build_to: source
    auto_apply: dependents

Learn more about configuring the build.yaml file

Watch Part 2 on YouTube

Watch Part 3 on YouTube

Get the source code

Further reading