WSL2へのFlutter開発環境構築

2021-10-03 (Sun)
WSL2上のUbuntu20.04にFlutter開発環境を構築

Table of Contents

はじめに

フロントエンドの勉強を初めて約1年、Next.jsに出会ったことで作りたいと思ったものは大体実装できるようになってきました1
この1年はWebアプリを作ることに注力してきましたが、最近はモバイルアプリを作りたいと思うことが多くなってきました。
一応、作りたいアプリのアイディアが現状でも3つほどあるので、今後これを形にしていきたいと思っています。

そのため、ずっと勉強したいと思って放置していたFlutterについに向き合うことにしました。
今回は、なぜFlutterを選んだのかという個人的な背景とWSL2上のUbuntu20.04にFlutterの開発環境を構築する手順の備忘録です。
同じように悩んでいる人の参考になれば嬉しいです。

モバイルアプリ開発のイマ

モバイルアプリ開発の手法は近年多様化しています。
それは、AndroidとiOSアプリを別々で実装するネイティブ開発に加え、FlutterやReact Nativeなどのクロスプラットフォーム開発が発達してきた影響です。

従来、モバイルアプリ開発と言えば、AndroidはJava (数年前からはKotlinも)、iOSはSwiftで開発されていました。
しかし、別々で開発するということは管理すべきコードが2つになるということです。
アップデートやバグ修正の手間もそれだけ増大してしまいます。

そのような中、1つのコードでAndroidとiOSアプリをどちらも開発してしまおうということで開発されたのがFlutterやReact Nativeなどのクロスプラットフォームフレームワークです。
複数環境で動作するアプリを1つのコードで実装できるということは、前述のソースコードの管理コストに加え、学習する言語も1つで良いという学習コストの削減にも繋がります。
例えば、FlutterだとDartという言語で開発しますし、React Nativeの場合はJavaScriptで開発します。

しかし、AndroidやiOSアプリのネイティプ開発が時代遅れになったのかと言うとそんなことはありません。
近年では、クロスプラットフォーム開発からネイティプ開発に移行したという例も見かけるようになってきました。

なぜネイティブ開発を選択するのかというと、以下の点でクロスプラットフォーム開発よりも優れているからだと思います。

  • パフォーマンスが良い
  • OSのアップデートに追従しやすい
  • OSレベルの新機能への対応が早い

したがって、最初に述べた通り、モバイルアプリ開発の手法が多様化し、選択肢が増えていると考えるのが良いと思います。

なぜFlutterなのか

選択肢が増えることは良いことであるのは間違いないですが、その分悩むことが増えるということでもあります。
混乱する頭を整理するためには、以下の2ステップで検討するのが良いと思います。

ネイティブかクロスプラットフォームか

この点は自身の持つ技術にも影響される要素です。
しかし、個人開発の場合はほぼ間違いなくクロスプラットフォーム開発が良いのではないかと思います。
企業レベルで開発など、AndroidとSwiftそれぞれのエンジニアを確保できるのであれば良いですが、個人開発や小規模なチーム開発で2つのソースコードをメンテナンスするのは辛いものがあると思います。

ちなみに私の技術レベルで考えると、10年前くらいにAndroidアプリを趣味で作っていました。
Androidのバージョンで言うと、2.xの時代です。
その頃はまだAndroid Studioもなく、Eclipseで開発していた覚えがあります。
そのため、現在のAndroidネイティプ開発についてはほぼ知識を持っていないことになります。
ちなみにiOSアプリの開発は行ったことがありません (そもそもAndroidユーザーなので…)。
AndroidとiOS、2つのアプリ開発を別々に学ぶのは現実的ではないと思ったので、私はクロスプラットフォーム開発を選択しました。

FlutterかReact Nativeか

クロスプラットフォーム開発のフレームワークとして何を選択するか?というのが2ステップ目です。
これは現状だとFlutterかReact Nativeの2択になるかと思います。
もちろん、Xamarinなど他にもフレームワークは存在しますが、盛り上がり具合などを考えると、前述の2つから選択しておくのが良さそうです。

FlutterとReact Nativeの概要をまとめると以下の通りです。

FlutterReact Native
開発元GoogleFacebook
言語DartJavaScript
初版リリース2018年2015年

ここで注目すべきは、Flutterの開発元はAndroidの開発元であるGoogleであるということです。
GoogleはFlutterの開発にかなり力を入れているため、少なくともAndroid開発に関してはネイティプ開発との差が縮まっていくのではないかと考えられます。
また、急にプロジェクトが終了することがなさそうなことも重要です。

一方、ReactNativeはJavaScriptで開発できることが魅力です。
私は実際に触ってはいないのですが、書き方を見た感じだとReactのコードに非常に近いと感じました。
私もNext.js使いなので、はじめはReact Nativeを選択しようと思いました。

しかし、色々考えた結果、以下の理由からFlutterを選択しました。

  • 現時点でFlutterの方が優勢の模様
  • 開発元Googleへの期待
  • Dartの学習コストがそこまで高くなさそう
  • React Nativeなら最悪乗り換えることになってもそこまでハードルが高くなさそう
  • 新しい言語を勉強するの楽しい 2

正直、どちらを選んでも良いと思います。
そんなことより早く勉強をはじめることの方が価値が高そうです (散々悩んだ自分への戒め)。

なぜWSL2上に環境構築するのか?

私は普段、自宅ではWindows端末を使っています。
一方、職場ではUbuntuをメインで使っています。
なるべく自宅と職場の環境を揃えたいため、自宅のPCではWSL2上のUbuntu20.04でプログラミングしています。
Windows上で直接開発しようとすると、環境構築でコケる事が多いのでなるべくWSL2上でやった方が楽なことが多いです。

ということでFlutterでのモバイルアプリ開発環境もWSL2上に構築することにしました。
以下、その作業の備忘録として残しておきます。

WSL2へのFlutter環境構築手順

Flutterの環境構築手順をステップを分けて、順番に説明いたします。
今回は、VSCodeでコーディングを行い、Androidの実機でワイヤレスデバッグできる状態までを目指します。
なお、WSL2のインストールやUbuntuの導入などについては割愛します。

また、私はシェルとしてzshを使っています。
それ以外のシェルを使っている場合は適宜読み替えて下さい。

JavaSDKのインストール

sudo apt install default-jdk
echo "\n\nexport JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64\nexport PATH=\$PATH:\$JAVA_HOME/bin\n" >> ~/.zshenv
source ~/.zshenv

AndroidSDKのインストール

mkdir -p ~/android/sdk/cmdline-tools
wget https://dl.google.com/android/repository/commandlinetools-linux-7302050_latest.zip -O latest.zip
sudo apt install unzip
unzip latest.zip
mv cmdline-tools ~/android/sdk/cmdline-tools/latest
rm -rf latest.zip
echo "\nexport ANDROID_HOME=\$HOME/Android/SDK\nexport PATH=\$PATH:\$ANDROID_HOME/cmdline-tools/latest/bin\n" >> ~/.zshenv
source ~/.zshenv
sdkmanager

sdkmanagerコマンドを実行し、以下の出力が表示されればOKです。

[=======================================] 100% Computing updates..

次に、adb(Android Debug Bridge)を使うため、platform-toolsをインストールします。

sdkmanager --install "platform-tools"
echo "\nexport PATH=\$PATH:\$ANDROID_HOME/platform-tools\n" >> ~/.zshenv
source ~/.zshenv
adb

adbコマンドでhelpが表示されればOKです。

次に、AndroidSDKをインストールします。
2021年10月現在はAndroid11 (APIレベル31)が最新バージョンなので、それをインストールします。
なお、インストールできるイメージは以下のコマンドで確認できます。

sdkmanager --list

インストールするイメージを選択して、インストールします。

sdkmanager --install "system-images;android-31;google_apis;x86_64" "platforms;android-31" "build-tools;31.0.0"

その後、インストールしたイメージのライセンスに同意する必要があります。
以下のコマンドを実行し、全て同意していきます。

sdkmanager --licenses

Flutterのインストール

公式ページで最新バージョンを確認し、インストールします。
2021年10月現在は2.5.2が最新バージョンなので、それをインストールします。

mkdir ~/flutter
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_2.5.2-stable.tar.xz
tar xf flutter_linux_2.5.2-stable.tar.xz
mv flutter ~/flutter/sdk
echo "\nexport FLUTTER_ROOT=\$HOME/flutter/sdk\nexport PATH=\$PATH:\$FLUTTER_ROOT/bin\n" >> ~/.zshenv
source ~/.zshenv

以下のように、Flutterのバージョンか出力されればOKです。

$ flutter --version

Flutter 2.5.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 3595343e20 (3 days ago) • 2021-09-30 12:58:18 -0700
Engine • revision 6ac856380f
Tools • Dart 2.14.3

flutter doctorコマンドを実行し、問題なく環境構築ができていることを確認して下さい。
私は以下のような出力結果となりました。

$ flutter doctor

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.5.2, on Ubuntu 20.04.3 LTS 5.4.72-microsoft-standard-WSL2, locale ja_JP.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Chrome - develop for the web
[!] Android Studio (not installed)
[✓] Connected device (1 available)

! Doctor found issues in 1 category.

VSCodeの拡張機能のインストール

WSL2環境でVSCodeを起動し、拡張機能をインストールします。
以下のコードでVSCodeを起動します。
なお、VSCodeのインストール手順については割愛します。

code .

以下の拡張機能をインストールします。

Flutter拡張機能をインストールすると、以下のDart拡張機能もインストールされるかと思います。
確認しておいて下さい。

ここまでで環境構築は完了です。

プロジェクトの作成と実機でのワイヤレスデバッグ

プロジェクトの作成

以下のコマンドでFlutterプロジェクトを作成できます。
(test_appはプロジェクト名です。自由な名前を設定してOKです。)

flutter create test_app

Android端末でのワイヤレスデバッグ

ワイヤレスデバッグを有効にするため、Android端末の設定を変更します。
なお、私はGoogle Pixel5 (Android 11)を使っています。
端末によって設定画面が若干異なる場合があります。

開発者向けオプションの有効化

はじめに、開発者向けオプションを有効化します。
「設定」→「デバイス設定」→「ビルド番号」を7回タップして下さい。
有効化されると、「設定」→「システム」内に「開発者向けオプション」という項目が増えます。

ワイヤレスデバッグの有効化

「設定」→「システム」→「開発者向けオプション」の「ワイヤレスデバッグ」をONにします。
以下のような確認画面が表示されるので、「許可」をクリックします。

ワイヤレスデバッグの許可

その後、「ワイヤレスデバッグ」→「ペア設定コードによるデバイスのペア設定」をタップします。
以下のようにペア設定コードおよびIPアドレスとポートが表示されます。
この情報を使ってペアリングを行います。

ペアリング設定

端末とペアリング

先ほどのIPアドレスとポートを使ってペアリングを行います。

$ adb pair 192.168.xxx.xxx:40461

Enter pairing code: 074061
Successfully paired to 192.168.xxx.xxx:40461 [guid=adb-xxxxxxxxxxxxxx-xxxxxx]

このペアリングの設定は1度行えば、2回目以降は不要です。

端末と接続

では端末と接続します。
このときはペアリングのときに使用したポートとは異なり、「開発者向けオプション」→「ワイヤレスデバッグ」の「IPアドレスとポート」に表示されているポート番号を使用します。

接続設定

では、接続してみましょう。

$ adb connect 192.168.xxx.xxx:38235

connected to 192.168.xxx.xxx:38235

接続している端末は以下のコマンドで確認できます。
以下の例では、Chromeも表示されていますが、Android端末が接続されていればOKです。

$ flutter devices

2 connected devices:

Pixel 5 (mobile) • 192.168.xxx.xxx:38235 • android-arm64  • Android 11 (API 30)
Chrome (web)     • chrome             • web-javascript • Google Chrome 94.0.4606.71

実機での実行

プロジェクトのディレクトリに移動し、VSCodeで開きます。

cd test_app
code .

lib/main.dartを開き、F5キーを押してデバッグを開始します。
ビルドに少し時間がかかりますが、無事ビルドが完了すると以下のようにサンプルアプリが起動します。

アプリの起動

無事起動できていれば、今回の環境構築は完了です!

まとめ

これでWSL2上でFlutterによるモバイルアプリ開発環境が整いました。
これからはFlutterを勉強して、作成したいアプリを開発できるように力をつけたいと思います。

Footnotes

  1. 効率的に書けるようになったとは言っていない

  2. 筆者はプログラミング言語の設計思想などを考えるのが好きな自称プログラミング言語マニアです。完全に趣味です。

Author Profile
liebe-magi

りーべ / liebe-magi

ものづくりが大好きな自称フルスタック(?)エンジニア。大学・大学院でコンピュータサイエンスを専攻し、現在は某企業の研究所所属。専門は組み合わせ最適化問題や機械学習など。主に使用している言語はPython、JavaScript (TypeScript)、Rust、Go。最近は競技プログラミングに興味を持ち、AtCoderのコンテスト (ABC) に毎週参加中 (現在緑)。趣味はマジック、漫画・アニメ、ゲーム(電源・電源問わず)。