この記事はPWA Advent Calendar 2019の14日目の記事です。
flutter on the webでのPWA対応についてです。
13日は、migiiさん
15日は、asmzさんです。
##fluter for web
flutter on the webがbetaになりました🎉
個人的には、flutterはPWAととても親和性があるツールだと考えています。React Native for webなどからわかるように、最近はmobile Appの知見をWebに還元する動きが高まっているし、そもそもFlutterはWebも含めたマルチプラットフォームを目指しています。(しかも、Dartは元々、Alternative JSとして作られています)
今後、flutterはシングルコードでWeb(PWA)、Android、iOSアプリを作ることのできる夢のような可能性を持っています。
(先日のFlutter interactでの画像)
公式サイトにも、PWAを前提とした記述があります。
A connected Progressive Web Application built with Flutter Web support for Flutter enables existing mobile-based applications to be packaged as a PWA for reach to a broader variety of devices, or to provide a companion web experience to an existing app.
しかし、現状はPWA化についてのドキュメントはありませんし、pwa Packageについてもflutter webのbadgeはついているものの、flutterでの使い方についてなどはありません。
今後、Packageの対応やNuxtのようにベースとしてPWAで作れるようになると思いますが、現段階でflutterをPWA化したい人に向けて、自分がやった方法を紹介したいと思います。
##flutter on the webでPWA
flutter on the webの始め方はこちらを参考にしてください。
とりあえず、今回でいうPWA化はinstallPopUpを表示し、ホーム画面にインストール可能にする部分までを実装しようと思います。(Offline対応などは調査中)
前提として、flutterはDartで書かれていますが、Build後のファイルはproduction JavaScript compilerによって最適化されたJavaScriptにコンパイルされています。つまり、Build後の構成は他のWebAppと同じように、メインとなるindex.html
とbuildされたjsファイルによって構成されています。
よって、buildして生成されたdeployフォルダにservice worker
とmanifest.json
を追加し、index.html
に数行の記述を追加すればPWA化することができます。
flutter on the webのビルドコマンドは以下で
flutter build web
build/web
が生成されます。そしてbuild/web
下にmanifest.json
,sw.js
を追加してあげます。
{
"name": "pwa_sapmle",
"short_name": "pwa",
"icons": [
{
"src": "assets/assets/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone"
}
self.addEventListener('fetch', function(event) {});
ここで重要なのは、icon画像をどこに配置するかという点で、直接build/web
に追加してあげてもいいですが、flutterのassetsに追加してあげてもいいです。上記の場合は、プロジェクト下にassetsをフォルダを作成し、その中にicon画像を配置します。そしてpubspec.yaml
に以下を記述します。
assets:
- assets/
そうすると、build後build/assets/assets
にicon画像が追加されます。
最後にweb/
下のindex.html
に以下のように記述します。(build/web
ではないです)
<!DOCTYPE html>
<html>
<head>
<link rel="manifest" href="manifest.json">
<meta charset="UTF-8">
<title>pwa_sample</title>
</head>
<body>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js').then(function (registration) {
}).catch(function (err) {
});
}
</script>
これでどこかに適当にbuild/web
をhostingしてあげると、
このようにPWA化が可能になります。
##最後に
sampleをhttps://github.com/dennougorilla/flutter_pwa_sample にあげておくのでよかったら確認してみてください。
PWA対応の定義は色々とあると思いますが、個人的にはここまでやっとけば、一応PWAと呼んでいいんじゃないかと思っています。offline対応やpush通知に関しては後々調べつつ、PackageやFlutter自身の対応を気長に待ちます。
PWAバンザイ!