Flutter Webを動かしたときにつまづいたこと

Flutter Webが来ました🎊

* https://github.com/flutter/flutter_web

ひとまず手元で `examples/hello_world` が動くところまでできています。

![スクリーンショット 2019-05-08 13.52.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2276/89f0d6e3-0c87-f812-c8c7-bff11d4b79f1.png)

Flutterに関してまったくセットアップしていない環境から始めたのですが、3点ほど引っかかるところがあったのでメモしておきます。

Flutter素人がやった手順なので、大間違いなところがありそうです。有識者の方、ツッコミお待ちしております。

## 全体の流れ

大まかなセットアップの流れとしては、次のような感じになります。

1. [普通のFlutterのセットアップ手順](https://flutter.dev/docs/get-started)でセットアップする
    - ひとまず `flutter doctor` コマンドが通ればOKです
    - Android StudioやVSCodeのセットアップはしなくても、たぶん `flutter precache` の手順まで実施できてればいけそうな気もします
2. [Flutter WebのGetting Started](https://github.com/flutter/flutter_web#getting-started)を実施します

このうち、手順2で引っかかるところがあったので、それぞれ解説します。

## 1. webdevのインストールはサンプルプロジェクトに入った後

`git clone` したらすぐに `flutter packages...` を実行していいような雰囲気で書いてあります。

![スクリーンショット 2019-05-08 14.01.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2276/9a8873e7-1b7a-c3e2-717d-951425780960.png)

ですが、実際にはpubコマンドは `pubspec.yaml` がある場所で叩かないといけないので、エラーになります。手順をなぞるなら、 `cd examples/hello_world` に入るのが先で、 `flutter packages...` を実行するのは後です。

## 2. dartコマンドにもパスを通す

`webdev serve` を実行すると、次のようなエラーが出ることがあります。

```bash
$ webdev serve
/your_flutter_path/flutter/.pub-cache/bin/webdev: line 7: dart: command not found
```

これは `webdev` コマンドのシェルスクリプト実装を見るとわかるのですが、内部で `dart` コマンドを実行しています。

```sh:webdev
#!/usr/bin/env sh
# This file was created by pub v2.3.0-dev.0.5.flutter-a1668566e5.
# Package: webdev
# Version: 2.0.4
# Executable: webdev
# Script: webdev
dart "/your_flutter_path/flutter/.pub-cache/global_packages/webdev/bin/webdev.dart.snapshot.dart2" "$@"

# The VM exits with code 253 if the snapshot version is out-of-date.
# If it is, we need to delete it and run "pub global" manually.
exit_code=$?
if [ $exit_code != 253 ]; then
  exit $exit_code
fi

pub global run webdev:webdev "$@"
```

もちろん皆さんのお手元には `dart` コマンドにパスが通っていますよね？　そんなわけないだろ・・・！

はい、というわけでググってみましたが、ドンピシャではないものの似たような悩みを見つけました。

[/bin/sh: dart: command not found · Issue #27162 · flutter/flutter](https://github.com/flutter/flutter/issues/27162)

> If you want to use the dart corresponding to your flutter environment, add `your-flutter-dir/flutter/bin/cache/dart-sdk/bin` to your PATH.

よっしゃ。ということでパスに追加したところ、本件のエラーは出なくなりました。

## 3. `pub get` はflutter経由ではなく直接叩く

それでは今度こそ動くかなということで `webdev serve` を叩きます。

```bash
$ webdev serve
webdev could not run for this project.
The pubspec.yaml file has changed since the pubspec.lock file was generated, please run "pub get" again.
```

`pubspec.yaml` と `pubspec.lock` のズレとはどういうことだろう……と思いつつ、ひとまず `pub get` をやり直しなさいと言われているので、やってみましょう。さきほど `webdev` をactivateしたときのコマンドに倣って、 `flutter packages pub get` で行けるでしょうか。

```bash
$ flutter packages pub get
Resolving dependencies...
Warning: You are using these overridden dependencies:
! flutter_web 0.0.0 from path ../../packages/flutter_web
! flutter_web_ui 0.0.0 from path ../../packages/flutter_web_ui
Got dependencies!
Precompiling executables...
Precompiled build_runner:graph_inspector.
Precompiled build_runner:build_runner.
$ webdev serve
webdev could not run for this project.
The pubspec.yaml file has changed since the pubspec.lock file was generated, please run "pub get" again.
```

ダメっぽいです。

ここで再び `webdev` コマンドの実装をよく見てみましょう。

```sh:webdev
#!/usr/bin/env sh
# This file was created by pub v2.3.0-dev.0.5.flutter-a1668566e5.
# Package: webdev
# Version: 2.0.4
# Executable: webdev
# Script: webdev
dart "/your_flutter_path/flutter/.pub-cache/global_packages/webdev/bin/webdev.dart.snapshot.dart2" "$@"

# The VM exits with code 253 if the snapshot version is out-of-date.
# If it is, we need to delete it and run "pub global" manually.
exit_code=$?
if [ $exit_code != 253 ]; then
  exit $exit_code
fi

pub global run webdev:webdev "$@" # ←！！！？？？
```

パスが通っている場所から `pub` が実行されています。これはもしかして、 `flutter packages pub` が管理してる場所とは違うのでは……？

しかし `pub` コマンドなんて手元にはなかったはず。まあ一応確かめてみますか……

```bash
$ which pub
/your_flutter_path/flutter/bin/cache/dart-sdk/bin/pub
```

なんかありますね。dartにパスを通したときに一緒に通ってたみたいです。

そういうことならひとまず叩いてみましょう。

```bash
$ pub get
Resolving dependencies... (16.5s)
+ analyzer 0.36.3
+ archive 2.0.8
+ args 1.5.1
+ async 2.2.0
+ bazel_worker 0.1.20
+ build 1.1.4
+ build_config 0.4.0
+ build_daemon 0.6.0
...
Downloading quiver 2.0.3...
Downloading intl 0.15.8...
Changed 66 dependencies!
Precompiling executables... (36.9s)
Precompiled build_runner:graph_inspector.
Precompiled build_runner:build_runner.
```

おっ、通りました。では、改めて `webdev serve` を実行してみます。

```bash
$ webdev serve
[INFO] Serving `web` on http://localhost:8080
[INFO] Running build completed, took 39.1s
[INFO] Caching finalized dependency graph completed, took 285ms
[INFO] Succeeded after 39.4s with 548 outputs (3169 actions)
```

やったー！　通ったー！！

## まとめ

きっと `flutter` コマンド経由で `pub` を使う正しい方法があって、僕のは無理やりな方法だという自信があるので、有識者の方、正しい方法をおしえてください！！！！！！

## 追記

先にチャレンジしてくださっていた @hiko1129 さんのほうもflutter経由じゃない `pub` を使ってる模様。

* https://qiita.com/hiko1129/items/efc20792016a22a7c88a

やっぱりそういう方向なのかな……

## 追記2

[@kwmt27](https://twitter.com/kwmt27)さんからおしえていただいたのですが、 `flutter pub` というpubもあるそうです。僕の手元では検証しづらくなったので、誰か試してみてください（無責任）

* https://twitter.com/kwmt27/status/1126000317437366274