Freezed + Riverpod 導入時にやること備忘録

本記事は [YUMEMI Flutter Advent Calendar 2023](https://qiita.com/advent-calendar/2023/yumemi-flutter) 2日目の記事です。

### モチベーション
会社に入って案件に従事していると、プロジェクト初期に行う設定などを忘れることが多いと思い備忘録を残していこうと思います。

## 前提
プロジェクトで Freezed + Riverpod を使いたいと考えた時、
自分の場合は、以下のパッケージを導入します。

- [build_runner](https://pub.dev/packages/build_runner)
- [freezed](https://pub.dev/packages/freezed)
- [freezed_annotation](https://pub.dev/packages/freezed_annotation)
- [json_serializable](https://pub.dev/packages/json_serializable)
- [json_annotation](https://pub.dev/packages/json_annotation)
- [flutter_hooks](https://pub.dev/packages/flutter_hooks)
- [hooks_riverpod](https://pub.dev/packages/hooks_riverpod)
- [riverpod_annotation](https://pub.dev/packages/riverpod_annotation)
- [riverpod_generator](https://pub.dev/packages/riverpod_generator)
- [riverpod_lint](https://pub.dev/packages/riverpod_lint)
- [custom_lint](https://pub.dev/packages/custom_lint)

かなり多いですね。
これらを導入するときには開発時のみ使用するパッケージなのかも気をつける必要があります。
また、これに加えてコードジェネレーションの設定も必要になります。

## 全パッケージ導入コマンド
以下コマンドで全てのパッケージを導入します。


```shell
flutter pub add dev:build_runner dev:freezed freezed_annotation dev:json_serializable json_annotation flutter_hooks hooks_riverpod riverpod_annotation dev:riverpod_generator dev:riverpod_lint dev:custom_lint
```

:::note warn
注意
すでに導入されているパッケージは最新版に更新されます
:::

## コードジェネレーション設定
自分が使っているbuild.yamlの設定

```yaml:build.yaml
targets:
  $default:
    builders:
      source_gen|combining_builder:
        generate_for:
          include:
            - "lib/**/*.dart"
        options:
          ignore_for_file:
            - type=lint
            - duplicate_ignore
      freezed:
        generate_for: #任意設定
          include:
            - "lib/**/model/*.dart"
            - "lib/**/*provider.dart"
      json_serializable:
        generate_for: #任意設定
          include:
            - "lib/**/model/*.dart"
            - "lib/**/*provider.dart"
        options:
          checked: true
          explicit_to_json: true
```

```yaml
# 設定時のバージョン
  build_runner: ^2.4.6
  freezed: ^2.4.5
  json_serializable: ^6.7.1
  riverpod_generator: ^2.3.5
```

### 解説

:::note warn
注意
パッケージのバージョンによっては記述方法が変わる可能性があります
:::

**source_gen|combining_builder**
`source_gen|combining_builder` を指定することでbuild_runner を使ったコードジェネレーションを対象に設定を行うことができます（たぶん...）

https://pub.dev/packages/build_config に載っているのでしょうかね？

**generate_for**
 `generate_for` を指定することでコードジェネレーションの対象になるフォルダやファイルを指定することができます。
（パフォーマンスが上がると勝手に思っています。どうなんですか？）

**ignore_for_file**
生成したファイルにlintの無効化の設定を加えることができます。
`type=lint` をつけると全てのlintルールを無視できます。
https://dart.dev/tools/analysis#suppressing-rules-for-a-file

ただし、`type=lint` が二重に指定された場合にlintに警告されるため`duplicate_ignore` も無効化します。

#### json_serializable
**checked: true**
この設定をすることで Json をパースする際に不正な値を検出しExceptionをスローするようになります。

**explicit_to_json: true**
この設定をすることで、モデルがシリアライズ可能なプロパティを持つ際に、そのプロパティも連鎖するようにシリアライズをするようになります。

設定の説明は `JsonSerializable` クラスのドキュメントに記載されています。
https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable-class.html

## linter設定
導入したriverpod_lintを有効化するには`analysis_options.yaml`に以下のように設定する必要があります。
```yaml: analysis_options.yaml
analyzer:
  plugins:
    - custom_lint
```


## おまけ
VSCodeを使っている場合 `fileNesting` の設定を行うとエクスプローラータブが見やすくなります
```json:.vscode/setting.json
{
  "explorer.fileNesting.enabled": true,
  "explorer.fileNesting.patterns": {
    "pubspec.yaml": "pubspec.lock,pubspec_overrides.yaml,.packages,.flutter-plugins,.flutter-plugins-dependencies,.metadata",
    "*.dart": "${capture}.g.dart, ${capture}.freezed.dart,"
  }
}
```