くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

初めてFlutterでWebアプリをつくってみたときに思ったこと

はじめてFlutterをつかったみたときの備忘録というか所感。
Crieitの1週間でWebサービスをつくる企画 web1weekがあったので、
なかなかやる機会がなかったFlutterに手を付けてみた(´ω`)

やってみるといろいろ気になるところが出てきたので、整理がてらメモ。

はじめるときやったこと

ここの書き方とかは個別に記事にする予定なので、ここはざっくり全体のことだけ。
シンプルなFlutter WebをGitHub Pageで公開した感じ。

Flutter自体やAndroidStudioのインストールは済んでいたので、その後から。

構成を考える

とりあえず、どういうパッケージ構成が良いのかなと、ざっくりいろいろ見てみた。

シンプルなのだったので、とりあえず、以下の感じ。

- configs   ... 定数とか設定関連
- models    ... モデルとかコアの処理とか
- pages     ... ページなどUI関連
  - widgets ... ページ内で使うWidget群
- main.dart ... メイン。テーマのカスタムやルーティングも。

処理も少なく、DBもFirebaseもないので、最小構成な感じ。

Flutter Webを有効化する

まずはFlutter Webはベータ版なので、
公式サイトみながら有効化する。

$ flutter channel beta
$ flutter upgrade
$ flutter config --enable-web

プロジェクトを作る

Android Studioから。「Start a new Flutter project」を選んで、
ポチポチしていけばOK。アプリと変わらない。

f:id:wannabe-jellyfish:20200316105833p:plain

実行

エミュレータの選択する部分で「Chrome(web)」とかが増えているので、
Chrome(web)」を選んで実行すると、Chromeの新しいウィンドウで起動してくれる。

f:id:wannabe-jellyfish:20200316105900p:plain

もちろん、HotReloadも効くけど、ガラッと変えるとリロードが必要になる。

Web向けの変更

Android/iOSごとの設定と同様に、Web版も個別設定ができる。
web/配下のファイルを修正すればOK。

f:id:wannabe-jellyfish:20200316105916p:plain

今回のでは主に、以下を変更。

  • メタタグの変更: index.htmlにdescriptionやOGタグを変更
  • ファビコンなどの配置: icons配下にfavicon.icoなどを配置
  • マニフェストの修正: PWAとして公開されるっぽいので、アプリ名などを設定

ビルド

リリース用にビルドする方法は以下の感じ。

# Web版のビルド
$ flutter build web

実行すると、build/web/配下にファイルが生成される。

f:id:wannabe-jellyfish:20200316105942p:plain

あとは、生成されたファイルをアップロードすればOK。

GitHub Pageで公開するときの注意点

GitHub Pageに公開するときにちょっとハマった。。

web/配下のindex.htmlやmanifest.jsonを修正した際、
/manifest.jsonとしていたが、

<!-- manifest -->
<link rel="manifest" href="/manifest.json">

リポジトリ名もパスにいれないとだめだった。。

<!-- manifest -->
<link rel="manifest" href="/tasu2tashizan/manifest.json">

Flutter Webを使ってみた所感など

調べて制限事項だったり、迷ったり、こうすればよかったかもという所感とか。
初Flutterなので、解消していきたい疑問とかを列挙してみた。

【制限】動的にメタ情報を変更できない

上記で修正したように、Flutter上でメタ情報を設定できず、
web/index.htmlを修正しなければならない。

以下のissueにも上がっている。
Server-side rendering for Flutter web · Issue #47600 · flutter/flutter

なので、CGM系サービスで投稿ごとにOGP画像を変えたりすることは現状難しいっぽい。

(以下のIssue #33245にあるようなdart:htmlをつかってゴリゴリ書き換えればいけるかも?だけど未確認。。)

【制限】URLに#がつく

namedRouteでパスを設定できるがURLに#がつく。

f:id:wannabe-jellyfish:20200316105958p:plain

以下のissueにワークアラウンドが紹介されているが、まだっぽい。。?
Flutter_web navigation should provide a way to remove hash symbol(#) · Issue #33245 · flutter/flutter

【反省】UIを全部Dartで書くので意識しないとカオスになる。。

Webみたいに、構造/装飾/動作がHTML/CSS/JavaScriptのように分かれていないため、
すべてがごちゃまぜになったFatなdartファイルが簡単に作れてしまう。。

VueのSFCのようにひとまとまりのコンポーネントにするのが良いのか?

役割ごとにかき分けるのが良いのか、単一ファイルコンポーネントが良いのかを含め、
どう書き分けるのがよいかなども気になるので、いろいろ見ていきたい。。

【反省】最初はStatelessだけでモックアップをつくるのがよいかも?

とりあえず、StatefulWidgetをつかって、部分的にStatelessWidgetにしていたけど、
いくつか本を読みながら、学びながらやっていたこともあり、ぐちゃぐちゃに。。

まずはUIを作って、あとから状態が必要な箇所をStatefulにしていくほうがよかったかもしれない。 BLoCパターンなどはまだ試せていないので、そのあたりも見ていきたい。

【疑問】パラメタに応じてリダイレクトするみたいな処理はどう書く?

「ログインが必要な画面で未ログインだと、ログインページに飛ばす」
みたいな処理を書きたかったけど、conextがないとNavigatorを呼べない。。

今回はそこまで重要じゃない&時間がないので省略したけど、
どうするのがいいか気になる。。

【疑問】デプロイの自動化とかどうするんだろう?

Flutterをインストールしないとビルドできないので、
現状ローカルでビルドしている感じ。

今後CIサービスでFlutterのビルドができるようになっていくのだろうか?

まとめ

簡単にWebアプリを作れてHotReloadもいい感じだけど、
まだまだissueがあり、思ってるWebサービスとはギャップがある感じ。

個別の処理とかはよく見るけど、全体的な方法論とか気になるところがまだまだあるので、 いろいろ見ながら、サクサク作れるようになりたい( ゚д゚)!

以上!!

作ったアプリはこちら

たすたすたしざん

f:id:wannabe-jellyfish:20200316110033p:plain