こんにちは、株式会社ラクスで先行技術検証を行っている技術推進課の@t_okkanです。
今回はFlutterの静的解析を紹介します。
FlutterはDartで実装しているため、静的解析もDartの仕組みを利用します。
Dartは静的型付け言語と動的型付け言語のどちらにも対応しているため、型チェックが比較的ゆるいプログラミング言語です。
そのため、静的解析のルールを定めることで型チェックを厳密にしたり、コードのバグを未然に防ぐことが必要になります。
また、ソースコードに強制的に統一されたコーディングスタイルを適用できます。
Flutterの静的解析の仕組みからできることを紹介しています。
Flutterの静的解析の構成要素
Flutterの実装言語であるDartの静的解析はAnalyzerとLinterから構成されます。
Analyzer
Linter
ソースコードがDartのスタイルガイドラインや設定した他のガイドラインに準拠しているかを解析します。
FlutterではこのDartの静的解析の仕組みを利用して、ソースコードの静的解析を行います。
静的解析の導入
Flutterのプロジェクトに静的解析を導入するには、analysis_optins.yaml
ファイルをpubsepc.yaml
ファイルと同じディレクトリに配置します。
./ sample |- android |- ios |- lib | |- main.dart |- analysis_options.yaml ← ファイルを追加 |- pubspec.yaml
Flutterの新規プロジェクトを作成した時に、プロジェクトのルートにanalysis_options.yaml
ファイルを追加することをお勧めします。
analysis_options.yaml
は以下のような実装になります。
include: package:pedantic/analysis_options.yaml analyzer: exclude: [build/**] strong-mode: implicit-casts: false linter: rules: - camel_case_types
analysis_options.yaml
では以下の設定が可能です。
inculde
他の
analysis_options.yaml
ファイルを取り込むことで、定義されている静的解析のルールを取り込む。analyzer
Analyzerや静的解析全体のカスタマイズを設定する。
linter
Linterのルールをカスタマイズを設定する。
それぞれの設定でできることを詳しく説明していきます。
includeの設定
include
にはすでに定義済みの外部のanalysis_options.yaml
ファイルをプロジェクトに取り込むことができます。
これにより静的解析を手軽に導入することができます。
また、analyzer
やlinter
を独自で設定して1から静的解析のルールを構築することも可能ですが、Flutterのプラグインとして定義済みのルールを適用することができます。
主なプラグインには以下のようなものがあります。
effective_dart
Dartを効率的に実装するために定めたルールであるEffective Dartに準拠したLinterのルールを適用できる。
pedantic
Googleが内部で使用している静的解析のルールを取り込むことができる。Flutter SDKを実装するプロジェクトで利用されているルール。Effective Dartよりもより厳密なルールが設定がされている。
それぞれのプラグインのリポジトリのanalysis_options.yaml
から、どのようなルールが設定されているのか確認できます。
静的解析のプラグインを導入する場合は、pubspec.yaml
にプラグインを追加し、analysis_options.yaml
のinclude
にプラグインで定義されているanalysis_options.yaml
を設定します。
例えば、pedantic
を導入する場合は以下のようになります。
- pubspec.yaml
dev_dependencies: flutter_test: sdk: flutter # プラグインを追加 pedantic: ^1.11.0
- analysis_options.yaml
# pedanticのanalysis_options.yamlを設定 include: package:pedantic/analysis_options.yaml
analyzerの設定
analyzer
ではDartの型システムのカスタマイズや、静的解析を適用する範囲の設定などができます。
厳密な型チェックを有効にする
Dartは部分的に動的片付け言語になるため、デフォルトでは暗黙的型変換が有効であったり、比較的ゆるめの型チェックになります。
Dartのデフォルトの型チェックよりも厳密な型チェックが必要な場合は、analyzer
のオプションでstrong-mode
を指定することで有効にできます。strong-mode
では以下のような設定が可能です。
implicit-casts
false
にすることで暗黙的型変換の実装を禁止できます。implicit-dynamic
false
にすることで動的な型宣言で使用するdynamic
型の使用を禁止できます。
analysis_options.yaml
は以下のように設定します。
analyzer: strong-mode: implicit-casts: false implicit-dynamic: false
コンパイル時の型チェックが厳密になり、より堅牢なコードになるので、できるだけ厳密な型チェックは有効にすることをおすすめします。
一部のファイルを解析の対象から除外する
Flutterの実装をしていると、immutableなクラスを自動生成するfreezed
パッケージなどで自動生成されたファイルは、静的解析の対象から除外したい場合があります。
また、一部のファイルを解析から除外したい場合は、analyzer
のオプションのexclude
に除外するファイルを設定できます。
以下にanalysis_options.yaml
の設定の一例を載せておきます。
analyzer: exclude: # ファイルを直接指定 - lib/client.dart # フォルダ内の特定の拡張子を指定 - lib/data/model/*.freezed.dart # フォルダ内の全てのファイルを指定 - test/_data/**
特定のルールをプロジェクトで無効にする
前述した静的解析用のプラグインを導入した際に、特定のルールだけは無効にしたい場合があります。
特定のルールをプロジェクトで無効にするには、analyzer
のオプションのerrors
に設定し、errors
のオプションに無視したいルール名、ignore
を設定すると、プロジェクト全体で指定したルールを無効にできます。
なお、AnalyzerとLinterのどちらのルールも無効にできます。
参考として、以下にanalysis_options.yaml
設定の一例を載せておきます。
analyzer: errors: # ルール名:ignore # Analyzerの無効化:TODO表記を無視する todo: ignore # Linterの無効化 avoid_empty_else: ignore
解析のルールの重要度を変更する
Flutterの静的解析にはinfo
、warning
、error
の3種類の重要度があります。
info
とwarning
:静的解析には失敗しないが、警告されるレベルerror
:違反していると静的解析が失敗するレベル
Flutterの静的解析では、特定の解析ルールの重要度をプロジェクト全体で変更することができます。
例えば、Linterルールはデフォルトでinfo
レベルに設定されていますが、warning
やerror
レベルに引き上げることが可能です。
重要度を変更するにはanalyzer
のerrors
オプションに、変更したいルール名と重要度(info
、warning
、error
)を設定します。
以下に、analysis_options.yaml
設定の一例を載せておきます。
analyzer: errors: # ルール名:重要度(info、warning、error) # Analyzerの変更:returnの省略を警告する missing_return: warning # Linterの変更 prefer_contains: error
linterの設定
プラグインであるpedantic
やeffective_dart
を導入することで、Linterを手軽に設定できましたが、もちろん開発者が個別でLinterをカスタマイズすることも可能です。
カスタマイズする項目をlinter
のrules
に設定します。
Linterで設定できるルールの一覧は、以下で公開されています。
pedantic
とeffective_dart
、Flutterでデフォルトで適用されている設定はそれぞれマークされており、設定されているルールを上書きして無効にすることもできます。
例えば、ローカル変数で型推論を使用するようにします。
omit_local_variable_types
を無効にする場合は、以下のようにfalse
を設定します。
include: package:pedantic/analysis_options.yaml linter: rules: omit_local_variable_types: false
ファイルや特定のコードを静的解析の対象から除外する
analyzer
の設定で、特定のファイルを静的解析の対象から除外することができました。
それに加え、ソースコードの特定の1行だけ特別に静的解析の対象から除外することができます。
また、ファイル内にそのファイルを静的解析の対象から除外する設定ができます。
1行のコードで特定のルールを除外する
特定の1行のコードでルールを除外するにはコードの1行上に
ignore: linterのルール
をコメントアウトで追加します。複数のルールを除外する場合はコンマ区切りで指定します。
// ignore: linterのルール名 // 以下実装例 class Point { int x, y; // ignore: empty_constructor_bodies Point(this.x, this.y) {} // 空のコンストラクタが警告されない }
ファイル内で特定のルールを除外する
ファイル内で特定のルールが適用されないように設定できます。ファイルのどこか(できればパッケージのimportの直下)に
ignore_for_file: linterのルール
をコメントアウトで追加します。複数のルールを除外する場合はコンマ区切りで指定します。
// ignore_for_file: linterのルール名 // 以下実装例 // ignore_for_file: omit_local_variable_types, empty_constructor_bodies class Point { int x, y; Point(this.x, this.y) {} // 空のコンストラクタが警告されない }
静的解析の実行
静的解析を実行する方法には、エディタで実行する方法と、コマンドラインで実行する方法があります。
静的解析の実行については、FlutterのリポジトリのWikiに詳しく記載されていますので、合わせてご確認ください。
エディタで静的解析を有効にする
Flutterの開発に対応しているエディタやIDEを使用している場合、各環境のFlutterとDartの拡張プラグインをインストールしていればプロジェクトのanalysis_options.yaml
を認識して、ファイル保存時などおいて、自動で静的解析を実行します。
各エディタのセットアップ方法は、以下に紹介されています。
手順に沿って拡張プラグインをインストールしてください。
コマンドラインで静的解析を実行する
コマンドラインからでも静的解析を実行できます。
プロジェクトのルートでflutter analyze
を実行します。
$ flutter analyze Analyzing flutter_analyzer... info • Avoid types as parameter names • lib/main.dart:39:16 • avoid_types_as_parameter_names 1 issue found. (ran in 4.2s)
まとめ
Flutterの静的解析についてまとめました。
Lintルールなど設定値が多く、いきなり一つ一つを自分で設定するのハードルが高いかと思います。
ですのでまずは、pedantic
やeffective_dart
などのプラグインを導入することをお勧めします。
また、別の方法としてはFlutterのリポジトリにあるanalysis_options.yamlファイルをコピーする方法もお勧めです。
あとは、Effective Dartをしっかり読み、Flutterの実装を進めて気になることがあれば個別でルールを追加していくと良いかと思います。
そして、ある程度ルールが固まってきたらテンプレート化し、複数のプロジェクトで使いまわせるようになるかと思います。
エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
https://career-recruit.rakus.co.jp/career_engineer/カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.comラクスDevelopers登録フォーム
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com