build_runner でのコード生成
Flutter(Dart)でのコード自動生成、出番多いですよね。
モデル定義やAPI・Firebase等との通信には不可欠と言っても過言でない Freezed・json_serializable・Retrofit を筆頭に
状態管理の決定版 Riverpod も今やコード生成抜きには語れませんし、ユニット/ウィジェットテストをかっちり整備すれば Mockito、
多言語対応が必要なら slang ――と自動生成抜きではもはや一定規模以上の開発は非現実的と言えます。
そんな build_runner での自動生成も、大概入力元/出力先はデフォルトの設定12 かと思いますのでその場合気をつけることは特にありません。
が、出力先を一か所にまとめたいetc.で生成ファイル出力先を build.yaml
で指定している場合は、自動生成を行うファイルやパッケージを新たに追加する際自動生成ファイルもエラーも何も出てこずド嵌まりすることがありますのでご注意ください。そう、私のことです(泣
生成されない場合に行うこと
既に導入していたパッケージで生成ファイルの出力先を指定していた場合 build.yaml
に下記のような設定があるかと思います。
source_gen|combining_builder:
options:
build_extensions:
'input/pattern': 'output/path'
この設定、入力パターンの限定と出力先の指定がワンセットなため、元々の設定意図は出力先の変更だけだったとしても
入力パターンにマッチしないファイルはコード生成指示(アノテーション等)がスルーされてしまい、生成ファイルもエラーも出力されない事態に陥ります。
従って、新たに生成対象を追加する際3 には既存設定で出力先の変更を指定してないか、していたら入力パターンが追加分をカバーできているかを確認し、未カバーだったら追記もしましょう…というお話でした。
補足・経緯(という名の概ね余談)
コード生成を行うパッケージの新規追加時、設定したい項目が特になければ build.yaml
にはそのパッケージに関する設定は何も書かないですし
何か書くにしても入出力先もそのパッケージの設定項目かな?と(あまり明るくなければ)思ってしまいそうなので、その点が罠になりそうに感じました。
実際私のケースでも、当初 Freezed(& json_serializable)で 出力先も一箇所(generatedフォルダ)にまとめる設定でコード生成を行っていて
後から Retrofit を追加4した際にこの罠に嵌まってしまい、必死に retrofit(_generator) の設定方法を探し回って builders > retrofit
以下をあれこれいじくり返すもうんともすんとも出力されず途方に暮れる・・・という状況でした。
build.yaml(抜粋)
targets:
$default:
builders:
source_gen|combining_builder:
options:
build_extensions:
+ # 🔽ここにこんな感じに書くのが正解
+ '^lib/api_client.dart': 'lib/api_client.g.dart'
'^lib/{{}}s/model.dart': 'lib/generated/{{}}.g.dart' # ★
freezed:
options:
build_extensions:
'^lib/{{}}s/model.dart': 'lib/generated/{{}}.freezed.dart'
+ # retrofit_generatorに対する個別の設定は🔽ここに書くが
+ # generate_for はこの場合効かず(★の指定が優先のため)
+ # options: 以下の設定も特にない場合は丸々不要となる
+ retrofit_generator:
+ enabled: true
+ generate_for:
+ include:
+ - lib/api_client.dart
+ options:
+ # 略
GitHub Copilot のAIチャットにも手を変え品を変え尋ねてみたものの、build_extensions
設定と新たに生成対象としたいファイルのパスの競合が原因と言いつつ5
その先の解決方法はトンチンカンなことばかり言ってくる(その通り書いてもエラーにしかならない)ので結局最後の一押しは自力でどうにか😥 AIももっと上手に使いこなせるようになりたい。
環境
[√] Flutter (Channel stable, 3.29.1, on Microsoft Windows [Version 10.0.26100.4351], locale ja-JP)
[√] Windows Version (11 Pro 64-bit, 24H2, 2009)
[√] Android toolchain - develop for Android devices (Android SDK version 35.0.1)
[X] Chrome - develop for the web (Cannot find Chrome executable at .\Google\Chrome\Application\chrome.exe)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.13.3)
[√] Android Studio (version 2024.3)
[√] VS Code (version 1.101.1)
[√] Connected device (2 available)
[√] Network resources
執筆時点ではChromeは未インストール(常用ブラウザがChromeでないことと、Webアプリは開発スコープ外なこと以外に特段の理由はありません)
freezed_annotation: ^2.4.4
dev_dependencies:
build_runner: ^2.4.13
freezed: ^2.5.7
json_serializable: ^6.9.0
retrofit_generator: ^9.2.0