今さらでもないのでFlutter for webを始めよう

この記事は、Goodpatch Advent Calendar 2019 6日目の記事です。

はじめに

今年はFlutterに注目して、個人的に情報を追っていた1年でした。
もう個人開発のモバイルアプリはFlutterでいいじゃんと思っている私です。 そんなFlutterですが、Google I/O 2019では昨年末からアナウンスされていたWebサポートが正式発表されました。 発表当初はTechnical Previewであったこともあり、本家Flutterとはパッケージが別れていたり、開発環境の構築も若干難があったりしましたね。
それから半年ほどが経ち、Flutter for webにも様々な改善が行われています。 今回は、発表当時試してみたけどしばらく追っていなかった方や、これから触ってみたい方に向けて、環境構築からリリースなど一通りの手順を解説してみたいと思います。

Flutter for webとは

2019年現在のFlutterは、iOS/Androidアプリを主なターゲットとしたクロスプラットフォームで開発可能なアプリケーションのフレームワークです。複数のプラットフォーム用アプリを単一のコードベースで開発することが出来ます。
モダンなUIフレームワークや充実した開発ツールが提供されていて、Firebaseを始めとしたプラグインも充実しているため、比較的容易に開発を始めることが可能です。 Flutter for webは、そんなFlutterをWebブラウザで実行可能にしたものです。
現在もTechnical Previewの段階にあり、製品向けへの利用は推奨されていません。 Webサポートに関する詳細な説明は本記事では割愛しますが、仕組みを知る上では次の公式ドキュメントが助けになるかと思います。
Web support for Flutter – Flutter

環境構築

さっそく公式ガイドを見ながら環境構築を始めます。
Building a web application with Flutter – Flutter

Flutter SDKのダウンロード

現在のところ、Webサポートの入ったSDKを利用するには、masterかdevチャンネルを利用する必要があります。 もしも既にflutter SDKを利用していれば、次のコマンドでSDKのチャンネルを切り替えます。
$ flutter channel dev
$ flutter upgrade  
まだSDKをインストールしていない場合は、Install – Flutter を参照して、各実行環境のSDKをインストールしましょう。
インストール直後は、stableチャンネルに設定されています。Webサポートを利用するため、先に紹介したコマンドでチャンネルを切り替えます。 余談ですが、Flutterではこの他にもいくつかのリリースチャンネルが運用されています。私は普段の開発ではbeta環境を使用しています。ある程度の新しい機能と安定性のバランスが取れていることが多いと感じているためです。

Webサポートを有効にする

Webサポートを有効にするには、次のコマンドを利用します。
$ flutter config —-enable-web
このコマンドは一度しか実行する必要はありません。
コマンドを実行すると、~/.flutter_settingsが生成されます。
{
    “enable-web”: true
}
Webサポートが有効になっていれば、flutter devicesを実行することで接続済みデバイスとして次のような結果が出力されます。
$ flutter devices
2 connected devices:

Chrome     • chrome     • web-javascript • Google Chrome 78.0.3904.108
Web Server • web-server • web-javascript • Flutter Tools
また、flutter doctorを利用することでもWebサポートが有効になっていることが確認できます。
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel dev, v1.12.15, on Mac OS X 10.15.1 19B88, locale ja-JP)
…
[✓] Chrome - develop for the web
…
[✓] Connected device (2 available)

! Doctor found issues in 2 categories.
IDE上のDeviceリストにもChromeが追加されましたね。(画像はVSCodeのもの)
device list

既存プロジェクトへのWebサポートの追加

既存のプロジェクトにWebサポートを追加するには、プロジェクトのトップディレクトリで次のコマンドを実行するだけです。
$ flutter create .
Createコマンドは既存のプロジェクトファイルを置き換えることはせず、不足しているファイル群だけを生成します。
実際に既存のプロジェクトで実行すると、web/index.htmlが新たに生成されました。
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>taptaptap2</title>
</head>
<body>
  <script src=“main.dart.js” type=“application/javascript”></script>
</body>
</html>
なお、初期生成状態から削除したり、名前を変えてしまったファイルが存在する場合、不要なファイルが生成されることもあるため、gitなどのコード管理ツールとの併用をおすすめします。

Webサポートを含めた新規アプリを作成する

新規に作成する場合のやり方は、Webサポートがなかった時と変わりません。次のコマンドを実行することでiOS/Android/Webに対応したFlutterプロジェクトが生成されます。
$ flutter create myapp

Webアプリを実行する

Webアプリを実行するには、次のコマンドを実行します。
$ flutter run -d chrome
ホットリスタートするには、rを入力します。
合わせてブラウザのリロードを行う場合は、Rを入力します。 先程確認したように、IDE上からの実行にも対応しています。
例えばVSCodeであれば、モバイルアプリを実行するときと同様に、deviceリストからChromeを選択した上で、F5キーを選択することでデバッグモードでの実行が可能になります。
VSCode
無事に実行することができれば、次のようにサンプルアプリがChromeで表示されます。
Chromeで実行

リリースビルドの生成

リリースビルドを生成するには、次のコマンドを実行します。
$ flutter build web
リリースビルドには、dart2js | Dartが利用されます。dart2jsを利用したビルドを行うには、上記のbuildコマンドのほかに、flutter run --release -d chromeでも可能です。 アウトプットファイルは、 build/webに生成されます。
このディレクトリをサーバーに配置することで、Webアプリの公開が可能です。
Github PagesやFirebase Hostingなどの各種ホスティングサービスも利用することができます。

サンプル

私が以前作成したアプリもWebサポートしたものをGitHub Pagesに置いてみました。
iframeで埋め込んでも問題なく動いていますね。
https://ymegane.github.io/TapTapTap2/ また、こちらで実際にFlutter for webを利用したサンプルを見ることができます。

サンプルのその後

Flutterで開発する準備が一通り揃ったあとは、是非豊富に用意されたFlutterのWidgetとUIフレームワークを試してみましょう。
Flutterは、公式のドキュメントやCodelabsが充実しているため、こちらに沿って一通り試してみるだけでも、基本的な開発手法について学んでいくことが可能です。 また、日本語の記事としては、@monoさんが執筆されている記事が大変充実しています。
私も一年を通して大変お世話になりました。

おまけ : Pluginなど

本家Flutterと統合されたことで、プラットフォームに依存しないDartパッケージであれば、基本的には利用可能です。
また、既存のモバイル向けPluginに対しても、Webサポートが追加される動きも出てきました。
ブラウザでも代替可能な機能については、今後Webサポートも増えていくかもしれませんね。 このあたりは追いきれていない部分もあるので、引き続き眺めていきたいところです。
Flutterで利用できるPluginは、Flutter packagesとしてリストされていてWebからも検索することができます。

おわりに

繰り返すようですが、現在のところFlutterのWebサポートはTechnical Previewであることは変わりません。
しかし、現在の状態でもFlutterの開発体験やドキュメントの充実度をそのままWebアプリケーション開発にも持ち込めるのは非常に魅力的に映ります。

2020年もさらに広がっていきそうなFlutterの世界が楽しみです。

最近やっていること: Flutter日記

こんにちは。2018年は一度も更新がなく気づくと2019年。早いですね。うらぴこさん元気ですか。

最近は、FlutterというiOS/Android向けにアプリを作ることが出来るフレームワークに興味がありましてちょこちょこと触っています。

https://flutter.dev/

これは練習で書いているおもちゃアプリ: https://github.com/ymegane/TapTapTap2

(タップやドラッグしたところに円が出てさーっと消えていくだけのアプリなんだけど、
基本的な画面の作りや座標系、非同期処理、アニメーションまで実現しないと実は書けないので、練習で書くのに割と適してるんですよ : )

FlutterはGoogleが提供していて、Fuchsiaという次期モバイルOSなんだかいつものGoogle社内競争の産物なのかわからない謎の新OS向けアプリケーションのSDKとしても知られていて、もしも今後Fuchsiaがメジャーになることがあれば大勝利かもしれません。

FlutterはDart言語で開発するんですが、これも既存の経験がある言語に比べて独特というわけでもなく、すんなり書き始めることができています。

https://www.dartlang.org/guides/language/language-tour


さらに開発環境もSDKとVSCodeとVSCode PluginがあればOKというお手軽さ。
FormatterやLinter、TestSuiteからパッケージ管理、パフォーマンス系のデバッグツールまで一通り揃っていて、さすがGoogleやでという感じです。(一部はDartのエコシステムです)

難点は、宣言的に記述するUIのうち、PaddingやOpacityなんかもView(FlutterではWidget)のプロパティではなく一つのWidgetとして宣言する必要がある点でしょう。

これはつまりどんなWidgetが存在するかあらかじめ知っておく必要があるということです。
そうでないと製品レベルのUIを組み上げることは難しいと思います。
しばらく書いていれば常套手段が溜まってきてそれなりにスラスラ書けるようになると思いますが、最初は途方に暮れましたし、今でも発見があります。

アニメーションもちょっと直感的じゃないと思うけど、これは慣れの問題じゃないかと思います。

また、これから始めてみようという方に注意点があるとすれば、結局iOS, Androidの知識も必要ということです。

少なくともリリースビルドするときには各OSのビルド設定を直接行う必要がありますし、既存のライブラリにない各OSの機能を使いたければ、Pluginなり各OS向けの連携コードを実装する必要があります(よく使いたくものは大体あります。)。

ちょっとビルドが通らないみたいなときに、Xcode/Android Studioを開いて設定を確認すれば問題が解消することもあります。

これはReactNativeなんかもそうなので、クロスプラットフォーム開発での常識かもしれません。

でも、そんなことは些細なことで、ここまで手軽にクロスプラットフォームなアプリ開発ができる環境が用意されていることは、素直に喜んでいいと思います。
公式のドキュメントも割と充実していますし。

そんなわけで、今年はしばらくFlutterをメインに触っていきたいな〜という気持ちです。