Using drift classes in other builders

Configure your build to allow drift dataclasses to be seen by other builders.

It is possible to use classes generated by drift in other builders. Due to technicalities related to Dart's build system and source_gen, this approach requires a custom build configuration. For complex builds like this, we recommend running drift in it's modular mode. This more is more efficient for larger builds and can be enabled by putting this content in a file called build.yaml next to your pubspec.yaml:

    auto_apply_builders: false
        enabled: true

      # run drift's builder first
      - ":drift"
      # This builder is enabled by default, but we're using the modular builder in
      # its own target instead.
        enabled: false

With modular generation, you'll have to replace the part statement in the database file with an import to filename.drift.dart. Also, your database class now extends from $DatabaseName, without a leading underscore.

By generating independent libraries, drift can manage imports on its own. By declaring a dependency in build.yaml, the build system also ensures that drift-generated files are ready before built_value or other builders that need to see them are running.

A full example is available as part of the drift repo.

If you run into any problems with this approach, feel free to open an issue on drift.

The technicalities, explained

Almost all code generation packages use a so called "shared part file" approach provided by source_gen. It's a common protocol that allows unrelated builders to write into the same .g.dart file. For this to work, each builder first writes a .part file with its name. For instance, if you used drift and built_value in the same project, those part files could be called .drift.part and .built_value.part. Later, the common source_gen package would merge the part files into a single .g.dart file.

This works great for most use cases, but a downside is that each builder can't see the final .g.dart file, or use any classes or methods defined in it. To fix that, drift offers other builders - drift_dev|not_shared and drift_dev|modular - those will generate a separate file only containing code generated by drift. So most of the work resolves around disabling the default generator of drift and use the non-shared generator instead.

Finally, we need to the build system to run drift first, and all the other builders otherwise. This is why we split the builders up into multiple targets. The first target will only run drift, the second target has a dependency on the first one and will run all the other builders.