【Flutter】Barrel Fileって使ってる?【登壇しました】

Dart

概要

どうも、@daiki1003です!

先日、YOUTRUST x yumemiのFlutter LT会を主催、登壇して来ました!

本記事では、その時に登壇して発表した内容を軽くまとめつつ補足しつつ記事にしたいと思います。
それでは、行ってみましょー!

Barrel Fileとは?

Barrel Fileは、すんごく簡単に言うとimportをまとめて外部に公開するこんなやつです。

// model.dart
export 'model/attack_on_titan.dart';
export 'model/hunter_hunter.dart';
export 'model/kingdom.dart';
export 'model/one_piece.dart';

そうすると、

import 'model.dart';

とするだけで、4つ全てをimportした時と同様の効果を得られます。

そもそもimportにこだわる必要ある?

あります。

importは、自分はこのファイルに依存していますよ、と言う宣言になります。
これを紐解くことが何につながるのか説明していきます。

ドメイン視点

あるドメインがどのドメインに依存しているのかを確認し、
正しい構造でコーディング出来ているのかの指標になります。

ドメインというのは、あるアプリケーションにおいて関心事のカテゴリだと考えておいてください。
一般的なSNSとかであれば、 feed, message, user, notification, settingなどなどです。
(この粒度は話し始めるとかなり長くなるので割愛します。)

わかりやすくするために少し極端な例を出します。

ユーザ情報を表示するコンポーネントをmessageフォルダ内に置いておいたとします。
そうすると、ユーザ情報を表示する画面では

// user_screen.dart
import 'message/component/user_tile.dart';

の様になってしまいますね。
ユーザの画面を実装するのにmessageimportしている?
ファイルの置き場所が良くないのではないか?

と言う気付きにつながります。

補足説明

僕は、Feature Firstなフォルダ分けを好んで利用しています。
なので、

// user_screen.dart
import 'friend/...';
import 'sns/...';
import 'user/...';

の様に、最初の方をざっと眺めるだけでどのようなドメインに依存しているのかパッと分かる様にもなっています 👍

レイヤー視点

中規模以上のアプリケーションになってくると、ある程度レイヤーを分けてコーディングしていることが多いかと思います。
そんな時に、importに注目すれば、どのレイヤーに依存しているかを確認することができます。

すごく大雑把な例を挙げると、データがUIに依存しているのは良くないとされていますが

// model/user.dart
import 'user/component/...';

userと言うモデルファイルの中でcomponentimportしている?
怪しいぞ?と言う気付きにつながります。

Barrel Fileの作り方

冒頭でも、使った

lib/comic
├── model
    ├── attack_on_titan.dart
    ├── hunter_hunter.dart
    ├── kingdom.dart
     └── one_piece.dart

この様な構成のファイルがあるとします。

lib/comic
├── model
│   ├── attack_on_titan.dart
│   ├── hunter_hunter.dart
│   ├── kingdom.dart
│   └── one_piece.dart
└── model.dart

[フォルダ名].dartとなるようなファイル(今回で言えばmodel.dart)を作成します。

(人によっては、lib/comic/model/内に作る人もいますが、
import 'model/model.dart';となるので個人的にはあまり好みではないです。)

そして、その中身を冒頭で書いたように

// model.dart
export 'model/attack_on_titan.dart';
export 'model/hunter_hunter.dart';
export 'model/kingdom.dart';
export 'model/one_piece.dart';

とします。

利用側

import 'comic/model.dart';

とすれば、4つ全ての内容が利用可能になります。

全部手動で作るの?

正直、手作りは大変です。

なので、

・自前でスクリプトを作成
Extensionを利用する

のどちらかが現実的かなと思います。

スクリプトを作成するなら、

grinder | Dart package
Grinder is a task runner for Dart, helping to define and automate common project workflows.

を使って書くのも良いかもしれません。

Extensionであれば、VSCode限定になってはしまうのですが、

Dart Barrel File Generator - Visual Studio Marketplace
Extension for Visual Studio Code - Visual studio code to generate barrel files for the Dart language.

なんてものも存在します。
調べられてないのですが、Android Studioにも同様のものはあるのではないでしょうか。

短い/少ないが正義ではない

作る際に意識しておきたいことなのですが、importをスッキリさせたいからと言って短くすれば良いわけではありません。
そうなると、極論lib.dartを作れば良いのでは?と言う話になってきますからね笑

二つ以上の階層をまとめようとし始めたら、一度立ち止まって考えてみても良いのかなと個人的には思います。
(ライブラリ提供時とかはまた話は別)

最後に

いかがでしたか。
長すぎるimportimportへの無頓着を生んでしまいます。

用法・要領を守って正しくお使いくださいませ。

誰かのお役に立てば。

Twitterフォローお願いします

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

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

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

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

☕️ Buy me a coffee

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

コメント

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