1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】build_runnerの生成対象(特に別パッケージ)を追加した際、自動生成ファイルが出てこなかったら確認すること

Posted at

build_runner でのコード生成

Flutter(Dart)でのコード自動生成、出番多いですよね。
モデル定義やAPI・Firebase等との通信には不可欠と言っても過言でない Freezed・json_serializable・Retrofit を筆頭に
状態管理の決定版 Riverpod も今やコード生成抜きには語れませんし、ユニット/ウィジェットテストをかっちり整備すれば Mockito、
多言語対応が必要なら slang ――と自動生成抜きではもはや一定規模以上の開発は非現実的と言えます。

そんな build_runner での自動生成も、大概入力元/出力先はデフォルトの設定12 かと思いますのでその場合気をつけることは特にありません。
が、出力先を一か所にまとめたいetc.で生成ファイル出力先を build.yaml で指定している場合は、自動生成を行うファイルやパッケージを新たに追加する際自動生成ファイルもエラーも何も出てこずド嵌まりすることがありますのでご注意ください。そう、私のことです(泣

生成されない場合に行うこと

既に導入していたパッケージで生成ファイルの出力先を指定していた場合 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 doctor
[√] 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アプリは開発スコープ外なこと以外に特段の理由はありません)

pubspec.yaml(抜粋)
  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
  1. build.yaml がない or あっても入出力の指定をしていない

  2. 入力は全ファイル対象・出力先は入力元と同じ場所

  3. 単に生成対象ファイルを追加する際も勿論ながら、コード生成を行うパッケージを新たに追加する際はフォルダ構成なども異なる可能性が高くなるので殊更要注意かと

  4. 元々半ば練習でプロトタイピングしていたコードで、当時 Retrofit は未習得だったためAPI通信はコード生成を伴わない http で行っていたが、開発本格化のため切り替えることに

  5. とはいえ結局これが最大のヒントではあった

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?