2024/07/16

NeovimでFlutterの開発環境を構築する

ようやくSwiftに馴染んできたと思ったら次の案件はFlutterだと言う。まだ具体的な時期は決まっていないが今年中の話には違いない。面接で「あらゆる技術領域にチャレンジしたい」などと自信満々にアピールしたことがボディーブローのように効いてきている。

とはいえ、良い話もある。SwiftでのiOSアプリ開発はXcodeの使用が絶対条件だがFlutterはVimで書ける。Xcodeを使うとしたらビルド周りの設定をする時だけだ。その上、よほど込み入った作りでなければ共通のコードでAndroidアプリも開発できるため受託側としては工数が少なく非常に都合が良い。いちコーダーとしては、単純なモバイル案件は全部FlutterかReact Nativeで受ければいいじゃんと感じてしまうがそうもいかない事情があるのだろう。

なんにせよまずは環境構築である。例によって会社の財布から教本を召喚して早めに勉強に取り掛かる。Swiftの時は入社直後だったため徒手空拳での対応を余儀なくされたが、今回は幾ばくかの猶予が残されている。毎日こつこつとキャッチアップしていれば正式なアサイン後には最低限動けるようになっているはずだ。

Flutterの導入および設定

手始めにFlutterのパッケージを導入する。以下に続く記述はLinux環境を想定しているが、WindowsのWSL環境やmacOSのターミナル環境でも大差はないと思われる。各々のディストリビューションの作法に従いflutterパッケージをインストールした後、flutter doctorコマンドの実行を行う。

 1~
 2❯ flueter doctor
 3Doctor summary (to see all details, run flutter doctor -v):
 4[] Flutter (Channel , 3.22.2, on Arch Linux 6.9.9-arch1-1, locale ja_JP.UTF-8)
 5[] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
 6[] Chrome - develop for the web
 7[] Linux toolchain - develop for Linux desktop
 8[] Android Studio (version 2024.1)
 9[] IntelliJ IDEA Ultimate Edition (version 2024.1)
10[] Connected device (2 available)
11[] Network resources
12
13• No issues found!

上記のコマンドはFlutterの開発環境を精査するもので、たとえばAndroidアプリを作る場合には少なくともAndroid toolchainAndroid Studioにチェックマークが入っていなければならない。macOSで実行した場合には別途、Xcodeなどの項目も現れる。目的がiOSアプリ開発ならそれらの導入が要求される。

といっても特に難しい要素はなく、基本的には指定されているソフトウェアを順次取り入れると要件をクリアできる。たとえばAndroid関連の項目にチェックマークが入っていないのなら、android-studioパッケージを導入して起動し、ウィザードに沿って必要最低限の初期設定を済ませれば解決する。ついでにSDK ManagerSDK ToolsからAndroid SDK Command-line Toolsにチェックを入れておくとAnroid toolchainの項目も満たすことができる。

最後にflutter doctor --android-licensesでライセンス条項に同意すると、Androidアプリ開発の要件が完全に満たされる。任意のディレクトリ下でflutter createを実行し、雛形のプロジェクトが作成されるか確認しよう。続けてflutter runでエミュレータ(デフォルトではWebアプリ開発用のエミュレータが立ち上がる)が立ち上がれば正常に動作している。

flutter-tools.nvimの導入および設定

FlutterではDartというaltJSな言語が用いられる。大抵の言語ではmason-lspconfig.nvim経由でLSPを導入するか、さもなければnvim-lspconfigの設定を書く形が通例だが、Flutterに関してはflutter-tools.nvimを導入するだけでDartのLSPも含めた実行環境が完成する。導入にはlazy.nvimなど任意のプラグインマネージャを用いるものとする。

 1require("flutter-tools").setup({
 2    ui = {
 3        border = "none",
 4    },
 5    dev_log = {
 6        enabled = false,
 7    },
 8    debugger = {
 9        enabled = true,
10        run_via_dap = true,
11    },
12})
13
14vim.keymap.set("n", "<leader>0", require("telescope").extensions.flutter.commands, { desc = "Open command Flutter" })
15vim.keymap.set("n", "<leader>r", ":FlutterReload<CR>", { silent = true, desc = "Flutter Reload" })
16vim.keymap.set("n", "<leader>R", ":FlutterRestart<CR>", { silent = true, desc = "Flutter Restart" })

上記は暫定的に定めた僕の個人設定だ。flutter-tools.nvimを入れるとLSPのみならずFlutterのCLI操作(flutter runなど)もVimから行えるようになるが、そのたびにログがスプリットで表示されるのはあまり嬉しくないためdev_logを無効化している。また、頻繁に使いそうなFlutter ReloadおよびFlutter Restartにはキーマップをあてがい、その他はTelescopeから呼び出す形にした。

 1local dap = require("dap")
 2
 3dap.adapters.flutter = {
 4    type = "executable",
 5    command = "flutter",
 6    args = { "debug_adapter" },
 7}
 8
 9dap.configurations.dart = {
10    {
11        type = "flutter",
12        request = "launch",
13        name = "Launch Flutter Program",
14        program = "${workspaceFolder}/lib/main.dart",
15        cwd = "${workspaceFolder}",
16    },
17}

さらに、以前に紹介したnvim-dapとの連係も一応有効にしておく。debuggerenabled = trueかつrun_via_dap = trueとすることで機能が働くようになる。現状では起動確認のために最小限の実行オプションのみを作り、上記の要領でnvim-dapの設定に追記を行った。以上でFlutterの環境構築は完了である。

動作確認

:FlutterEmulatorsで任意の仮想デバイスを呼び出してから:FlutterRunを実行すると、プロジェクトが読み込まれた状態でエミュレータが立ち上がる。後はひたすらコードを書いていくだけだ。ホットリロードに対応しているおかげであたかもWebサービスのごとくモバイルアプリを実装できる。これは畑違いの僕にも元来よく馴染んだ開発スタイルでたいへん体験が良い。やっぱり全部こんな感じになってくれないかな。

©2011 Rikuoh Tsujitani | Fediverse | Keyoxide | RSS | 小説