🐙

Flutter開発を加速するVSCodeスニペットの使い方

2021/12/13に公開

Flutter開発でよく使うFreezedの記述を大変ですよね?
VSCodeのスニペット機能を使えばdartファイル名に対応するFreezed用クラスを一瞬で作れます。これを気にFlutter開発を加速するオリジナルスニペットをつくてみませんか?

個人スニペット

まずは自分だけに反映される個人スニペットの書き方です。

スニペットファイルを開く

  • 設定マーク、User Snippetsの順で選択します。

  • dart.jsonを選択すると個人用スニペットのファイルが開きます。

State用のスニペット

StateNotifierのStateなどに使う想定です。

スニペット

dart.jsonに以下のJsonを追記します。

dart.json
{
    "State用Freezed": {
        "body": [
            "// 保存時の自動整形でfoundationが消えないように警告を消している",
            "// ignore: unused_import, directives_ordering",
            "import 'package:flutter/foundation.dart';",
            "import 'package:freezed_annotation/freezed_annotation.dart';",
            "",
            "part '$TM_FILENAME_BASE.freezed.dart';",
            "",
            "@freezed",
            "class ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/g}} with _$${1} {",
            "  const factory ${1}({",
            "    required ${2:String id},",
            "  }) = _${1};",
            "}"
        ],
        "prefix": [
            "freezedstate",
            "statefreezed"
        ],
        "description": "Freezed State"
    },
}

一部解説

  1. // ignore: unused_import, directives_orderingは保存時のimport修正でfoundationのimportが消えないようにしてます。devtoolでの表示が綺麗になるものですが、なくても問題無いです。(自分は入れといて損はないだろくらいで入れてます)
  2. TM_FILENAME_BASEでファイル名からpartを埋めます
  3. {1:{TM_FILENAME_BASE/(.*)/${1:/pascalcase}/g}}でファイル名をパスカルケースに変換してクラス名を自動で決めてます。

使用例

hoge_state.dartというファイルでfreezedstateと入力すると以下のようになります。

hoge_state.dart
// 保存時の自動整形でfoundationが消えないように警告を消している
// ignore: unused_import, directives_ordering
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'hoge_state.freezed.dart';


class HogeState with _$HogeState {
  const factory HogeState({
    required String id,
  }) = _HogeState;
}

Json変換用のスニペット

APIから受け取るJsonのパースなどに使う想定です。

スニペット

dart.jsonに以下のJsonを追記します。

dart.json
{
    "Json用Freezed": {
        "body": [
            "// 保存時の自動整形でfoundationが消えないように警告を消している",
            "// ignore: unused_import, directives_ordering",
            "import 'package:flutter/foundation.dart';",
            "import 'package:freezed_annotation/freezed_annotation.dart';",
            "",
            "part '$TM_FILENAME_BASE.freezed.dart';",
            "part '$TM_FILENAME_BASE.g.dart';",
            "",
            "@freezed",
            "class ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/g}} with _$${1} {",
            "  const factory ${1}({",
            "    required ${2:String id},",
            "  }) = _${1};",
            "  ",
            "  factory ${1}.fromJson(Map<String, dynamic> json) => _$${1}FromJson(json);",
            "}"
        ],
        "prefix": [
            "freezedjson",
            "jsonfreezed"
        ],
        "description": "Freezed Json"
    },
}

使用例

hoge_entity.dartというファイルでfreezedjsonと入力すると以下のようになります。

hoge_entity.dart
// 保存時の自動整形でfoundationが消えないように警告を消している
// ignore: unused_import, directives_ordering
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'hoge_entity.freezed.dart';
part 'hoge_entity.g.dart';


class HogeEntity with _$HogeEntity {
  const factory HogeEntity({
    required String id,
  }) = _HogeEntity;
  
  factory HogeEntity.fromJson(Map<String, dynamic> json) => _$HogeEntityFromJson(json);
}

プロジェクト用スニペット

先ほどまでは個人用のスニペットでしたが、.vscodeディレクトリにスニペットファイルを作ることで、チームメンバーとスニペットを共有することもできます。
基本的な書き方は同じで、スニペットを書くファイルが異なります。

スニペット

プロジェクト直下の.vscodeディレクトリに、[適当な名前].code-snippetsを作り以下のJsonを追記します。

.vscode/freezed.code-snippets
{
    "State用Freezed": {
        "body": [
            "// 保存時の自動整形でfoundationが消えないように警告を消している",
            "// ignore: unused_import, directives_ordering",
            "import 'package:flutter/foundation.dart';",
            "import 'package:freezed_annotation/freezed_annotation.dart';",
            "",
            "part '$TM_FILENAME_BASE.freezed.dart';",
            "",
            "@freezed",
            "class ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/g}} with _$${1} {",
            "  const factory ${1}({",
            "    required ${2:String id},",
            "  }) = _${1};",
            "}"
        ],
        "prefix": [
            "freezedstate",
            "statefreezed"
        ],
        "description": "Freezed State",
        "scope": "dart"
    },
}

スニペットそのものの違いは、scopeが追加されたことです。

最後に

同じ要領でファイル名からすぐに対応するクラス名のStatelessWidgetを作るスニペットなども作れるので、Flutter開発を効率化しましょう👍

紹介

複数のファイルを同時に生成したり、ディレクトリを作成したりなど、もっと大きなテンプレートが欲しい時はmasonもおすすめです🧱
https://zenn.dev/toridori/articles/859aa1999ece9a

拡張機能

スニペットは自分で書く他に拡張機能をインストールすることでも使えます。
Riverpod用のスニペットが使えるようになる拡張機能なんかがあります。

https://marketplace.visualstudio.com/items?itemName=robert-brunhage.flutter-riverpod-snippets

GitHubで編集を提案

Discussion