📝

Flutterプロジェクトでのコード品質改善 - pedantic_monoとdart fixによる段階的リファクタリング

に公開

背景

毎日色んな作業をやってるのに、アウトプット出せないのなんか嫌だなぁと思って、昔は結構書いてたブログを再開しようと思いつつも、自分で全部やるのは腰が重いなぁってことで。
こちら の記事を見つけて、おーーーいいじゃんこれ。ってことで早速自分なりにやってみました。
これから生成AIフルに使ってカスタマイズして毎日投稿したい!!!!って思ってマス。
/blogのサブコマンドは作らずとも、雑に自然言語でいい感じに作ってはくれるので、ベストなやり方は模索中なんですが、続けてみて固まってきたらそれも記事にしようと思います!

概要

Flutterプロジェクトで技術的負債が蓄積していく中、コード品質を一定に保つことは重要な課題です。今回は、まず厳格なリンタールール「pedantic_mono」を導入し、その後dart fixコマンドを活用して段階的にコード品質を改善した事例を紹介します。

技術スタック

  • Flutter 3.19.5+
  • Dart SDK
  • pedantic_mono ^1.24.0(厳格なリンタールールセット)
  • dart fix(Dart標準ツール)
  • analysis_options.yaml

実装内容

1. pedantic_monoの導入

まず最初に、より厳格なコーディング規約を適用するために pedantic_mono パッケージを導入しました。これは、Flutterの標準的なflutter_lintsよりも厳しいルールセットを提供します。

# pubspec.yaml
dev_dependencies:
  flutter_lints: ^2.0.1
  pedantic_mono: ^1.24.0  # 追加
# analysis_options.yaml
# 以前:flutter_lintsを使用
include: package:flutter_lints/flutter.yaml

# 変更後:pedantic_monoを使用
include: package:pedantic_mono/analysis_options.yaml

2. 型安全性の課題と段階的アプローチ

pedantic_mono導入により、323件の型関連の警告が発見されました。これらを一度に修正することは現実的でないため、段階的なアプローチを採用しました。

# analysis_options.yaml
analyzer:
  errors:
    # 型の不一致エラー(111件)
    argument_type_not_assignable: info
    
    # 型推論失敗による警告(76件)
    inference_failure_on_untyped_parameter: info
    
    # 関数戻り値の型推論失敗(67件)
    inference_failure_on_function_return_type: info
    
    # 関数呼び出し時の型推論失敗(42件)
    inference_failure_on_function_invocation: info
    
    # インスタンス生成時の型推論失敗(15件)
    inference_failure_on_instance_creation: info
    
    # raw型使用警告(12件)
    strict_raw_type: info

これにより、エラーレベルを一時的に下げて、段階的に改善していく方針を取りました。

改善対象となる課題の全体像

エラーレベルをinfoに調整した後、改善が必要な課題の全体像は以下の通りです:

順位 ルール名 件数 割合 説明
1 require_trailing_commas 276 17.6% 末尾カンマの追加
2 prefer_single_quotes 222 14.2% シングルクォートの使用
3 use_super_parameters 116 7.4% superパラメータの簡潔記法
4 argument_type_not_assignable 111 7.1% 型の不一致エラー
5 inference_failure_on_untyped_parameter 76 4.9% 型推論失敗(パラメータ)
6 inference_failure_on_function_return_type 67 4.3% 型推論失敗(戻り値)
7 avoid_redundant_argument_values 61 3.9% 冗長な引数値
8 always_put_control_body_on_new_line 60 3.8% 制御文の改行
9 sort_constructors_first 55 3.5% コンストラクタの順序
10 lines_longer_than_80_chars 51 3.3% 80文字を超える行

全45種類のルール、合計1,568件の改善項目があることが判明しました。

この中で、上位3項目(require_trailing_commas、prefer_single_quotes、use_super_parameters)はdart fixで自動修正可能なため、まずはこれらから着手することにしました。

3. flutter analyzeによる静的解析の改善

次に、エラーレベルの問題から着手しました。

# 静的解析の実行
flutter analyze

# エラー/ワーニングの確認と修正
make analyze

4. dart fixによる自動リファクタリング

require_trailing_commas

可読性とgit diffの改善のために末尾カンマを追加しました。

# 末尾カンマの自動追加
dart fix --apply --code=require_trailing_commas

# 結果:22ファイルに41箇所の修正

修正前:

Widget build(BuildContext context) {
  return Container(
    child: Column(
      children: [
        Text('Hello'),
        Text('World')
      ]
    )
  );
}

修正後:

Widget build(BuildContext context) {
  return Container(
    child: Column(
      children: [
        Text('Hello'),
        Text('World'),
      ],
    ),
  );
}

prefer_single_quotes

Dartの慣習に従い、文字列リテラルをシングルクォートに統一しました。

# シングルクォートへの変換
dart fix --apply --code=prefer_single_quotes

# 結果:32ファイルで217箇所の修正

修正前:

headers[HttpHeaders.contentTypeHeader] = "application/json";
final String message = "Hello World";

修正後:

headers[HttpHeaders.contentTypeHeader] = 'application/json';
final String message = 'Hello World';

use_super_parameters

Flutter 3.0以降で推奨されるsuperパラメータの簡潔な記法に移行しました。

# superパラメータの最適化
dart fix --apply --code=use_super_parameters

# 結果:114ファイルで116箇所の修正

修正前:

class MyWidget extends StatelessWidget {
  const MyWidget({Key? key}) : super(key: key);
}

修正後:

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});
}

5. 自動フォーマットの適用

# 全ファイルのフォーマット
dart format .

# 結果:56ファイルが変更され、適切な改行が追加

学んだこと

意外だった落とし穴

  1. pedantic_monoの厳格さ

    • 323件もの型関連の警告が発見され、技術的負債の大きさが可視化された
    • 一度に全て修正するのは現実的でないため、段階的アプローチが必要
  2. エラーレベルの調整の重要性

    • CIを壊さずに厳格なルールを導入するため、一時的にinfoレベルに下げる判断
    • チーム全体の開発速度を維持しながら品質改善を進める
  3. dart fixとdart formatの違い

    • dart fixは構文の修正のみ(カンマ追加など)
    • dart formatは改行やインデントの調整
    • 両方を実行することで完全なコード整形が可能

今後使えそうな知見

  1. 段階的な品質改善プロセス

    # 1. 厳格なリンタールールの導入
    # 2. エラーレベルの調整(info化)
    # 3. 簡単に修正できるルールから適用
    # 4. 型安全性は時間をかけて改善
    
  2. 優先順位の付け方

    • 自動修正可能なもの(trailing commas、quotes)を先に
    • 型関連は影響が大きいため後回し
    • チームの合意を得ながら進める
  3. analysis_options.yamlの活用

    analyzer:
      errors:
        # 一時的にinfoレベルに下げてTODOコメントを残す
        argument_type_not_assignable: info # TODO: 型関連の警告をinfoレベルに下げて出力を抑制
    

もっと良い書き方の発見

  1. ルールの採用基準

    • pedantic_monoは厳格だが、長期的なコード品質向上に有効
    • 段階的導入により、既存の開発フローを妨げない
  2. ドキュメント化の重要性

    • なぜinfoレベルに下げたのか
    • いつまでに改善するのか
    • TODOコメントで意図を明確化
  3. CI/CDへの組み込み

    # GitHub Actionsの例
    - name: Analyze code
      run: flutter analyze
    
    - name: Check formatting
      run: dart format --set-exit-if-changed .
    

終わりに

pedantic_monoの導入により、プロジェクトの技術的負債が可視化されました。323件の型関連警告は一見圧倒的ですが、これを段階的に改善することで:

  1. 型安全性の向上 - ランタイムエラーの削減
  2. コードの可読性向上 - 統一されたコーディングスタイル
  3. 保守性の向上 - 明示的な型情報による理解しやすさ

重要なのは、完璧を求めすぎないことです。段階的アプローチにより、チームの開発速度を維持しながら着実に品質を改善できます。

まずはdart fixで自動修正可能な部分から始め、型安全性は中長期的な課題として取り組むことをお勧めします。皆さんのプロジェクトでも、pedantic_monoの導入を検討してみてはいかがでしょうか。

91works Tech Blog

Discussion