【Flutter】very_good_analysisの導入で修正が必要になった13個の項目

Dart

誰に向けた記事?

– 何らかのlinterは導入してはいるが、今以上厳しくしてみたいなと思っている方
very_good_analysis | Dart Packageを知らない方
very_good_analysis | Dart Packageを知っているがどんな警告が出るのか知りたい方

概要

どうも、@daiki1003です!

先日、あるプロジェクトにvery_good_analysis パッケージを導入してみました。

元々は、pedantic_monoパッケージを使っていたのですが、
もっと厳しいパッケージがあるとのことで導入をしてみました。

個人的には、lintは厳しい方に寄せる方がデメリットよりもメリットの方が優ると考えています。

– 綺麗なコードを書く雰囲気が醸成される
– 割れ窓理論の逆 (なんていうんだろう笑)
– コードに規律が生まれ、レビュアーの負荷が減少する
– 効率的なアプリケーションが作成できる
– (厳しい方から緩い方に寄せるのは、難しくない)

そんな中で、先日very_good_analysisパッケージを見つけました。

本記事では、

very_good_analysisの概要
very_good_analysisの追加
very_good_analysisの追加で対応した13個の項目

について書いていこうと思います。

very_good_analysisの概要

very_good_analysis | Dart Package
Lint rules for Dart and Flutter used internally at Very Good Ventures.

very_good_analysisVery Good Venturesが提供しているパッケージです。
執筆時は、5.1.0が最新です。

Very Good Venturesは多数パッケージを提供しており、信頼性も高いと思います。

Packages of publisher verygood.ventures
Pub is the package manager for the Dart programming language, containing reusable libraries & packages for Flutter and general Dart programs.

最近だとdart_frog辺りが有名でしょうか。

現在ある中で最も厳しいパッケージ?

実は、Flutterlinterって結構種類が存在するのですが、数ある中でもvery_good_analysisは最多の適用数を誇っている様です。

very_good_analysisの追加

pubspec.yaml

いつものように、pubspec.yamlに追加します

very_good_analysis: ^5.1.0

analysis_options.yamlの変更

analysis_options.yamlに以下を追記します。

もし、既存のlinterパッケージがあるなら置換します。

include: package:very_good_analysis/analysis_options.yaml

また、バージョンごとに固定する事も出来ます。

include: package:very_good_analysis/analysis_options.5.1.0.yaml

very_good_analysisの追加で対応した13個の項目

public_member_api_docs

publicなメンバーに対しては、ドキュメントを書きましょうという項目です。

正直に言うと、これに関しては大変すぎたのでignoreさせてもらいました…!
パッケージを除いて、これを守れてるプロジェクトって世にどれくらいあるんだろう。

always_put_required_name_parameters_first

requiredなパラメタを常に先頭に持ってこいという警告です。

// BEFORE
class SomeWidget extends StatelessWidget {
  const SomeWidget({
    super.key,
    required this.value,
  });

  final int value;
}

// AFTER
class SomeWidget extends StatelessWidget {
  const SomeWidget({
    required this.value,
    super.key,
  });

  final int value;
}
// BEFORE
void someMethod({
  int? intValue,
  required String stringValue,
}) { ... }

// AFTER
void someMethod({
  required String stringValue,
  int? intValue,
}) { ... }

prefer_asserts_with_message

assert文を書く時は必ずメッセージを指定せよ、という警告です。

// BEFORE
assert(users.isNotEmpty);

// AFTER
assert(users.isNotEmpty, 'users must not be empty');

avoid_equals_and_hash_code_on_mutable_classes

immutableではないクラスに対して、bool operator ==(Object other)およびint get hashCode
overrideするなよ、という警告です。

// BEFORE
class SomeClass {
  const SomeClass(...);

  @override
  int get hashCode => ...;

  @override
  bool operator ==(Object other) {
    ...
  }
}

// AFTER
@immutable
class SomeClass {
  const SomeClass(...);

  @override
  int get hashCode => ...;

  @override
  bool operator ==(Object other) {
    ...
  }
}

use_if_null_to_convert_nulls_to_bools

nullablebool値の比較時にnull-aware operatorを使用せよ、という警告です。

// BEFORE
bool? isEnabled;
if (isEnabled == true) {
  ...
}

// AFTER
if (isEnabled ?? false) {
  ...
}

missing_whitespace_between_adjacent_strings

一つの文字列を複数行で定義している際に、1行目の最後に改行を入れろ、と言う警告です。

// BEFORE
Text(
  'This is'
  'a pen',
)

// AFTER
Text(
  'This is ' // 空白を追加
  'a pen',
)

なお、日本語ではこの警告は出ない様です。

avoid_escaping_inner_quotes

Dartでは、文字列リテラルの生成の際にsingle quote(')の利用が推奨されています。
なので、I'm a pen.の様な文字列リテラルを生成する時はescapeしていました。
そうではなく、そう言う時だけはdouble quotesを使えよ、という警告です。

// BEFORE
'I\'m a pen.'

// AFTER
"I'm a pen."

leading_newlines_in_multiline_strings

'''を記述した行は必ず改行しろよ、という警告です。

// BEFORE
final someString = '''{
  aaa,
  bbb,
}''';

// AFTER
final someString = '''
{
  aaa,
  bbb,
}''';

unnecessary_raw_strings

文字列リテラルに rを付けることで、raw stringを生成することができます。
でも、必要ない時は普通の文字列を生成してね、という警告です。

// BEFORE
Text(
  r'This is a string',
  style: ...,
),

// AFTER
Text(
  'This is a string',
  style: ...,
),

use_raw_strings

逆に、必要があるときは raw stringにしなさいよ、と言う警告です。

// BEFORE
RegExp('^https://example.com/.*\.(jpg|png)')

// AFTER
RegExp(r'^https://example.com/.*\.(jpg|png)')

always_use_package_import

絶対パスでimportしてね、と言う警告です

// BEFORE
import 'user.dart';

// AFTER
import 'package:sample/user/model/user.dart';

prefer_if_elements_to_conditional_expressions

コンポーネントを表示する際に、二項演算子ではなくif/elseで記述しろ、と言う警告です。

const isLiked = true;

// BEFORE
children: [
  ...
  isLiked ? 
    _LikedComponent() 
    : _NormalComponent(),
  ...
]

// AFTER
children: [
  ...
  if (isLiked)
    _LikedComponent()
  else
    _NormalComponent(),
  ...
]

no_runtimetype_tostring

全てのクラスの親クラスであるObjectにはruntimeTypeと言うプロパティがあります。
これは、現在の型名を表すクラス(Typeクラス)を返してくれるのですが、これに対してtoStringを呼ぶな、と言う警告です。

// BEFORE
42.runTimeType.toString

// AFTER
// 特になし?

最後に

いかがでしたでしょうか?
pedantic_monoも割と厳しめのパッケージなのでflutter_lintsなど、
他のパッケージからの移行の際はもっと多くの警告が出るかもしれませんね。

誰かのお役に立てば。

Twitterフォローお願いします

「次回以降も記事を読んでみたい!」
「この辺分からなかったから質問したい!」

そんな時は、是非Twitter (@daiki1003)Instagram (@ashdik_flutter)のフォローお願いします♪

Twitterコミュニティ参加お願いします

Twitterコミュニティ「Flutter lovers」を開設しました!
参加お待ちしております😁

☕️ Buy me a coffee

また、記事がとても役に立ったと思う人は
コーヒーを奢っていただけると非常に嬉しいです!
@daiki1003

コメント

タイトルとURLをコピーしました