Smile Engineering Blog

ジェイエスピーからTipsや技術特集、プロジェクト物語を発信します

Vite2+Capacitor2でWEB&モバイル開発環境構築

1つのソースコードで、WEB・モバイル端末・デスクトップ向けのアプリを開発するプラットフォームは、「ReactNative」「Flutter」「Xamarin」「Uno Platform」「Unity」などが有名で、それぞれ特徴を持っています。
当記事では、Vueの開発におけるホットリロードを高速化する「Vite」をベースにプロジェクトを作り、「Capacitor」を追加した環境を作ります。 その環境を使い、1つのVueコードでWEB・Androidアプリのプロダクトビルドを実行するまでをお伝えします。(iOSアプリの生成も可能なようです)
デバッグや動作確認は、Viteのプロジェクト生成時のサンプルを使っています。

なぜ「Vite+Capacitor」か

やはりVueによるWEB開発に慣れたチームがモバイルアプリも生成するには最適です。
WEBとモバイルアプリの共通機能のデバッグにおいて、「Vite」の高速なホットリロードの恩恵を十分受けられます。
例えば「Flutter」でもホットリロード機能がありますが、「Vite」の方がブラウザへの反映が体感でも速いと思います。
また、Vueの様々なエコシステムをモバイルアプリに適用できる可能性もあります。
例えば、以下でも記載しますが、JavaScriptによるCSSフレームワークである「Tailwind CSS」や、http通信フレームワークの定番「axios」は、一部の機能しか確かめていませんが、Androidアプリでも全く同じように機能が適用されることを確認しました。
ただ、今は動作しても、今後プロジェクトで採用するVueやJavaScriptフレームワーク・ライブラリが動くか、またそれらがバージョンアップしたときにも、あるいはAndroidiOSがバージョンアップしたときにも、きちんと動作することを「Capacitor」が担保できるかが心配ではあります。
長期保守を検討する場合は、「Capacitor」の企業向けサイトの情報が参考になるかもしれません。

ところで、プロジェクト生成時のサンプルソースをほぼそのまま、プロダクト版でビルドしたファイルサイズは、WEBもAndroid(apk)も「Vite2+Capacitor2」のほうが「Flutter2」より小さいようでした。(下表参照)

Vite2+Capacitor2 Flutter2
WEB 64KB 3.1MB
Android(apk) 1.6MB 15.3MB

※WEBはMAPファイルは含めていません。

サンプルは完全に同一ではありませんが、双方ともタイトルの表示と+ボタンで1ずつ加算結果を表示するだけのアプリです。それだけの機能でしかないのに、結構差が大きい気がします。

ですが、モバイル機能中心の開発・デバッグは、Flutterなど他のプラットフォームのほうがよいかもしれません。 特にモバイルアプリはCapacitorの仕様によりWebViewで動作しますので、FlutterやReactNativeなど、ネイティブ寄りのプラットフォームのほうが機能によっては高速に動作するかもしれません。(ただ、Capacitorのホワイトペーパーでは、「WebViewがモバイルで遅いと考えるのはもう古いよ」と言ってます)

開発のライフサイクル概要

最初にyarnでviteベースの初期プロジェクトフォルダを生成し、WEBとモバイルで共通の機能をVueの開発手法に従ってコーディングしていきます。
エディタやIDEVisual Studio Codeなど、何でもかまいません。デバッグはViteで用意されたサーバをコマンドラインから起動し、WEBブラウザIDEで確認しながら行います。
Visual Studio Codeですと、「Debugger for Firefox」というプラグインを追加し、<プロジェクトルート>/.vscode/launch.jsonに設定を加えると、デバッガでブレークポイントの設置・ステップ実行・変数値の確認ができるようになります。

WEBのプロダクトビルドファイルは、Viteのコマンドを実行して生成します。
一方、モバイル特有の機能(カメラやGPSなど)の動作確認や、モバイルのプロダクトビルドは、Andorid StudioやXCodeから行います。(当記事では、iOSアプリ向けのXCodeによるデバッグやビルドは割愛しています) Capacitorの機能で、WEBのプロダクトビルドファイルをベースに、AndroidiOS用のプロジェクト上にWebViewコードが生成されるようになっています。
つまり、基本的に毎回WEBのプロダクトビルドを行ってから、シミュレータや実機で動作確認、Andorid StudioやXCodeでビルドという手順を踏みます。他のマルチプラットフォーム開発環境と比べると、この手順が煩わしいと感じます。
さらに、Andorid StudioやXCodeブレークポイントの設置、ステップ実行でモバイル機能のデバッグができないのも難点と思います。

一方、例えばFlutterであればWEB向けモバイル向け関係なく、同じ方法でブレイクポイント設置、ステップ実行、変数値の確認ができますし、ビルドもflutter build web flutter build apk flutter build ipaなどとコマンドを実行するだけでよく、開発環境として洗練されているように思いました。

なお、モバイル特有の機能のコーディングは、Viteプロジェクト内のVueの中で、JavaScriptまたはTypeScriptで記述します。
このとき、import { Plugins, CameraResultType } from '@capacitor/core'などとして、Capacitorより必要機能をインポートします。

動作確認した環境

ソフト バージョン 説明
Linux Mint 20.1 Ubuntuベースのディストリビューション
Node.js 14.16.0 JavaScript実行環境
NPM 6.14.11 JavaScriptパッケージ管理
Yarn 1.22.10 NPM互換のJavaScriptパッケージ管理システム
Vite 2.1.0 高速なVueベースのWEBデバッグ・ビルド環境
Vue 3.0.5 WEB開発フレームワーク
TypeScript 4.1.3 静的型付け・オブジェクト指向のWEB開発言語
Capacitor 2.4.7 WEBビルドファイルのモバイル開発環境への橋渡しツール
Android Studio 4.1.2 Androidデバッグ・ビルド環境

「Vite」の開発環境を構築

Node.js・NPM インストール

sudo apt install nodejs npm

NPM を最新版に

sudo npm install -g npm

n インストール

sudo npm install -g n

n を使って NodeJS を最新安定版に

sudo n stable

旧バージョンのNodeJS・NPM を削除

sudo apt purge nodejs npm

ログインシェル起動

exec $SHELL -l

バージョン確認

node -v

npm -v

Yarn インストール

sudo npm install -g yarn

Yarn バージョン確認

yarn -v

※最新バージョンのYarn2系では、「Vite」のコマンドは実行可能でしたが、「Capacitor」のコマンドはエラーで実行できませんでした。

Viteプロジェクト生成

ここでは「test_vite」というプロジェクトをホームフォルダの「develop」フォルダに生成する例とします。

cd $HOME/develop

yarn create @vitejs/app test_vite

コマンドを実行すると「? Select a template: … 」とメッセージが表示されます。 TypeScriptを使うとして「vue-ts」を選択してEnterキーを押下します。 すると、「develop」フォルダ配下に「test_vite」フォルダが生成され、その配下に以下のファイル群が生成されます。

├── README.md
├── index.html
├── package.json
├── public
│   └── favicon.ico
├── src
│   ├── App.vue
│   ├── assets
│   │   └── logo.png
│   ├── components
│   │   └── HelloWorld.vue
│   ├── main.ts
│   └── shims-vue.d.ts
├── tsconfig.json
└── vite.config.ts

これでプロジェクトフォルダの生成は完了です。 Visual Studio Codeなどで、当フォルダをプロジェクトルートに設定するとよいと思います。

WEBのデバッグ

NPMによるモジュールのインストール

cd $HOME/develop/test_vite
yarn
プロジェクトフォルダへ移動し、「yarn」コマンドを実行します。
「package.json」を参照し、Node.jsで管理されたJavaScirptのライブラリがインターネットよりダウンロードされてきます。

デバッグサーバの起動

yarn dev
プロジェクトフォルダにて、「yarn dev」コマンドを実行します。
サンプルアプリが読み込まれ、以下のようなメッセージが表示されて、デバッグサーバが起動します。

  vite v2.1.2 dev server running at:

  > Local:    http://localhost:3000/
  > Network:  http://192.168.11.143:3000/

WEBブラウザで「http://localhost:3000」にアクセスすると、下図のようなサンプルアプリの画面が表示されます。

f:id:jspnet:20210317190015p:plain
Viteサンプルアプリ画面

「count is: 0」のボタンをクリックすると、1ずつ増えていきます。

プログラムの修正

デバッグサーバは起動したまま、WEBブラウザを開いたままの状態でソースコードを修正すると、一瞬でWEBブラウザに反映されます。
デザインや動作をまめにチェックしながら、開発を進めることができます。
カメラやGPSなど、モバイル特有の機能の動作は、ここでは確認できません。後述しますが、Capacitorをプロジェクトに追加後、Andoroid Studioなどから起動するエミュレータなどで動作確認します。
モバイルアプリと共通の機能は粗方ここで確認してもよいかと思いますが、厳密なテストはエミュレータや実機で実施したほうがよいでしょう。 デバッグサーバを終了するときは、プロンプトでCtrl+Cキーを押下します。

WEBのプロダクトビルド

cd $HOME/develop/test_vite
yarn build

プロジェクトフォルダへ移動し、「yarn build」コマンドを実行します。
すると、プロジェクトフォルダに「dist」というフォルダが生成されます。そのファイル群を本番環境のWEBサーバにデプロイします。 「dist」フォルダ内は以下の構造になっており、これらファイルサイズの合計が上記表の「Vite2+Capacitor2」に記載した64KBになっていました。

dist
├── assets
│   ├── index.e108508f.css
│   ├── index.e30e4e65.js
│   ├── logo.03d6d6da.png
│   └── vendor.6801b2a0.js
├── favicon.ico
└── index.html

Andorid Studioのインストール

Androidアプリのデバッグ・ビルド環境であるAndorid Studioをインストールします。
Linux Mintの「ソフトウェアマネージャ」よりAndorid Studioを検索すると、執筆時点での最新版(4.1.2)をインストールできました。

f:id:jspnet:20210318160433p:plain
Linux Mint ソフトウェアマネージャ起動

f:id:jspnet:20210318160632p:plain
Linux Mint での Android Studioインストール

Capacitorの追加

NPMによるモジュールのインストール

ViteプロジェクトにNPMを利用してCapacitorを追加します。

cd $HOME/develop/test_vite
yarn add @capacitor/core @capacitor/cli

なお、yarn add @capacitor/cli@next @capacitor/core@next とすると、最新ベータ版が追加されます。執筆時点ではバージョン「3.0.0-rc.0」が追加され、以後のコマンドも一応すべて問題なく実行できました。

Capacitorプロジェクトの初期化

次に以下のコマンドを実行し、初期化します。
npx cap init

質問のプロンプトが表示されますので、入力します。

  • Name:test_vite(プロジェクト名)
  • Package ID:com.test(モバイルアプリのパッケージID)
  • Web asset directory:dist(WEBのプロダクトビルドファイルを読み込むパス(yarn build出力先))

もし入力を誤った場合は、実行後にプロジェクトルートに生成されたcapacitor.config.tsを削除し、再度npx cap initを実行すればやり直せます。

さらに以下のコマンドを実行し、AndroidiOS用のモジュールを追加します。
npx cap add android
npx cap add ios

最新ベータ版は、yarn add @capacitor/ios@next @capacitor/android@next で追加できます。

Android Studio の起動ファイルのパスを追加

以降のAndroidデバッグ時のcapacitorのコマンドを実行した際、自動でAndroid Studioを起動させるため、環境変数CAPACITOR_ANDROID_STUDIO_PATHAndroid Studio の起動ファイルのパスを設定します。
「Andorid Studioのインストール」の手順を実施していた場合、実行ファイルのパスは以下になります。
/var/lib/flatpak/app/com.google.AndroidStudio/current/active/files/extra/android-studio/bin/studio.sh
これを環境変数に追加するため、以下のコマンドを実行するとよいでしょう。
echo "export CAPACITOR_ANDROID_STUDIO_PATH=\"/var/lib/flatpak/app/com.google.AndroidStudio/current/active/files/extra/android-studio/bin/studio.sh\"" >> $HOME/.profile

ZIPの解凍など、他の手順でAndroid Studioをインストールした場合でも、studio.shファイルのパスをCAPACITOR_ANDROID_STUDIO_PATHに設定しておけばよいと思います。 これで最低限のモバイルアプリのデバッグ・ビルド環境ができました。ここまでは環境構築なので1度行うだけで大丈夫です。

Andoridでの動作確認

WEBのプロダクトビルド

Andoridアプリでの動作を確認する際、まず最初にWEBのプロダクトビルドを実行します。
上記でお伝えしたように、プロジェクトルートフォルダへ移動し、yarn buildコマンドを実行して「build」フォルダにプロダクトビルドファイルを生成します。

なお、デバッグ前に当然コーディングをするわけですが、基本的にはカメラやGPSなど、WEBでは使えないモバイル端末専用の機能のデバッグが主になるでしょう。
具体的なコーディング方法はCapacitorの公式サイトや紹介サイトをご覧ください。ご参考までに、公式サイトからカメラ機能について以下のとおり引用します。

import { Plugins, CameraResultType } from '@capacitor/core';
const { Camera } = Plugins;
async takePicture() {
  const image = await Camera.getPhoto({
    quality: 90,
    allowEditing: true,
    resultType: CameraResultType.Uri
  });
  var imageUrl = image.webPath;
  imageElement.src = imageUrl;

上記のとおり、TypeScriptやJavaScript@capacitor/coreより必要機能をインポートします。

Androidプロジェクトへコピー

以下のCapacitorのコマンドを実行することで、WEBのプロダクトビルドファイルをベースにAndroidプロジェクトへコピー&変換されます。
npx cap sync

Android Studioを起動

以下のCapacitorのコマンドを実行することで、コピー&変換されたAndroidプロジェクトがAndroid Studioにて開かれます。
npx cap open android

Android Studioで動作確認

あとは、Android Studioの標準機能に従ってデバッグビルドを行い、エミュレータや実機で動作を確認します。
メニュー「Run」→「Run」を選択するとエミュレータが起動し、動作確認ができます。 f:id:jspnet:20210322204919p:plain

f:id:jspnet:20210323150827p:plain
エミュレータでアプリを起動
「count is: 0」のボタンをクリックすると、1ずつ増えていきます。
ここで、Android Studioで「Debug...」を選択してエミュレータを起動しても、ソースがブレークポイントを置けるものではないので、意味がありません。ただ重いエミュレータがさらに重くなるだけです。ステップ実行や変数値チェックができないのはつらいところ....

また、Flutterのようにホットリロード機能がありません。
Vue系のファイル修正の都度、エミュレータを停止 → yarn buildnpx cap syncAndroid Studioで「Run」でエミュレータを起動...の流れに、手間・時間がかかりそうです。エミュレータの起動でも30秒、停止で10秒ほどかかりますし....
これが、モバイル専用機能が多い場合にお勧めしづらい点です。WEBと完全に同一の機能をモバイルアプリでも提供するか、極簡単なカメラやGPSなどの機能を付けるだけのアプリなら問題ないかもしれません。

Andoridのプロダクトビルド

Android Stuidoの標準機能でプロダクトビルド、.apkファイルの生成を行います。
Vueで修正 → yarn buildnpx cap sync までは前項の動作確認手順と同じです。

通常のAndoridアプリ開発同様、Android SDKSDK Platforms)のバージョンに注意を払う必要がありますが、CapacitorのバージョンとAndroid SDKのバージョンがリンクしているようです。つまり、Capacitor2.4.7だとAndroid10.0が、最新ベータ版のCapacitor3.0.0-rc.0だとAndroid11.0が動作可能なバージョンのようです。

f:id:jspnet:20210322194815p:plain
Android Studio Settings画面

プロダクトビルドですが、基本的にはAndroid Studioで最初にアプリの署名の設定をした上でビルドします。
メニュー「Build」→「Generate Signed Bundle / APK」を選択します。
f:id:jspnet:20210322200405p:plain

次に「APK」を選択し、「Next」ボタンをクリックします。
f:id:jspnet:20210322200555p:plain

一度も署名キーファイルを作成したことがなければ、ここで「Create new...」を選択します。
f:id:jspnet:20210322200643p:plain

署名に必要な情報を入力し、「OK」ボタンをクリックします。「Key store」の「Password」や「Key」の「Password」は、この次の画面ですぐ利用しますので、記憶しておいてください。
「Key store path:」に入力情報が保存されます。次回ビルド時より同じ入力をしなくて済みますので、保管しておきましょう。
f:id:jspnet:20210322200919p:plain

前画面で入力した「Key store」の「Password」や「Key」の「Password」を入力し、「Next」をクリックします。
f:id:jspnet:20210322201133p:plain

Destination Folder:」にはビルドファイルの保存先を指定します。初期値のままでよければ、覚えておいてください。「Build Variants:」は「release」を、「Signature Versions:」にはアプリに応じて選択し、「Finish」をクリックします。
f:id:jspnet:20210322201654p:plain

そうしますとGradleが実行され、サンプルアプリであれば20秒ほどでビルドファイルが「Destination Folder:」に生成されます。
f:id:jspnet:20210322201937p:plain

この「app-release.apk」ファイルをUSBケーブルやWi-FiなどでAndroid端末へコピーし、起動すれば、インストールできるようになります。Playストアへの公開対象にもなります。
2回目以降であれば、上記は初期値として入力済みの状態となり、手間が少なくビルドできると思います。

f:id:jspnet:20210323153935p:plain
インストールしてAndroidスマホに生成されたアイコン
f:id:jspnet:20210323155345p:plain
Androidスマホでアプリを起動
WEBやエミュレータ同様、「count is: 0」のボタンをクリックすると、1ずつ増えていきます。

まとめ

長い手順になりましたが、繰り返し操作していると慣れてきて、早く開発できるようになると思います。
記事中Flutterと比較しましたが、どちらも一長一短、向き不向きがあるので注意です。
クロスプラットフォームの開発環境を検討されている方向けに、参考になれば幸いです。