DockerでReact Native環境作成から、Expo Clientで実機確認するまで

iOS、Android両方に対応するアプリを作成することができるReact Native。
最近、個人的に興味がわいたので、Docker環境作成にチャレンジしてみたのですが、あまり記事を見かけなかったので構築手順を書いておきます。

※この記事はQiitaからの転載です。

※2019/9/21追記
後述しますが、自分がやった時にホットリロードが効かなかったり、エミュレータ環境との連動がうまくできなかったりしてます…。
自分のやり方が悪いだけかもしれませんが、あまりDockerで構築するメリットがないかもしれません。

※2019/9/28追記
WSLで環境作り直しました。
 →WSLでReact Native + Expo環境を作ろう

前提 #

  • docker導入済み
  • docker-compose導入済み

環境構築手順 #

事前準備 #

React Nativeで開発をしていく上でExpoを使うと便利です。
環境構築も比較的楽に行え、アプリの内容をQRコードで発行して簡単に実機確認を行うことができます。

Expoアカウントを作成 #

Expoの公式サイト

  1. expo.ioにいき、「Create an account」を選択。
  2. e-mail、ユーザ名、パスワードを入力して「Create your account」を選択。

Expo Clientをインストール #

Expo ClientのApp Store画面

  1. 使用するiOS/Android端末にApp Store/Google playからインストール。
  2. 作成したExpoアカウントでログインしておく。

Docker環境作成 #

自分の場合は以下のディレクトリ構成で行っています。

React Native(プロジェクトフォルダ)
├─ docker
| ├─ node
|   ├─ dockerfile
├─ .env
├─ docker-compose.yml

Dockerfile #

FROM "node:10-alpine"

WORKDIR /usr/src/app/

RUN apk update && apk add bash

RUN yarn global add expo-cli

後ほど、expo startする際にbashが必要になりますが、使用しているイメージのalpine linuxにはbashが入っていないため、インストールしています。
はじめからbashが入っているイメージを使用するのもありです。

React Nativeのプロジェクトを作成するCLIツールとして、以前はcreate-react-native-appがあったそうなのですが、expo-cliに統合されたそうなのでこちらをインストール。

.env #

REACT_NATIVE_PACKAGER_HOSTNAME=(自分のローカルPCのIPアドレス)

コンテナに渡す環境変数を定義します。
REACT_NATIVE_PACKAGER_HOSTNAMEは、後ほど$ expo startでExpoアプリをホスティングする際のIPになります。デフォルトではコンテナのIPを使用してしまうために、Expo Clientから接続することができないので、ローカルPC自体のIPを指定しておきます。
IPはWindowsでは$ ipconfig、Macでは$ ifconfigで確認できます。

docker-compose.yml #

version: "3"
services:
  node:
    build: ./docker/node
    volumes:
      - ./app/:/usr/src/app
    tty: true
    stdin_open: true
    environment:
      - REACT_NATIVE_PACKAGER_HOSTNAME=${REACT_NATIVE_PACKAGER_HOSTNAME}
    ports:
      - "19000:19000"
      - "19001:19001"
      - "19002:19002"

tty、stdin_open - $ docker-compose upしたコンテナを起動させたままにするために設定。
environment - .envファイルで定義した環境変数を設定。
port - Expoで使用する3つのポートを設定。

起動 #

バックグラウンドで起動

$ docker-compose up -d

RUN yarn global add expo-cliの個所でWARNがたくさん出ますが、ERRORがなければ動いてくれると思います。(すみません、WARNの内容まではちゃんと見れていません)

Expoプロジェクト #

作成 #

# コンテナの中に入る
$ docker-compose exec node bash

# expoプロジェクト作成
$ expo init .

テンプレートが選択できます。
とりあえずはblankを選択してEnter。

bash-4.4# expo init .
? Choose a template: (Use arrow keys)
  ----- Managed workflow -----
❯ blank                 a minimal app as clean as an empty canvas
  blank (TypeScript)    same as blank but with TypeScript configuration
  tabs                  several example screens and tabs using react-navigation
  ----- Bare workflow -----
  minimal               bare and minimal, just the essentials to get you started
  minimal (TypeScript)  same as minimal but with TypeScript configuration

Expoプロジェクトの表示名を聞かれます。
入力してEnter。

? Choose a template: expo-template-blank
? Please enter a few initial configuration values.
  Read more: https://docs.expo.io/versions/latest/workflow/configuration/ ‣ 0% completed
 {
   "expo": {
     "name": "<The name of your app visible on the home screen>",
     "slug": "app"
   }
 }

Yarnを使ってパッケージをインストールするか聞かれます。Yでインストール実行。

? Yarn v1.17.3 found. Use Yarn to install dependencies? (Y/n)

これでExpoプロジェクトのひな型が作成されました。

起動 #

expo startもしくはyarn startでExpoサーバとして起動。
しばらくするとQRコードが表示されます。
expo startの画面

Expo Clientで実機確認 #

表示されたQRコードをiOS/Android端末から読み込むと、Expo Clientが立ち上がりビルドが始まります。
なお、注意点として、ExpoサーバになるPCとiOS/Android端末は同じネットワークにつないでいる必要があります。
しばらくしてビルドが終わると初期ガイドが表示されます。
Expoアプリのガイド

ガイドを消すと、Expoアプリの画面が表示されます。これが実行結果です。
blankテンプレートを選択したのでシンプルな画面ですね。
一連の手順で比較的楽に実機確認をすることができました。
ただ、ホットリロードがうまく動作していないのか、コードの変更が即座に反映されませんでした。なぜ…。
Expoアプリの実行画面

補足 #

http://localhost:19002 #

アクセスすると、Expo DevToolが使用できます。
ここからシミュレータを起動したりできるみたいです。
(X Code、Android Studioのインストールや設定が別途必要になるようです)
末尾にも書いていますが、自分はうまくいきませんでした…。
Expo DevTool画面

http://localhost:19001 #

HTMLが表示されます。
expo start時の表示でMetro Bundlerだと書いてありましたが、なんなのかはよくわかってません。
metro bundler画面

http://localhost:19000 #

Expoプロジェクトの情報?が表示されます。
Expoサーバの情報

エミュレータについて(2019/9/18追記) #

自分の環境はWindowsなので、Docker環境の中にAndroidのエミュレータ環境を作ろうとしましたがうまくいきませんでした…。

一応やってみたこととしては
1.openjdkをインストール
2.Android公式からコマンドラインのzipファイルをダウンロード
3.Andoid SDKを格納するディレクトリを作成し、zipファイルを解凍して配置
4.Android SDKに関するパスを設定
5.sdkmanager、avdmanagerコマンドが実行できることを確認
6.sdkmanagerコマンドで必要なSDKをインストール
 ↑
ここでエミュレータをインストールしたのですが、なぜかemulatorコマンドが実行できませんでした。パスはちゃんと通しているはずなのに、ひたすらNo such file or directoryが出てしまい…。一体なんなのか。

WSLで環境構築した方が、早いかもしれませんね。
だからDockerで構築している記事がほとんどなかったんでしょうか…。

参考リンクまとめ #