Flutter FAQ 🇯🇵

よく目にするFlutterに関する疑問への私感

公式ドキュメントにも充実したFAQページがありますが、本記事ではFlutterについてよく目にする疑問について、自分なりの見解を述べていきます。

Flutterの魅力は?

各所で語り尽くされていますし、公式サイトのトップにも載っていますが、次の3点が特に魅力的なポイントです。

flutter.dev より

さらに自分なりに表現すると、次のように思っています。

  • Hot Reload/Restartによって、実装と確認のフィードバックサイクルが極めて速い(ビルドで数十秒以上程度待たされることの多いネイティブ開発環境と比べて)
  • ネイティブアプリと見分けの付かないような高クオリティ・高パフォーマンスなアプリの開発も可能
  • リッチなフルカスタムUIも組みやすい

さらに、Google I/O 2019でもアピールされていたデスクトップ・Webへのクロスプラットフォームアプリの開発も可能になりつつある(まだプレビュー版で現時点でのプロダクション利用は厳しい)のも、今後への期待ポイントです。

Flutterの学習コストは?

個人的には、以下程度に思っています。

  • 簡単なプロトタイプ・ごくシンプルなアプリ: まあまあ簡単
  • ある程度複雑・中規模以上のアプリ: 簡単ではない(iOSネイティブよりも少し習熟しやすいかも?程度)

簡単なプロトタイプ・ごくシンプルなアプリ

簡単なプロトタイプなどが組める程度であれば、以下ができればOKです。

もちろん常にベストな実装をしようとすると単純なアプリでもそう簡単でもないですが、とりあえず動けばOKレベルならあまり難しくないです。

例えば、非エンジニアのデザイナーが高精度なプロトタイピングツールを使う代わりにFlutterで組むことなども、難易度的に充分妥当な選択肢だと思います。

ある程度複雑・中規模以上のアプリ

ある程度複雑・高品質・高パフォーマンスなアプリを組もうとすると、特に状態管理周りにしっかり取り組む必要が出てきます。

学習し始めは、宣言的なUIフレームワークならではの難しさ・奥深さを感じるところだと思います。

公式ドキュメントでも以下などでまあまあ手厚めに説明されています。

Google I/Oでも毎年これに関するセッションがあり、そこからも重要なトピックであることが伺えます。

以下の役目・使い方をきちんと理解して、何らかのパターン(BLoCなど)に落とし込んで使いこなすことが肝です。

  • 更新を伝えられるクラス: ValueNotifier・StreamController・RxDartのObservable など
  • 伝えられた更新をUIに反映するWidget: ValueListenableBuilder・StreamBuilderなど
  • 更新を伝えられるクラスやそれを束ねたものを下位ツリーへ受け渡すWidget: InheritedWidget・providerなど

また、アニメーションも見た目に関係する状態の値をListenableベースで連続的に伝えてリビルドすることでなされているだけ(アニメーションの絡まない通常の画面更新と実質一緒)と捉えられると、一層理解が深まって適切な扱いができるようになるはずです。

このあたりが分かるようになると、複雑な画面も、ロジック・状態と分離されたごくシンプルな疎結合なWidgetの組み合わせで組めるようになってきます。

状態の更新を過不足なく必要なところのみに伝播させられるようになると、次のような良い結果に繋がります。

  • バグの低減(逆にFlutterで複雑なアプリを雑に組むと破綻して収拾つかなくなるはず)
  • UI更新パフォーマンス向上(アニメーションが滑らかになるなど)
  • バッテリー消費減

学習コストは低くは無いがキャッチアップはしやすい

Hot Reload/Restartで試行と学習のフィードバックサイクルを高速に回せるので、Flutterの開発スキルは効率良く身につけやすいと感じています。

また、公式ドキュメントなどが充実していてかつ分かりやすいというのも、キャッチアップのしやすさに関係します。それについては以下の記事で述べました。

特に、Flutter Widget of the Week というWidgetをそれぞれ極めて分かりやすく解説している1本あたり数分の動画が秀逸なので、Flutterに触れる際はどこかのタイミングですべて目を通すことをお勧めします。

ネイティブ知識は必要?

クロスプラットフォームフレームワークでもネイティブ知識は大事と言われることがよくありますが、FlutterはUIが独自描画方式なこともあってネイティブ知識の必要性は低めです。

開発するアプリの要件実現のために必要なものを満たす、Flutterフレームワークの機能およびパッケージが存在しない(あるいは低品質)な場合は、ネイティブロジックを書いた上でそれをFlutterのDartコードから呼び出せるようにプラットフォームチャンネルを使って自分で実装する必要があります。

ただ、GoogleもFlutter開発に力を入れており、世界的にどんどんFlutter人気が高まっていることもあって、大抵のパッケージはすでに存在するので、そのようなシーンはかなり限定的です。僕はこれまでその必要性が生じたことはありません(firebase_storageにプルリクをしてマージされたことがある、ということくらいです)。

というわけで、次の場合に自作する必要があるかも?という程度です。

  • 既存パッケージがあるが、それが機能・品質不足のとき
  • 既存パッケージが無いようなすごくマイナーなネイティブ機能を使いたいとき
  • 最新iOS/Androidネイティブ機能をいち早く使いたいとき

ただ、プロジェクト設定・ビルド周りの知識は、特にiOSについてけっこう必要になってきます。その際は、以下の記事を参照すれば見よう見真似でなんとかなるとも思います。

僕はAndroidネイティブ知識がほぼゼロですが、FlutterにおけるAndroidのプロジェクト設定周りは簡単なので、これまでちょっと調べるだけでどれもすぐ解決できています。

モバイルアプリ開発スキルはあった方が良い

iOS/Androidネイティブ固有知識はそこまで必要ないですが、モバイルアプリ開発に関する諸々のノウハウは活きてくる場面が多いです。なので、現実的にはiOSかAndroidネイティブ開発者がFlutterキャッチアップするのがスムーズな道筋だとは思います。

ただ、「モバイルアプリ開発経験が無くて、いきなりFlutterに手を出すのはありか?」と聞かれたらそれはそれでありだとも思います。学ぶべきことがたくさんあってけっこう大変そうだとは思います(ソフトウェア開発スキル全般似たようなものですが)が、まずiOSかAndroidのネイティブ開発スキルを身につけてからにすべきとはまったく思いません。iOS/Androidネイティブ開発経験ゼロでもFlutterに興味あったらまずFlutterから入っても大きな問題は無く、必要になったタイミングで少しずつ学んでいけば良いと思います。

Dartってどうなの?

個人的にこれまでで一番気に入っている言語であったSwiftと比べると、第一印象としてはけっこうネガティブに思う部分もありましたが、今ではけっこう気に入っています。言語仕様単体での評価というより、トータルの開発体験(補完・ビルドの速さ、標準パッケージの充実度・使いやすさ、など)としてかなり満足度高いです。

どの言語で作っても問題無い系のCLIツールを作る場合にどの言語で書くか選ぶ際、今ならDartで書こうかなと思うくらいの書き味の良さを感じています。

いわゆるnull安全でない(解決に向けて実装中)

とはいえ、気になる点もいくつかあって、その1つはnullableかどうかが型で区別できない(SwiftのOptional相当のものがない)ことです。

実際、Flutterアプリを書いていてこれに関するミスをよくします。ミスに気づいたらHot Reload/Restartでささっと直せるので開発スピード低下要因にはあまりなっていないですが、例えば開発中にnullの場合の考慮抜けに気付けずバグを仕込んだままリリースしてしまうことなどもあり得えます。なので、やはりnullの可能性が明示されてその場合の処理を強制されるような仕組みはあると嬉しいです。

そして、これについては実装中ステータスとなっていて対応が着々と進んでいます。Dartではこれを non-null by default(NNBD) と呼んでいます。

必要な要件や考慮事項が多く、すぐリリースというわけにはいかないでしょうが、そう遠くない将来リリースされると期待して待っています。

また、同じく要望が多く現在実装中のものとして、Static Extension Methods(いわゆる拡張メソッド)対応があります。

その他気になる点

また、よく不満の声があがるものとして、行末セミコロンが必須なことが挙げられます。特に、セミコロン不要のSwift・Kotlinでのネイティブアプリ開発者がFlutterでDartに触れた時に、「今さらセミコロン書くの面倒だし冗長」などと感じられることが多いのかと思います。これは熱心な議論がありつつも、変更対応の困難さなどから残念ながらペンディング状態となっています。個人的には、セミコロン書くことは単体ではそこまで嫌ではないものの、不要な言語と交互に書くときなどに煩わしさを感じるので不要になると嬉しいです。しかし、多大な労力を費やしてまで不要にしてほしいかと言われると微妙な気もしています🤔

その他、言語仕様の面から見て、普段Swiftなど書いている人から気になりそうな点は以下です。それまで慣れ親しんでいた言語で当たり前に使っている機能が無いと不便に思ったりもしますが、僕はこういうもんだと納得しながらDartに付き合っています。

  • enumの表現力が低い
  • クラス定義のネストができない
  • パターンマッチングが無い
  • 型を前方に宣言する(Swift・TypeScriptなどは後方)

Dartの良い点

他言語利用者から見て気になりがちな点を先に書きましたが、Dartの良い点もたくさんあります。前述の通り、僕はトータルでとても高く評価しています。

  • async/await(いわゆるPromiseと似た非同期型のFuturesの結果を同期的に取得できる構文)が言語機能に組み込まれている
  • Streams(Rxの簡易版みたいなもので複雑な非同期処理には別途rxdartパッケージ併用が必要)が標準パッケージに含まれていて、Futuresとの相互変換もスムーズにできる
  • Cascade notation(.. )によって、あらゆる既存メソッド・プロパティなどをメソッドチェーン的に扱える
  • dartfmt が言語とセットになっていて、書き方を簡単に揃えられる(analysis_options.yamlによって細かいカスタマイズも可能)
  • 標準パッケージが充実していて、野良パッケージが必要な場面が少ない

また、Mixinも備わっていて、けっこう気に入って使っています。SwiftのProtocol Extensionなどと似ていますが、機能的にはフィールド(格納型プロパティ)を持てることが大きな違いです。

Dartの学習コストは?

Swift・Kotlin・C#・Java・TypeScriptなど、メジャーな静的型付け言語のどれが1つでも書ければ、ほとんど勉強せずとも勘で読み書きできるレベルだと思います。

最近リニューアルされた公式ドキュメントもよくまとまっています。

とりあえずざっと学びたい場合はこちらのページがおすすめです。

お行儀よく書きたい場合はEffective Dartです。

また解きながら学べるページもあって学習しやすいです。

そもそもなぜDart?

こちらによくまとまっています。端的に言うと単純に最も相性が良く、現在のFlutterの魅力はDartのおかげとも言えます。

また、Google I/O 2019ではDartセッションがあり、Flutterと絡めながらアピールされていました。上述のNNBDと拡張メソッドについての話もありました。

デザインはやっぱりマテリアルデザイン?

Flutterではマテリアルデザインに関するWidgetがほぼ網羅されていて、マテリアルデザインベースで組むと効率が良いのは確かです。質・量ともに充分なものが揃っていて、機能不足やバグで悩むことは稀なはずです。

ただ、iOS用のWidgetもけっこう充実してきて、iOSっぽいアプリもあまり苦労なく組めます。

また、基本的なWidgetを自由に組み合わせて、フルカスタムUIを組むこともできますし、あるいは画面によってこれらを色々組み合わせるのももちろん自由です。

Flutterでは、どういうデザインにするにしても、自由度高く効率良く組めます。ただ、クロスプラットフォームでより効率良くUI実装したいのであれば、マテリアルデザインに寄り添うのが得策です。

例えば、「Android上ではマテリアルデザインで、iOS上ではiOSっぽいデザインにしたい」というのはよくある要望だと思います。Flutterではそれも比較的効率良く組めますが、とはいえその都度別デザインを組んでUIを出し分けしてさらにその確認を継続的に行っていくというのはかなりのコスト増につながります。なので、プラットフォームごとにUIを変える場合はメリットがその決して軽くないコスト増に見合うかをきちんと検討して覚悟を持った上で行うべきです。

また、仮にその余力があったとして、例えばさらにAndroid 9.0 Pieで搭載されiOS 13でも搭載されると噂されているダークモード対応(Flutterでも対応済み)などもやろうとなると確認バリエーションがどんどん増えていってしまいます。そのあたりをどう取捨選択していくかの判断が大事だと思います。

ちなみに、Google I/O 2019のマテリアルデザインやiOSセッションでも同様の話題に触れられていました。

マテリアルデザインだとアプリの個性を出しにくいのでは?

マテリアルデザインには、Material Themingといって色や形状のアレンジなどカスタマイズポイントが豊富に用意されています。これをきちんと活用すればアプリの個性はしっかりと出せます。また、メイン画面はフルカスタムUIにするなど色々工夫の余地はあります。

というわけで、まとめると次のようになります。

  • マテリアルデザインに統一が効率良い
  • プラットフォームごとにUIを変える場合はそのコスト増に見合うかしっかりと判断してから
  • Material Theming活用や一部フルカスタムUIとすることなどでアプリの個性は充分出せる

既存アプリとの組み合わせはできる?

Flutterは、既存ネイティブアプリに部分導入することも可能です。ただし、プレビュー版の機能です。

また個人的には組み合わせた際のメリットが、その繋ぎ合わせ部分の厄介ごとによるデメリットをペイするか微妙に思っていて、まだ試したこともないです。

ただ、うまくいってそうな事例もあり、ちゃんと取り組めば良い手段の1つかもしれません。特に、大きなネイティブコードベースを持ち、ゼロからの作り直しが容易でない場合はある程度コストかけてでもハイブリッド構成にする価値がありそうです。

また逆に、「Flutterアプリメインで、一部ネイティブの方が向いている要件についてはネイティブ画面で処理させる」というのは何の問題もなくできます。 image_picker プラグイン ではネイティブの写真ピッカー画面を表示したり、各所で当たり前のようになされているやり方です。

FlutterアプリにネイティブUIを部分的に埋め込める?

ネイティブUIにフルスクリーンで遷移させて一部のタスクを任せるのは上述の通り普通にできますが、さらにFlutterアプリにネイティブUIを部分的に埋め込むことも可能です(ただしまだプレビュー機能です)。昨年末のFlutter Live で目玉のアップデートの1つとして紹介されたものです。

次のようにFlutter UIの一要素としてネイティブのGoogle MapsやWebビューを埋め込む用途が意図されています。これができるとUI上の制約がかなり減りますね。

Flutter 1.0: Google のポータブル UI ツールキット より

これを利用して、ARKitやARCoreをFlutterで利用する開発者も出てきています(公式対応のIssueもありますが)。

ただ、この機能はプレビュー版であってまだ動作が完全ではなく、さらにこの機能を有効化すると他の部分にも悪影響を及ぼすことがいくつか報告されています(こちらのIssueなど)。デフォルトは無効になっていますが、プレビュー版の間に有効化したアプリをリリースする際はそのあたりのリスクを入念にチェックした方が良いです。

Firebaseは使える?

バッチリ使えます 👌 同じGoogleが開発しているだけあって、ネイティブSDKをラップした高品質な公式プラグインがほぼフル機能で揃っています。

FlutterFire という名前でこのように一覧されています。

FlutterFire より(2019/05/27時点でのスクショ)

ただ、必ずしもすべての機能が使えるわけではなく、最新機能への追従はワンテンポ遅れる場合があります。もしどうしてもすぐに未対応の最新機能を使いたい場合は、その部分だけ自前で書いてしのぐ(あるいはそういうことをしている非公式プラグインを見つけてくる)ということもできます。

また、冒頭で軽く触れたデスクトップアプリやfor webでは現状使えないはずです(がんばれば使えるかもしれませんが、とても苦労するはずです)。
iOS SDKはmacOSでも動く ので、将来的には特定の環境のデスクトップでも使えるようになるかなと思っています。for webも同様にWeb版のSDK をラップしたものが提供されて使えるようにならないかなと期待しています。

アプリ内課金はできる?

Google I/O 2019でFlutter 1.5のアナウンスがなされましたが、その目玉のアップデートの1つがアプリ内課金対応の公式パッケージ(in_app_purchase)でした。

the most requested new feature in Flutter 1.5 is the In-App Purchase plugin, which is now available in beta for Android and iOS.
Announcing Flutter 1.5 — Flutter — Medium

これまでも非公式のアプリ内課金パッケージはありましたし、もちろん自分でその処理を書くことでどうとでもできましたが、公式パッケージが用意されたというのはとても安心感あります。

というわけで、回答としては以前からできたが、1.5で公式パッケージが提供されたので、より簡単かつ安心して対応できるようになった、ということです。個人的には近いうちに今開発中のアプリで使ってみる予定なので、楽しみです。

リリース済みのアプリに対しての動的なアップデート(Code Push)はできる?

Flutterはjust in time(JIT)コンパイルでも動くので、Code Push対応との相性は良く技術的には可能ですが、現在未対応で、また対応予定もペンディング状態です。

また、仮に対応されても、App Store上のiOSアプリに対して実際に行うとガイドライン違反になるのではと議論されています。ただ、おそらくAndroidアプリのGoogle Playでは問題なさそうなのと、ストア以外の方法で配布してそれに対してアップデートかけたいという要望が海外ではけっこうあったりするようで、この対応を切望しているFlutterユーザーもけっこういるようです。

本物のネイティブアプリと比べて実際どう?

Flutterは独自描画方式で、ネイティブUIコンポーネントは使っていないため、それと100%一致する触り心地を提供するのは原理的にとても難しいです。(特にiOSの場合)本物のネイティブアプリとは違うものになってしまうことは否めないです。

ただ、それはあくまでネイティブと100%一致するかどうかという観点であって、一般ユーザーが違和感を持つかどうかはまた別問題です。個人的には、Flutterで一般ユーザーがネイティブアプリと区別付かない程度のアプリを作ることは十分可能だと思っています。むしろ、Flutterの生産性の高さ故に、同じ時間でネイティブアプリ以上のユーザー体験を提供することもできるとも思っています。

「(特にiOSの場合)」と書いたのは、同じGoogleがAndroidもFlutterも開発しているため、AndroidネイティブアプリのフィールをFlutterで再現しやすいからです。実際、僕はネイティブAndroidアプリとFlutterアプリを判別することができません(iOSではある程度判別できます)。このあたり、以下にも詳しく触れました。

そもそもクロスプラットフォームフレームワーク全般に良い印象が無いのだけど?

一見良いことばかりのように見えるクロスプラットフォームフレームワークに無闇に飛びつかずに疑ってかかるのは良いことだと思いますし、僕もそのスタンスです。逆に、噂や過去の一部の事例を元に思考停止して全否定するのも避けるべきだと考えています。

過去のクロスプラットフォームフレームワーク全般すべてが失敗しているわけではなく、十分うまくいっているのもありますし、僕は入念な探求をした上でFlutterはとても筋が良いと評価して安心して使っています。

その他ネイティブに比べて不利な点教えて

以下、Flutterの原理的に厳しそうなものや単純に現時点で未対応ゆえの制約を紹介していきます。Issue詳細の 👍 の数が優先度に加味されるので、早く解決してほしいものがあればどんどん押していきましょう 👍

UIの関係するようなネイティブ機能が活用できないことが多い

例えば、パスワード自動補完機能が使えませんし、こういうUIの細かいところに追従するのはやや難しめだと思います。

What Flutter Can’t Do: Limitations より

同様に、iOSの3D Touchのpeek/pop対応も、ネイティブUIが密接に絡むので難しそうです。圧力検知は問題なくできるので、似たUIをFlutter側で提供することになる気がします🤔

Take Advantage of 3D Touch — Apple より

一方、同じ3D Touchでもクイックアクションは公式パッケージが提供されています。これはクイックアクションはアプリの外でなされ、アプリ側はどのアクションが選択されたかの情報をもとに適切なハンドリングをするだけで済むからです。

アプリサイズが少し大きくなる

How big is the Flutter engine? に2018年12月時点での最小限のアプリの計測結果が載っています(同じアプリがネイティブでどうなるかは不明です)。

日本は通信状況が良く、中規模以上のアプリだと数十MB〜百MB超くらいが当たり前なので、こういうちょっとした上乗せがあっても許容できることがほとんどだと思います。通信状況が悪く少しでもアプリサイズを下げることがインストール増に繋がるような国では多少ネックになってくるかもしれません。

iOSのBitcode非対応なので、その有効化が必須なwatchOS/tvOS対応が不可能になる

これはけっこう大きなネックだと思っています。FlutterでwatchOS/tvOSアプリが作れないということではなく、FlutterでiOSアプリを組んだ場合、そこにネイティブのwatchOSアプリを足せなくなってしまうということです。

パフォーマンス

大抵のアプリでは問題にならない程度には高速にロジックの処理およびヌルヌルUI更新もできるFlutterですが、やはりネイティブに比べると少しだけ遅いです。

なので、パフォーマンス最優先のアプリでは不向きです。

ただし、現実的にはそこまで常に最高のパフォーマンスが必要なアプリはとても稀であり、必要な時にプラットフォームチャンネルでネイティブに任せたり、あるいはIsolateで別スレッド活用したりで済むことが大半だと思います。


ここから、すでにFlutterを触り始めたあたりの方対象の内容となります。では、引き続きつらつらと書いていきます(現時点で2項目ですが何か思いついたら足します)。

Widgetのネストが深くなるのがネックでは?

FlutterのWidgetのネストが深くなりがち問題をよく聞きますが、「問題」と呼ぶのは少し不適切な気がしています。

まず、FlutterにおいてWidgetのネストが深くなっても、「ネストが深くなってそれに応じて可読性・メンテナンス性が少しずつ下がっていく」以外の実害はまったくありません。XML・HTMLなどでタグのネストが深くなっているのとほぼ同等の状態です。

次のスクショは、iOSアプリのUI定義ファイル(xibファイル)ですが、このようにそもそもUI定義にはネストが付きまとうことが多く、Flutterならではの問題ではありません(あらゆるUI定義をWidgetのネストで表現していくのでネストが比較的増えやすい面もありますが)。

Flutterの場合、Dartコードですべて記述する故に、連続した if 文や非同期処理のコールバック地獄などでネストが深くなってロジックの複雑性が増してしまうのと似たような感覚で捉えてしまっているように見受けられることがありますが、それとは全くの別物です。

「ネストが深くなってそれに応じて可読性・メンテナンス性が少しずつ下がっていく」以外の実害はまったくありません。

ある程度までWidgetのネストが重なることは問題ありませんが、とはいえその数が多くなっていくとやはり扱いにくくなっていきます。XMLなどでUIを定義する場合も複雑なビューコンポーネントを切り出して単純化していきますが、Fluterでも同様のことをやれば良いだけです。さらに、FlutterはコードでUIを表現しているが故にその切り出し作業がとてもやりやすいです。また、上述の通り、ロジック的に複雑性が増しているわけではないので、ほとんど機械的にリファクタリングできることもポイントです。ロジックが複雑に絡み合っているような複雑性を解消する場合は安全にリファクタリングするためには高い対応コストがかかりますが、FlutterのWidgetのネストが深い状態は基本的にそれとは違います。

そのため、まずは適当にベタ書きして、あとで適宜リファクタリングしてネストを減らして今後弄りやすくする、というのもありで、僕もそういう書き方をすることがよくあります。

ネスト解消は、具体的には次のように行います。

  • (プライベート)メソッドに切り出し( _buildXxx(...) という命名がオススメ)
  • 別Widgetに分ける
  • ロジックを分ける(メソッドに分けるのが簡単だが、ロジック処理を担うクラスに移譲するのがベター)

ネスト解消観点では、メソッドに切り出しと別Widgetに分けるのは同等ですが、次のような場合は別Widgetに切り出すのが良いです。

  • 共通的に使うWidget
  • const のWidgetにすることでリビルドを減らしてパフォーマンス向上をはかりたい

後者については以下の記事に詳しく書いたのでご覧ください。

メソッド切り出しの方が簡単で小回りが利きやすいので、それで済む場合はそれで良いと思います。

Android StudioではFlutter Outlineにてbuildメソッドなどの構造を把握できますが、僕は比較的複雑な画面でも以下の例程度に収まるようにしています。
(上述の通り実装中はネストがもっと深くなることもありますが、仕上げの作業後にこの程度まですっきりさせるようにしています。)

buildコードとそのアウトライン

Flutterのchannelはどれがオススメ?

Flutterは開発者が任意のchannelを選んで開発を進めることが可能です。

以下の4種類あります。

  • master: 最新・不安定
  • dev: テスト済みの最新バージョンが出来次第流れてくる
  • beta: 毎月devから最良の状態のものへ追従(Bad-Builds が流れてこないようにケアされている)
  • stable: 四半期ごと目安くらいに安定版がリリースされる

通常はstableを選択するのが良いです。まだリリース前のアプリなどで最新版をなるべく早くガシガシ使っていきたいという場合は dev などもありで、僕もそれを選ぶことがちょくちょくあります。ただ、バグがあった時に自分たちのミスなのか最新channelゆえの不具合なのか分かりにくくなるなど弊害もあるので、やはりstableが常に無難な選択肢ではあります。

巷のパッケージも、stableに従うようなポリシーのものが多く、例えばFlutterに破壊的変更があってstableとdevなどで動くコードに差が出る際はstableが優先されることが多いはずです。きちんとメンテナンスされているパッケージでも、devを使っている場合、取り急ぎforkして自分でささっと対応するなどの面倒ごとが増えたりします。


長くなりましたが以上です。適宜追記していったり、長くなったトピックは別記事として切り出したりしながら更新していこうと思っています。