パッケージが統合されたFlutter for Webへのアップグレード
Flutter for Webのパッケージがflutter
に統合されました。それに伴い既存のFlutter for Webのプロジェクトでアップグレードが必要になったのでその記録です。
Upgrading
まだstableには来てないのでdevに向けて、webを有効にします。
$ flutter channel dev
$ flutter upgrade
$ flutter config --enable-web
channelの変更は、次のバージョンがstableに来たら不要になると思います
$ flutter --version Flutter 1.10.6 • channel dev • https://github.com/flutter/flutter.git Framework • revision cc3ca9a916 (5 days ago) • 2019-09-25 10:57:58 -0400 Engine • revision 63949eb0fd Tools • Dart 2.6.0 (build 2.6.0-dev.0.0 69b5681546)
既存プロジェクトですでに作成済みの web/main.dart
を削除します。
次に、プロジェクトをFlutter SDK向けに変更していきます。
$ flutter create .
pubspec.yaml
を置き換えて、flutter_web
の部分をflutterに置き換えます。
web/assets/
に置いていた FontManifest.json
の内容を移行します。
MaterialIconsは
flutter: uses-material-design: true
となり、
fontを利用していた場合は fonts
フォルダをプロジェクトルートに作り、そこにフォントファイルを置きます。その後、font名の指定とfontのpathを書きます。
flutter: ... fonts: - family: KosugiMaru fonts: - asset: fonts/KosugiMaru-Regular.ttf
画像などの素材は、 assets
フォルダをプロジェクトルートに作り、そこに移動させます。その後フォルダを指定します。
flutter: ... assets: - assets/
これで web/assets
フォルダは空になったと思うので、削除します。
実行は次のコマンドです。Windowが立ち上がります。
$ flutter run -d chrome
ドキュメント的には以上なのですが、自分の環境では更に次のような手順が必要でした。
追加手順
rootBundleのimport
rootBundle
を使っている場合、含まれるパッケージが変わっているので flutter/service
からimportします。
import 'package:flutter/services.dart' show rootBundle;
assetsのパス
rootBundle
でassetsにアクセスしている場合、pathが次のように変わります。
some.json
だったものが
assets/some.json
になります。assetsに指定しているフォルダからpathを指定する必要があります。
BinaryMessengerへのアクセス
runApp
より早いタイミングで rootBundle
を利用している場合、chromeのconsoleにエラーが出ます。
Uncaught (in promise) Error: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized. If you're running an application and need to access the binary messenger before `runApp()` has been called (for example, during plugin initialization), then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first. If you're running a test, you can call the `TestWidgetsFlutterBinding.ensureInitialized()` as the first line in your test's `main()` method to initialize the binding.
rootBundle
がbinaryMessengerを利用しているため、怒られます。回避するためにはエラー文の通り、
WidgetsFlutterBinding.ensureInitialized()
をrootBundle
より先に呼び出します。
dart:htmlのimportエラー
自分はIntelliJで開発しているのですが、Target of URI doesn’t exist: ‘dart:html’.
のエラーが出ました。ですが、ターミナルからビルドする分には問題ありませんでした。
現状Dart SDKが提供しているもので、利用できるものとそうでないものがあるみたいです。
Release Buildのアウトプット先
今までは build/
だったのですが、build/web/
に変わりました。Deployする際には注意が必要です。
リリースビルドのコマンドは次です。デフォルトでreleaseのconfigurationになっています。
$ flutter build web
まとめ
パッケージ統合以前のFlutter for Webのプロジェクトでも、アップグレードガイドがあるので移行自体はさっとできます。
ただし、いくつか注意点があるのでハマりすぎないように気をつけてください。
自分の環境において、マイグレーションのドキュメントに書いてないことで気をつける必要があったことは次の5点です。
- rootBundleのimportが変わる
- assetsのパスが変わる
- assetsに早いタイミングでアクセスしている場合は
WidgetsFlutterBinding.ensureInitialized()
が必要になる - Dart SDKのいくつかのパッケージはWebでの利用に制限がある
- アウトプットのpathが異なる
参考
Upgrading from package:flutter_web to the Flutter SDK · flutter/flutter Wiki · GitHub
Properly enable dart:html imports · Issue #35588 · flutter/flutter · GitHub
技術書典7にFitbit本の続編を出した
先日開催された技術書典7にサークル参加しました。サークル参加としては2回目で、技術書典5以来なので1年ぶりの参加でした。
前回の参加記事はこちら
事前準備(執筆編)
1年ぶりで、結構色々忘れていました。
次の記事を参考に環境を構築しました。去年と大きく異なっていたのは、Re:VIEWのメジャーバージョンが2から3に変わっていました。
続編という位置づけで考えていたのですが、旧刊を購入していないと話がわからないのでは敷居が高すぎると思ったので、一部内容は重複してしまうのですが、それぞれ独立して読めるような構成にしました。
今回は表紙をお願いすることにしました。
お願いするにあたって、何が決まっていれば嬉しいのかがわからなかったので、こんな感じだと嬉しいなってのをboothからピックアップして雰囲気を伝えました。
あとは表示サイズと仮タイトルを伝えて、ここはこういうふうにしたほうがFitbitをつけてるのが映えるよーってのをやり取りして決めていきました。
印刷は前回と同じく日光企画さんにお願いしました。Fitbit Versa 2の発売日が技術書展7の明後日なので、なるべく最新の情報を詰めたくて前日まで粘ってたのですが、結局開発者向けの新しい情報は公開されませんでした。
前日印刷でも、午前10時までにデータを入稿すれば間に合いはしますが、印刷代が倍くらいに膨れるので最後の手段と思ったほうが良さそうです。
自分の場合だとA5サイズ64ページで50冊印刷して50,240円でした。
事前準備(ブース編)
前回の振り返りを見て、背の高いPOPスタンドを置いておくと目立つというのと、卓上に布があったほうが圧倒的に見栄えが良いことがわかっていたので、準備しました。
今回は本の価格を1000円にしました。残っていた旧刊も売れればいいなと思い持っていきました。旧刊は500円なので、数枚程度500円玉を用意し、万札にも耐えられるように1000円札を用意しました。
あとはPOPスタンドに吊るす紙をA4で印刷し、電子版も対応していたのでQRコードを印刷した紙を用意しました。
当日
若干遅刻してしまいました。サークル入場も遅れていたので結果的に自分はほとんど待つことなく入場できましたが、準備が間に合わないんじゃないかとヒヤヒヤしました。
本は技術書典のバックアップ印刷所さんに依頼しておけばブースまで持ってきてもらえます。当日着いたらすでに届いていました。
実際の部数は65冊ありました。
遅れたこともあり、立ち読み本の扱いがよくわからなかったのですが横のサークルの方に教えてもらい、無事提出できました。準備はサッとできました。
設営できた!お待ちしております。 #技術書典 pic.twitter.com/vrduvUGU92
— Shinya Sakemoto @技術書典7(い17C) (@sakebook) September 22, 2019
実は今回も売り子を見つけられず一人での参加となりました。辛かったですがお手洗いなどは横のサークルの方が気を利かせてくれて助かりました。
技術書典5でFitbit本を購入し、今回も購入してくださった方がいてめちゃめちゃ嬉しかったです。
後払いで20部、現金で19部の合計39部売れました。印刷代やサークル参加費を考えると赤字です。旧刊は完売したのでそこは良かったです。余った部数が多かったのでboothにあずけて帰りました。boothでも、月に安定して売上が立たなければ保管料金がかかるみたいなので注意です。
今回販売した新刊のboothリンクです。Versa 2買った人や購入検討中の人は買って損のない内容になってます。
終わってみて
一人参加は相変わらず辛いですが、ちょっとこなれた感じがあります。ウェアラブルデバイスに関するサークルがうちと横のサークルしかなく、横の方はその辺りを話題にだしたりしていたのですが、自分はあまりそういう接客ができていなかったです。交流という意味でも接客という意味でもその辺りはもう少しやりようはあったなーと思いました。
立ち読みはしてくれたのですが、そこから購入に至らなかった人がわりといました。本の質の問題なのか、目次から読み取りにくかったのか、思ってたのと違ったのか、その辺りがわからないのが辛いところです。
掛けた時間と帰ってくるお金は相変わらず見合わないですが、サークル参加自体は敷居が低くなってきているので、気になってる方はやってみると良いと思います。自分の好きなことを好き勝手書いていいんですよ!
参考
DartでCloud Functions for Firebaseを動かす
最近FlutterでDartを触っているので、Dartでなにかできればなと思いました。
ちょっとした処理をしたくなって、Cloud Functions for Firebaseが使えればなと思い調べたところ、DartをJavascriptにトランスパイルしてCloud Functionsで利用できるようにするPluginがあったのでその紹介をします。
firebase_functions_interop
READMEが充実しているのでその通りにやればだいたいできます。
build_runnerでビルドして、生成された.jsファイルをpackage.jsonが見るようにします。
デバッグ
serve
コマンドでローカルに立ち上げることができます。
$ firebase serve --only functions
ハマったところ
通信はnode_httpで行う
http.getを行おうとすると実行時に次のようなエラーが発生します。
ReferenceError: XMLHttpRequest is not defined
firebase_functions_interopがnode_httpで通信を行なっているので、それに合わせます。
Cloud Functions for Firebaseの無料版ではOutbound networkに制限がある
Cloud Functions for Firebase内でSlackなどとOutbound networkを行うと次のようなエラーログが吐かれます
Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions
無料版だとOutbound networkingがGoogle services onlyという制限があります。
解決するにはFlameプランかBlazeプランにする必要があります。
作ったもの
SlackのOutgoing WebHooksを使って、トリガーとなる言葉とユーザグループを指定するとランダムにユーザを選択するものを作りました。
まとめ
DartでもCloud Functions for Firebaseを動かすことはできますが、適宜制約があるのでハマらないように気をつけましょう。
参考
firebase_functions_interop / Dart Package
node-interop/build_node_compilers at master · pulyaevskiy/node-interop / GitHub
Cloud Functions for Firebase - Billing account not configured / Stack Overflow