ESP32 で React アプリケーション

ESP32 で Web サーバを立てて,React アプリケーションを動かす方法を紹介します.

はじめに

大枠は,以前書いた『ESP32 で Angular アプリケーション』とほぼ同じです.

create-react-app を使って生成したファイルに対して必要な処置を順に説明します.

React 側の準備

React 側でやることは,大きく次の3つがあります.順に説明していきます.

  • 配置パスの指定
  • ファイル名のランダム化の停止
  • ファイルの圧縮

配置パスの指定

React アプリを ESP32 で配信する場合,おそらく API サーバも ESP32 で動かすことになると思います.ルートではなく /app にアプリを配置し,API のエンドポイントを /api に配置すると,配信の際の扱いがしやすくなります.

配信パスの指定は,package.json に「”homepage”: “/app”,」を追加することで行います.「”version”:」の次の行当たりに挿入すれば OK.

ファイル名のランダム化の停止

create-react-app を使っている場合,そのままではランダム化を簡単に止めらませんので,まずは設定を部分的に上書きするために作られた react-app-rewired をインストールします.

アプリのビルド時に react-app-rewired を使うようにするために,package.js の scripts を次のように書き換えます.

そのうえで,config-overrides.js というファイルを作成し,次の内容を設定します.

ファイルの圧縮

React アプリはシンプルなものでもサイズがそれなりに大きくなってしまいます.小さなアプリであればそのままでも収まるかもしれませんが,ESP32 の Flash サイズは潤沢ではないので,gzip で圧縮して配信しておくのがおすすめです.

そのため,下記のような Makefile を使って圧縮されたファイルを生成するようにします.

実行すると下記のようになり,300KB あったものが 1/4 近くの 84KB になっていることが分かります.これなら,ROM サイズ(4MB)に対してかなり小さいので,サイズを気にせずにアプリ開発が行えます.

ESP32 への組み込み

以上で準備したファイルを ESP32 から配信できるようにします.ESP-IDF の使用を前提に,順に説明していきます.

  • ファームへのファイルの組み込み
  • サーバによるファイルの配信

ファームへのファイルの組み込み

main/component.mk に次のように記載します.これにより,生成されるファイルに React アプリケーションが組み込まれるようになります.

「../react/build/」は,生成した React アプリケーションの相対パスで置き換えてください.

サーバによるファイルの配信

まずは全体像を示します.下記のコードで Angular アプリを配信できるようになります.

APP_PATH は,Angular アプリをビルドしたときの --base-href= の指定と合わせておきます.

コードのポイントを順に説明します.

ファイルデータの取得

COMPONENT_EMBED_FILES で指定して組み込んだファイルデータの開始・終了アドレスは,次のようにして取得できます.

アドレスさえ取得できれば,あとは httpd_resp_send_chunk にて送信データとして指定してやれば配信できます.

gzip ファイルの配信

上のほうで HTML 以外は gzip で圧縮しました.そのため,次のようにして,圧縮されていることをブラウザーに通知します.

パスのワイルドカード指定

ESP32 の HTTP Server ライブラリでは,パスに対応するハンドラ関数を指定してやる必要がありますが,React のように複数のファイルがある場合,ファイル毎に関数を用意するのは手間です.

そこで,ワイルドカードによる指定を行えるようにするため,下記のようにします.

その上で,次のようにすると,/app 以下の全てのアクセスに対して http_handle_app が呼ばれるようになります.(下記では APP_PATH マクロを展開しています)

あとは, http_handle_app の中で,req->uri を基にどのファイルへのアクセスか判定して,適切なファイルを配信してやれば OK.

動作確認

Wifi 接続が完了したタイミングで次の関数を呼んでおけば,React アプリを実行できるようになっています.

サンプル

サンプルとして,ESP32 が検出した WiFI アクセスポイントの表示を行う esp32_wifi_scan を github に登録してありますので,適宜参考にしてください.