LoginSignup
1
2

More than 1 year has passed since last update.

Cordova & React & TypeScript 環境構築&デバッグ手順 (2021年10月時点)

Last updated at Posted at 2021-10-20

2021年10月時点で Cordova & React & TypeScript の環境作成とデバッグを行う手順です。

参考ページ通りの手順を行っても、環境の問題でビルドが失敗することが多かったので、

成功するまでの試行錯誤をまとめました。

目的

  • Cordova+Reactでアプリを作成し、Android実機上でTypeScriptのデバッグを行う。

前提

  • create-react-app を使い、ビルド、実行、パッケージの追加ができること
  • Windows10

作成したソース一式

概要手順

  • ①cordova環境でreactの動作確認を行う(ブラウザ)
    1. cordovaのインストール(npm)
    2. react用プロジェクトと、cordova用プロジェクトを作成する
    3. cordova用フォルダから、config.xmlをreact用フォルダにコピーする
    4. reactのビルドフォルダを「build」⇒「www」に変更する
    5. reactの「public/index.html」ファイルを修正。cordova化に必要な<meta>タグをとcordova.jsの読み込み追加する
    6. reactの「src/index.ts」を変更する。
    7. reactをビルドしてから、cordova run browserで動作確認を行う
  • ②android用モジュールのビルド環境作成とビルド
    1. Android Studioのインストール
    2. JDK8をインストール
    3. Gradle(ビルド自動化システム)のインストール
    4. ビルドに必要な環境がそろっているかcordova requirementsで確認
    5. Andoroid向けにビルドを行う (失敗します・・・)
    6. ビルドエラーの対処① (メモリ不足エラー)
    7. ビルドエラーの対処② (SDK Build-tool に不足しているファイルへの対処)
    8. ビルドが正常終了することを確認
  • ③Android実機での実行
    1. Android端末の「USBデバッグ」を有効にする
    2. PCとAndroid端末をUSBで接続する
    3. 接続したAndroid端末が、cordova側から認識されていることを確認
    4. 実機でアプリを実行する
  • ④Androidでアプリをデバッグ実行 (soucemapを手動読み込み)
    1. 実機でアプリを実行する
    2. PCのChromeからリモートデバッグを行う
    3. TypeScriptソースでのデバッグを可能にするためsourcemapを追加
  • ⑤create-react-appのビルド設定を変更し、sourcemapをインライン化する(手動読み込み不要)
    1. webpackの設定を変更するため、rewireを追加する
    2. プロジェクト直下にbuild.jsを作成し、webpackの設定を変更するスクリプトを記載する
    3. package.jsonのscriptsに、ビルド用スクリプトを追加する
  • ⑥Cordova pluginを利用する(cordova-plugin-vibration)
    1. pluginを追加
    2. pluginを利用する

Emulatorでの確認はしていません。ディスク空き容量の関係で構築できなかったためです

①cordova環境でreactの動作確認を行う(ブラウザ)

cordovaのインストール(npm)

cordovaをグローバルインストールします(ローカルインストールだと動きません)

npm install -g cordova

react用プロジェクトと、cordova用プロジェクトを作成する

craでreactアプリを作成する

npx create-react-app hello-cordova-react --template typescript --use-npm

Cordova プロジェクトを作成する

cordova create hello-cordova com.example.cordova hello-cordova

下記のメッセージが出た場合 cordova telemetry onを実行してから、Cordova プロジェクトを作成する。

You have been opted out of telemetry. To change this, run: cordova telemetry on.
Creating a new cordova project.
  • hello-cordova-reactフォルダと、hello-cordovaフォルダが同一フォルダに入っている状態になっていることを確認
$ ll
total 4
drwxr-xr-x 1 c480 1049089 0 Oct 18 16:37 hello-cordova/
drwxr-xr-x 1 c480 1049089 0 Oct 18 16:25 hello-cordova-react/

cordova用フォルダから、config.xmlをreact用フォルダにコピーする

hello-cordova/config.xml を hello-cordova-react 下にコピーする

cp ./hello-cordova/config.xml ./hello-cordova-react/

※ 「hello-cordova/」はこれ以降使わないので削除しても大丈夫です。

reactのビルドフォルダを「build」⇒「www」に変更する

reactプロジェクト側のpackage.jsonを開き、下記のように修正します。

windows用(cmd)の記載方法です。(gitbashを利用している場合も内部コマンドはcmd.exeのため、この書き方です)

  • &&の前後にスペースを入れないこと。スペースを含む不正なパスになり、エクスプローラーから削除できなくなります。
  "scripts": {
    "build": "set BUILD_PATH=www&&react-scripts build",
  }

windows以外の場合は、下記の通りだと思いますが未検証です。

  "scripts": {
    "build": "BUILD_PATH='./www' react-scripts build",
  }

package.jsonに下記を追加("private"の次行)

  "homepage": ".",

reactの「public/index.html」ファイルを修正。cordova化に必要な<meta>タグをとcordova.jsの読み込み追加する

public/index.html の <head>内に下記を追加する。

  <meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src * data: content:;">
  <meta name="format-detection" content="telephone=no">
  <meta name="msapplication-tap-highlight" content="no">

</body>の直後の下記を追加

  <script type="text/javascript" src="cordova.js"></script>

修正後のpublic/index.html(長くなるためコメントは消してあります)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="Web site created using create-react-app" />
    <meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src * data: content:;">
    <meta name="format-detection" content="telephone=no">
    <meta name="msapplication-tap-highlight" content="no">
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />

    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />

    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
  <script type="text/javascript" src="cordova.js"></script>
</html>

src/index.tsx を開いて以下のように編集する

変更前

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

変更後

const startApp = () => {
  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById("root")
  );
};

if ((window as any).cordova) {
  document.addEventListener("deviceready", startApp, false);
} else {
  startApp();
}

src/App.tsxを開き、後で動作確認のために利用するためボタンを追加する。

import React from 'react';
import logo from './logo.svg';
import './App.css';

const click = () => {
  alert('test');
};

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <button onClick={click}>click</button>
      </header>
    </div>
  );
}

export default App;

reactをビルドしてから、cordova run browserで動作確認を行う

hello-cordova-reactフォルダに移行後、reactをビルドする(wwwフォルダに配置されます)

npm run build

プラットフォームを追加(hello-cordova-reactフォルダ)

cordova platforms add browser
cordova platforms add android

cordovaプロジェクトを実行

cordova run browser

localhost:8000でReactアプリが開きます。

run-in-browser.png


②android用モジュールのビルド環境作成とビルド

android studio のインストール

2021/10時点ではAndroid Studio(2020.3.1)でした。
2022/02jiではAndroid Studio(2021.1.1)です。

(インストール手順)
手順に従いインストールを行います。

SDKのインストールパスを確認するためAndroid Studioを起動します。

android-studio.png

SDK Managerを選択します。下記画面の赤枠内にSDKのインストールパスが表示されています。

sdk-path.png

SDKのパスを環境変数に設定します。

env-path-sdk.png

JDK8をインストール

  • Java JDK のバージョンを確認
$ java -version
java version "1.8.0_121"

version 8(1.8) がインストール済みの場合は、次へ進みます。

Version 8以降がインストールされている場合はアンインストールして、OpenJDK8をインストールします。

未導入の場合はhttps://adoptopenjdk.net/からOpenJDK8をダウンロードしてインストールします。

  • 環境変数JAVA_HOMEを設定します(jdkインストールフォルダ)

    path_jdk.png

Gradle(ビルド自動化システム)のインストール

Gradleをダウンロード後、任意のフォルダに解凍して、Gradleのbinフォルダのパスを環境変数pathに追加します。

env-path-gradle.png

Andoroid Sdkの'platform-tools'のパスも追加します。

ビルドに必要な環境がそろっているかcordova requirementsで確認

$ cordova requirements

Requirements check results for android:
Java JDK: installed 1.8.0
Android SDK: installed true
Android target: not installed
Please install Android target / API level: "android-29".

上記のようなメッセージが表示される場合、Android Studioから、Android SDK Platform 29をインストールします。(2022/02時点では30でした)

Android Studioを起動し、SDK Managerを選択します。

android-studio.png

赤枠 Show Package Detailsをチェックし、詳細一覧表示します。

黄色枠(Android 10.0)の2つを選択してOKをクリックします。

sdk-platform.png

  • API levelは、platforms/android/project.propertiesファイルで指定されている値のようです。インストールするバージョンにより異なる可能性があるので、指定されたバージョンを選択してください。

再度確認します。エラーが出ていないので、ビルドが可能になりました。

$ cordova requirements

Requirements check results for android:
Java JDK: installed 1.8.0
Android SDK: installed true
Android target: installed android-31,android-29
Gradle: installed D:\tools\gradle-6.9.1\bin\gradle.BAT

Requirements check results for browser:

platforms/android/project.propertiesファイル

# Project target.
target=android-30
android.library.reference.1=CordovaLib
android.library.reference.2=app

Andoroid向けにビルドを行う

cordova build android

残念ながらエラーが発生します。

ビルドエラーの対処① (メモリ不足エラー)

(環境依存かもしれません。エラーがなければ次へ進んでください)

$ cordova build android
Checking Java JDK and Android SDK versions
ANDROID_SDK_ROOT=C:\Users\x_xxxx\AppData\Local\Android\Sdk (recommended setting)
ANDROID_HOME=undefined (DEPRECATED)
Using Android SDK: C:\Users\x_xxxx\AppData\Local\Android\Sdk
Starting a Gradle Daemon (subsequent builds will be faster)

FAILURE: Build failed with an exception.

* What went wrong:
Unable to start the daemon process.
This problem might be caused by incorrect configuration of the daemon.
For example, an unrecognized jvm option is used.
Please refer to the User Manual chapter on the daemon at https://docs.gradle.org/6.9.1/userguide/gradle_daemon.html
Process command line: C:\Program Files (x86)\Java\jdk1.8.0_181\bin\java.exe -Xmx2048m -Dfile.encoding=windows-31j -Duser.country=JP -Duser.language=ja -Duser.variant -cp D:\tools\gradle-6.9.1\lib\gradle-launcher-6.9.1.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 6.9.1
Please read the following process output to find out more:
-----------------------
Error occurred during initialization of VM
Could not reserve enough space for 2097152KB object heap

一言にすると2GBのメモリが確保できないというエラー(OSの空きメモリは6GBあっても失敗した)

下記ページを参考に、起動時に確保するメモリを1GBに変更します。

cordovaを使用してのビルド時にデーモンプロセスエラーが発生する

cordova-could-not-reserve-enough-space-for-2097152kb-object-heap

  • 対応方法 - reactのプロジェクトにあるGradleのビルド設定ファイルを修正します。
    \platforms\android\cordova\lib\config\GradlePropertiesParser.js

変更前

// to allow dex in process
'org.gradle.jvmargs': '-Xmx2048m',

変更後

// to allow dex in process
'org.gradle.jvmargs': '-Xmx1024m',

ビルドエラーの対処② (SDK Build-tool に不足しているファイルへの対処)

Android Studio(2020.3.1)+Gradle(6.9.1)では、ビルド時に下記エラーが発生します。

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
> Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager.

Android Studio(2020.3.1)では、cordovaのビルドに必要な下記2ファイルが含まれなくなったようです。
⇒build tool 30をインストールして、そこから不足しているファイルをコピーします。

<Andorid SDK path>/build-tools/31.0.0/dx
<Andorid SDK path>/build-tools/31.0.0/lib/dx.jar

2022/02時点(Android Studio(2022.1)+Gradle 8.0)では下記のエラーとなります。

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

See https://docs.gradle.org/7.1.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 6s
Command failed with exit code 1: E:\Users\tkykn\git\cordova\hello-world-react\platforms\android\gradlew cdvBuildDebug -b E:\Users\tkykn\git\cordova\hello-world-react\platforms\android\build.gradle

詳細がわからないためplatforms/android/CordovaLib/cordva.gradleファイルにorg.gradle.warning.mode=allを追記して再ビルドを行います。

エラー内容`Install the Android build tools version 30.0.3 or higher'から、 Android build tools のインストールが必要なことがわかります。

FAILURE: Build failed with an exception.

* Where:
Script 'E:\Users\tkykn\git\cordova\hello-world-react\platforms\android\CordovaLib\cordova.gradle' line: 69

* What went wrong:
A problem occurred evaluating script.
> No installed build tools found. Install the Android build tools version 30.0.3 or higher.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 824ms
Command failed with exit code 1: E:\Users\tkykn\git\cordova\hello-world-react\platforms\android\gradlew cdvBuildDebug -b E:\Users\tkykn\git\cordova\hello-world-react\platforms\android\build.gradle
  • 対応方法 - SDK Build-tool 30を導入し、そこから不足ファイルをコピーする

Android studio の SDK ManagerのSDK Tools(タブ)から「Android SDK Build-tool 30.0.3」を導入

  • Show Package Detailsをチェック
  • バージョン一覧が表示されるので、30.0.Xを選択して追加する

sdk-tools.png

不足しているファイルをコピーします。Andorid SDK pathは、上記の図のピンクで囲った部分です。

コピー元

<Andorid SDK path>/build-tools/30.0.3/dx.bat
<Andorid SDK path>/build-tools/30.0.3/lib/dx.jar

コピー先

<Andorid SDK path>/build-tools/31.0.0
<Andorid SDK path>/build-tools/31.0.0/lib/

※Android Studio(2022.1)の場合は、<Andorid SDK path>/build-tools/32.0.0へコピーする。

ビルドが正常終了することを確認

やっとビルドが通るようになります。

$ cordova build android
Checking Java JDK and Android SDK versions
ANDROID_SDK_ROOT=C:\Users\x_xxxx\AppData\Local\Android\Sdk (recommended setting)
ANDROID_HOME=undefined (DEPRECATED)
Using Android SDK: C:\Users\x_xxxx\AppData\Local\Android\Sdk
Subproject Path: CordovaLib
Subproject Path: app
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
~~略~~

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 22s
40 actionable tasks: 40 up-to-date
Built the following apk(s):
        C:\Users\x_xxxx\Documents\git\cordova\hello-cordova-react\platforms\android\app\build\outputs\apk\debug\app-debug.apk

③Android実機での実行

Android端末の「USBデバッグ」を有効にする

PCとAndroid端末をUSBで接続する

許可を求めるダイアログが出た場合はOKをクリック。

接続したAndroid端末が、cordova側から認識されていることを確認する

$ cordova run --list
Available android devices:
b764afd4
Available android virtual devices:
Android_Accelerated_x86_Oreo
pixel_2_pie_9_0_-_api_28

接続しているAndroid端末はAvailable android devices:の直下に表示されます。

実機でアプリを実行する

$ cordova run android --target=b764afd4

--target=の後ろに、認識されたデバイスのIDを指定して実行します。

④Androidでアプリをデバッグ実行 (soucemapを手動読み込み)

TypeScriptを利用している場合、デバッグ時にSourceMapが必要です。

(コンパイル後のJavaScriptソース位置から、コンパイル前のTypeScriptソース位置を割り出すために必要な情報。デバッグ時に、TypeScriptのコードを利用できるようになる。)

実機でアプリを実行する

  • 下記コマンドで接続されているAndroid端末を確認する
$ cordova run --list
  • Android端末で実行する
$ cordova run android --target=b764afd4

PCのChromeからリモートデバッグを行う

PCのChromeからリモートデバッグを行うため、DevToolsのDeviceを開きます。

chrome://inspect/#devices

chrome-devices.png

USBデバッグを有効にした端末のアプリが、Remote Targetに「WebView in 【アプリ名】」と表示されます

inspectをクリックして、リモートデバッグを開始します。

  • この時点ではsourcemapが読み込まれないため、TypeScriptソースでのデバッグができません。(コンパイル後jsソースでしかデバッグができない)

TypeScriptソースでのデバッグを可能にするためsourcemapを追加

  • Chrome DevToolにsourcemapを読み込ませることで、コンパイル前のTypeScriptソースでデバッグを行うことができます。

###「Source」タブ⇒「FileSystem」の「Add folder to workspace」で、ローカルPCの「www」(reactのビルドファイル保存フォルダ)を選択(~.js.map というファイル名がsourcemapです)

chrome-filesystem.png

main~.js.mapファイルを選択してCopy link addressをクリック

chrome-add-map.png

次に「Page」タブを開き、「Source map detected」というメッセージを右クリックして、ソースマップを追加する

chrome-add-map2.png

DevToolにTypeScriptソースが追加され、デバッグできるようになる

スマホ側で`click`ボタンを押すと、ブレークポイント(6行目)で止まります。

chrome-debug-ts.png

毎回sourcemapを指定するのは大変なため、reactのビルド設定を見直して、sourcemapをinline化します

⑤create-react-appのビルド設定を変更し、sourcemapをインライン化する(手動読み込み不要)

SourceMapをインライン化(JavaScriptソースの最後に追加)します。そのためには、webpackのビルド設定の変更を行う必要があります。
通常はejectしてからwebpackの設定を変えますが、
rewire を使うと、eject無しでwebpackのビルド設定を上書きできます。

  • production buildを行う際、source mapをinline-source-map(jsソース自体に埋め込む)設定にします。

webpackの設定を変更するため、rewireを追加する

  npm i -D rewire

通常のbuildとは別に、SourceMapをインライン化するビルドスクリプトを追加します。

プロジェクト直下にbuild.jsを作成し、webpackの設定を変更するスクリプトを記載する

const rewire = require('rewire');
const defaults = rewire('react-scripts/scripts/build.js');
const config = defaults.__get__('config');

config.devtool = 'inline-source-map';

ビルドスクリプトからconfigオブジェクトを取り出して、devtoolプロパティーをinline-source-mapに変更します。(変更前はcheap-module-source-mapがセットされています)

package.jsonのscriptsに、ビルド用スクリプトを追加

"build-inlinemap": "set BUILD_PATH=www&&node ./build.js",

ビルドを行い結果を確認

npm run build-inlinemap
cordova run android --target=b764afd4
  • sourcemapがinline(.jsファイルに含む)化されたため、TypeScriptソースでのデバッグが可能になります

chrome-inlinemap.png

⑥Cordova pluginを利用する(cordova-plugin-vibration)

pluginを追加

端末を振動させるプラグインを追加します。

cordova plugin add cordova-plugin-vibration

pluginを利用する

App.tsxを修正。ボタンクリック時、端末を1秒振動させます。

import React from 'react';
import logo from './logo.svg';
import './App.css';

const click = () => {
  navigator.vibrate(1000);
  // alert('test');
};

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <button onClick={click}>click</button>
      </header>
    </div>
  );
}

export default App;

ビルド後に再度実行します。ボタンクリック時に、端末が1秒間ブルブルすれば成功です。

npm run build-inlinemap
cordova run android --target=<デバイスのID>

おまけ1

Error: No Java files found which extend CordovaActivity.
というエラーが発生した場合の対処方法

cordova platform rm android
cordova platform add android
  • config.xml を変更した場合に起きるようです。その場合、上記のコマンドでなおります。

おまけ2

Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: .
というエラーが発生した場合の対処方法

adb uninstall [パッケージ名]
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2