はじめに
Flutter for Webを使っておよそ3時間でPWAサービスをリリースします!
ちょっと前までFlutterの名前も知らず、知ってからもiOS/Androidクロスプラットフォームという印象でした
しかし、2021年3月のFlutter2リリースで正式にWeb対応したということを知りまして、将来性しか感じておりません!
ということで独自ドメインとAWSを併用して爆速でPWAサービスをリリースしてみました
PWAとは
Progressive Web Appsの略で、ウェブサイトにも関わらずネイティブアプリのような挙動を実現する機能です
アプリストアにリリースすることもなく、スマホのホーム画面にインストールできたり、プッシュ通知ができたりします
ブラウザのUIがなくなる分、画面を最大限使えるのが個人的にはイチオシのポイントです
↓は今回作成したサンプルページの例ですが、PWA化した方が上下の表示領域が広いです
.
できることは限られますが、ストアの審査も要らずにネイティブ風のアプリが作れるのはアツいのではないでしょうか
ちなみにサンプルはこちらに置いておきます
開発環境
- Flutter 2.0.6
- MacOS Big Sur 11.2.3
- AndroidStudio 4.1.2
ちなみにApple M1チップですが、特に問題ありませんでした
作る
Flutterのサンプルアプリを作る
Flutterの導入
Flutterそのもののインストールについては公式もありますし、他の方も書いていると思うので割愛します
Flutter公式を参照しながら、
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.0.6, on macOS 11.2.3 20D91 darwin-arm, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] Connected device (1 available)
• No issues found!
コマンドが全て問題なく通るようにしてあればOKです
加えて、AndroidStudioをエディタとして使うのが個人的に好きです
こちらもやり方は割愛しますが、AndroidStudioにFlutterとDartのプラグインを入れることになります
※参考【Flutter】 アプリ開発入門 Hello Flutter!!
Flutterプロジェクトを作成する
AndroidStudioを起動し、「Flutter Application」を選択してプロジェクトを作成します
Web向けのリリースだけならば、iOSやAndroidのコードについてはチェックを外してもOKです
プロジェクトを作成したら、ターミナルでFlutter for Webを有効化します
$ flutter config --enable-web
Flutter for Webが有効化されていると、デバッグデバイスにChromeが追加されます
$ flutter devices
1 connected device:
Chrome (web) • chrome • web-javascript • Google Chrome 90.0.4430.93
動かしてみる
AndroidStudioに戻ってFlutterプロジェクトを開くと、デバッグ対象にChromeが追加されています
この状態でデバッグボタンを押せば、勝手にChromeが起動してアプリが動きます
doctorをオールOKにするのがやや手こずりますが、環境構築はものすごく簡単ですね...
ビルドする
動くことが確認できたら、Web向けにビルドします。下記のコマンドを叩くだけ
$ flutter build web
するとbuild/web/以下にindex.htmlに一通り出力されます
しかもこの時、manifest.jsonが生成されていまして、なんとデフォルトでPWA対応しています。
あらやだFlutter恐ろしい子
もしindex.htmlがないよ!みたいなエラーが出たら、下記のコマンドを叩いて再度やってみてください
$ flutter create .
アプリルート以下のwebディレクトリが丸ごとできていないケースがあるようです
Flutterの出番は一旦ここまでです
AWS S3 + CloudFrontでFlutter for Webを静的ホスティングする
ちなみにS3への直アクセス制限(Restrict Bucket Access)もやります
S3バケットを作成する
パブリックアクセスはブロックでOKです。後ほどCloudFront経由のみを許可します
Flutter for Webをアップロードする
作成したS3バケットに、flutter build webで生成されたbuild/web/以下のファイルを全てアップロードします
CloudFrontからS3にアクセスする
CloudFrontのディストリビューション作成から、新規作成します
- OriginDomainName : 先ほど作成したS3バケット
- Restrict Bucket Access : Yes ※OriginDomainNameでS3を指定すると出てくる
- Origin Access Identity : Create a New Identity
- Grant Read Permissions on Bucket : Yes
作成に成功すると、S3の「アクセス許可」の「バケットポリシー」に下記が追加されます
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity xxxxxxxxxx"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*"
}
]
}
ちなみにS3静的ホスティング時のポリシーが残っているとアクセス拒否されることがあるようなので、S3にアップロードした時点でホスティングして確認した人はご注意ください
そのほか画像には無いですが、下記の設定をしています
- 「General」→「Edit」→Default Root Object : index.html
- 「Behaviors」→「Edit」→Viewer Protocol Policy : Redirect HTTP to HTTPS
この時点でCloudFrontのDomainNameからアクセスできることを確認してください
ドメインを取得する
お好みの独自ドメインを取得します
今回はムームードメインで適当に「flutter-pwa-sample.site」を取得しました
184円/年と激安
HTTPS対応する
PWA化するにはHTTPS化が必要です
Route53でホストゾーンを作る
取得したドメインを使ってRoute53でホストゾーンを作ります
証明書を発行する
ホストゾーンができたら証明書を作成します
CloudFrontから証明書を参照するために、ここだけ北部バージニアで行ってください
AWS Certificate Managerで取得したドメインを入力し、
「Route53でのレコードの作成」をすると、先ほどのホストゾーンにCNAMEレコードが追加され、自動的に検証が始まります
「発行済み」になればOKです。私の場合は数分程度で完了しました
CloudFrontに証明書を紐づける
CloudFrontのディストリビューション設定を開き、下記を設定します
- Alternate Domain Names : ドメイン名
- Custom SSL Certificate : 先ほど作成したSSL証明書
ルートレコードを作る
Route53でドメイン名ルートのレコードを作ります
独自ドメイン側を設定
最後に、独自ドメイン側にRoute53のネームサーバを設定して終了です
Route53には最終的に4レコードあることになりますが、NSレコードの値を独自ドメイン側にも設定します
ムームードメインの場合は、「コントロールパネル」→「ドメイン名」→「ネームサーバの設定変更」から、↓のような感じで設定すればOKです
末尾のピリオドは不要なのでご注意ください
数日かかるかも!と書かれていますが、私の場合はごはん食べている間に反映されていました
完了!
ということで、証明書発行やネームサーバ設定の反映待ちの時間を入れても2~3時間で、PWAサービスを公開することに成功しました!
Safariの場合はサイトを開いて「ホーム画面に追加」するだけで、ネイティブアプリのような見た目で表示することができるようになります
FlutterはUIの構築もやりやすく、個人や少人数チームであれば超有力な選択肢になると思っています
(今回はWebですが、Win/MacOS/Linuxへもリリースできる)
Web歴1年ちょいのまだまだ素人ですが、精進していきたいと思います