Flutter Web を試す

「Flutter for Webの環境構築手順」
https://qiita.com/kurun_pan/items/6349f6f38c837ee250b3

を元に、インストールと実行方法などを確認。


# 環境

- Ubuntu 18.04 AMD64
 - Apache2 インストール済
- 検証日 2020/10/23

今回のインストール作業で入った flutter, Dart のバージョンは以下の通り

```

$ flutter --version
Flutter 1.23.0-18.1.pre • channel beta • https://github.com/flutter/flutter
Framework • revision 198df796aa (8 days ago) • 2020-10-15 12:04:33 -0700
Engine • revision 1d12d82d9c
Tools • Dart 2.11.0 (build 2.11.0-213.1.beta)
```

# インストール作業

「Flutter for Webの環境構築手順」
の通り。

```


$ git clone https://github.com/flutter/flutter
$ sudo mv flutter /usr/local/
```

パスを通す。

```
export PATH=$PATH:/usr/local/flutter/bin/


```
を ~/.bashrc の最後に加えて

```

source ~/.bashrc

```

で反映。


Flutter for web は beta での提供なので、

```

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


ここで、「Flutter for Webの環境構築手順」では

> 2.2.1 補足
flutter configコマンドで~/. flutter_settingsファイルの内容が書き換わります。

```

$ cat ~/.flutter_settings 
{
  "enable-linux-desktop": true,
  "enable-macos-desktop": true,
  "enable-web": true
}
```
とありましたが、該当のファイルはありませんでした。


```

$ flutter devices
```

で

```

Downloading package sky_engine...                                   0.5s
Downloading flutter_patched_sdk tools...                            4.6s
Downloading flutter_patched_sdk_product tools...                    4.8s
Downloading linux-x64 tools...                                      9.9s
Downloading linux-x64/font-subset tools...                          1.2s
2 connected devices:

Web Server (web) • web-server • web-javascript • Flutter Tools
Chrome (web)     • chrome     • web-javascript • Google Chrome 84.0.4147.125
```
となって web ターゲットが用意されていることがわかります。


# 実行してみる

## Chrome で実行

```

$ cp -rf /usr/local/flutter/examples/hello_world/ .
$ cd hello_world/
$ flutter run -d chrome


```

でローカルマシンの Chrome に以下の表示がされることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/401a7e01-21a4-e80a-18c9-3ebbe0da382e.png)

## Webサーバで実行

```

$ flutter run -d web-server
```

で

```


Launching lib/main.dart on Web Server in debug mode...
Syncing files to device Web Server...                                   
 7,964ms (!)                                       
lib/main.dart is being served at http://localhost:37479
The web-server device requires the Dart Debug Chrome extension for debugging. Consider using the Chrome
or Edge devices for an improved development workflow.

Warning: Flutter's support for web development is not stable yet and hasn't
been thoroughly tested in production environments.
For more information see https://flutter.dev/web

🔥  To hot restart changes while running, press "r" or "R".


```

と出ているとおり、http://localhost:37479 をブラウザで開いてみます。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e5019772-2323-912d-c48d-39e761849170.png)


# その他のサンプルプログラム

```

$ ls /usr/local/flutter/examples
README.md               flutter_view  image_list  platform_channel        platform_view
flutter_gallery.readme  hello_world   layers      platform_channel_swift  splash

```

とある。それぞれ hello_world と同じ手順で flutter run -d chrome でそれぞれ実行してみた。

## flutter_view
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/459bd72a-e2a7-ba09-3e2f-05fc0ee0a1bc.png)

マウス操作だと特に何も操作できなかった。



## image_list

ブラウザは立ち上がるが白画面のまま、以下のようにエラー。

```

This application is not configured to build on the web.
To add web support to a project, run `flutter create .`.
Launching lib/main.dart on Chrome in debug mode...
Syncing files to device Chrome...                                       
18,009ms (!)                                       
Debug service listening on ws://127.0.0.1:41173/dFzJuC1CmZQ=

Warning: Flutter's support for web development is not stable yet and hasn't
been thoroughly tested in production environments.
For more information see https://flutter.dev/web

🔥  To hot restart changes while running, press "r" or "R".
For a more detailed help message, press "h". To quit, press "q".
Error: Unsupported operation: SecurityContext constructor
    at Object.throw_ [as throw] (http://localhost:33211/dart_sdk.js:4339:11)
    at Function.new (http://localhost:33211/dart_sdk.js:56988:17)
    at main$ (http://localhost:33211/packages/image_list/main.dart.lib.js:881:55)
    at main$.next (<anonymous>)
    at runBody (http://localhost:33211/dart_sdk.js:37699:34)
    at Object._async [as async] (http://localhost:33211/dart_sdk.js:37730:7)
    at main$ (http://localhost:33211/packages/image_list/main.dart.lib.js:878:18)
    at main (http://localhost:33211/web_entrypoint.dart.lib.js:33:27)
    at main.next (<anonymous>)
    at http://localhost:33211/dart_sdk.js:37679:33
    at _RootZone.runUnary (http://localhost:33211/dart_sdk.js:37533:58)
    at _FutureListener.thenAwait.handleValue (http://localhost:33211/dart_sdk.js:32507:29)
    at handleValueCallback (http://localhost:33211/dart_sdk.js:33054:49)
    at Function._propagateToListeners (http://localhost:33211/dart_sdk.js:33092:17)
    at async._AsyncCallbackEntry.new.callback (http://localhost:33211/dart_sdk.js:32818:27)
    at Object._microtaskLoop (http://localhost:33211/dart_sdk.js:37794:13)
    at _startMicrotaskLoop (http://localhost:33211/dart_sdk.js:37800:13)
    at http://localhost:33211/dart_sdk.js:33309:9
```

## layers

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/df9dd413-5d67-6fa0-f458-fd5786a7937c.png)

fmm...




## platform_channnel

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0fde17e8-8bea-48f9-ef3a-3af304a9636c.png)

ボタンは押せるがターミナルに以下のようにエラーが発生

```

Error: MissingPluginException(No implementation found for method getBatteryLevel on channel
samples.flutter.io/battery)
    at Object.throw_ [as throw] (http://localhost:42331/dart_sdk.js:4339:11)
    at MethodChannel._invokeMethod
    (http://localhost:42331/packages/flutter/src/services/system_channels.dart.lib.js:944:21)
    at _invokeMethod.next (<anonymous>)
    at http://localhost:42331/dart_sdk.js:37679:33
    at _RootZone.runUnary (http://localhost:42331/dart_sdk.js:37533:58)
    at _FutureListener.thenAwait.handleValue (http://localhost:42331/dart_sdk.js:32507:29)
    at handleValueCallback (http://localhost:42331/dart_sdk.js:33054:49)
    at Function._propagateToListeners (http://localhost:42331/dart_sdk.js:33092:17)
    at _Future.new.[_completeWithValue] (http://localhost:42331/dart_sdk.js:32935:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:42331/dart_sdk.js:32957:35)
    at Object._microtaskLoop (http://localhost:42331/dart_sdk.js:37794:13)
    at _startMicrotaskLoop (http://localhost:42331/dart_sdk.js:37800:13)
    at http://localhost:42331/dart_sdk.js:33309:9

```

## platform_channel_swift

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/62a03f72-a0cc-44f6-5cc9-68f2e2af8a67.png)

platform_channnel と同様、ボタンは押せるがターミナルにエラーが発生します。





## platform_view

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c75aaf7a-f92e-86da-77da-f6db8a61fbbc.png)

## splash
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/56633d22-eb39-3d57-5c02-f7c3b504cd84.png)




# gellery


/usr/local/flutter/examples/

には、flutter_gallery は無くて代わりに flutter_gallery.readme  があります。

> The Flutter Gallery > sample application that used to live in
this /examples/ directory has moved, and is now located here:
> 
> https://github.com/flutter/gallery


とあるので、こちらを試してみます。

```

$ git clone https://github.com/flutter/gallery
$ cd gallery/
$ flutter run -d chrome

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a6cd212f-7084-7086-4ba4-6a2216327427.png)


# 外部から接続してみる


```

$ flutter run -d web-server
```

として実行したものは、外部からアクセスできなかった。

なので

```

$ flutter build web
```

とすると

```

・
・
・
"ur": 35 untranslated message(s).                                       
"uz": 35 untranslated message(s).                                       
"vi": 35 untranslated message(s).                                       
"zh": 35 untranslated message(s).                                       
"zh_CN": 35 untranslated message(s).                                    
"zh_HK": 35 untranslated message(s).                                    
"zh_TW": 35 untranslated message(s).                                    
"zu": 35 untranslated message(s).                                       
To see a detailed report, use the --untranslated-messages-file          
option in the tool to generate a JSON format file containing 
all messages that need to be translated.
Compiling lib/main.dart for the Web...                            145.5s
```

となって  build/web/ に以下のファイルができる。

```

404.html                   main.dart.js_21.part.js  main.dart.js_41.part.js  main.dart.js_61.part.js
assets                     main.dart.js_22.part.js  main.dart.js_42.part.js  main.dart.js_62.part.js
favicon-16x16.png          main.dart.js_23.part.js  main.dart.js_43.part.js  main.dart.js_63.part.js
favicon-32x32.png          main.dart.js_24.part.js  main.dart.js_44.part.js  main.dart.js_64.part.js
favicon.ico                main.dart.js_25.part.js  main.dart.js_45.part.js  main.dart.js_65.part.js
flutter_service_worker.js  main.dart.js_26.part.js  main.dart.js_46.part.js  main.dart.js_66.part.js
icons                      main.dart.js_27.part.js  main.dart.js_47.part.js  main.dart.js_67.part.js
index.html                 main.dart.js_28.part.js  main.dart.js_48.part.js  main.dart.js_68.part.js
main.dart.js               main.dart.js_29.part.js  main.dart.js_49.part.js  main.dart.js_69.part.js
main.dart.js_1.part.js     main.dart.js_3.part.js   main.dart.js_5.part.js   main.dart.js_7.part.js
main.dart.js_10.part.js    main.dart.js_30.part.js  main.dart.js_50.part.js  main.dart.js_70.part.js
main.dart.js_11.part.js    main.dart.js_31.part.js  main.dart.js_51.part.js  main.dart.js_71.part.js
main.dart.js_12.part.js    main.dart.js_32.part.js  main.dart.js_52.part.js  main.dart.js_72.part.js
main.dart.js_13.part.js    main.dart.js_33.part.js  main.dart.js_53.part.js  main.dart.js_73.part.js
main.dart.js_14.part.js    main.dart.js_34.part.js  main.dart.js_54.part.js  main.dart.js_74.part.js
main.dart.js_15.part.js    main.dart.js_35.part.js  main.dart.js_55.part.js  main.dart.js_75.part.js
main.dart.js_16.part.js    main.dart.js_36.part.js  main.dart.js_56.part.js  main.dart.js_76.part.js
main.dart.js_17.part.js    main.dart.js_37.part.js  main.dart.js_57.part.js  main.dart.js_77.part.js
main.dart.js_18.part.js    main.dart.js_38.part.js  main.dart.js_58.part.js  main.dart.js_8.part.js
main.dart.js_19.part.js    main.dart.js_39.part.js  main.dart.js_59.part.js  main.dart.js_9.part.js
main.dart.js_2.part.js     main.dart.js_4.part.js   main.dart.js_6.part.js   manifest.json
main.dart.js_20.part.js    main.dart.js_40.part.js  main.dart.js_60.part.js  version.json
```


/var/www/html が DocumentRoot として Apache2 を設定していたので、

```


$ sudo mkdir /var/www/html/fluttertest
$ sudo cp -a build/web/* /var/www/html/fluttertest/
$ sudo chown -R www-data:www-data /var/www/html/fluttertest
```


で外部から http://[server]/fluttertest でアクセスできた