WSLでReact Native + Expo環境を作ろう

前回、DockerでReact Native環境を作成した記事を書いて多くの方に見ていただけたようなのですが、結局ホットリロードがうまく働かない、エミュレータ環境との連携がうまくいかない等、使い勝手がイマイチだったのでWSLで環境を作り直しました。
前回の記事：[DockerでReact Native環境作成から、Expo Clientで実機確認するまで](https://qiita.com/h-yoshikawa/items/51b631ec0a6beabdce2d)

基本的な作成手順は一緒なので内容が重複するところもありますが、エミュレータに関する記述も少しあわせて書いておきます。

## 前提
- Node.jsがインストール済み（自分はanyenv + nodenvでいれてます）
- npm or yarnコマンドが実行できる

## 環境構築手順
### 事前準備
React Nativeの開発支援サービスであるExpoを使用します。
Expoに関する説明は前回も書いたので省略します。

#### Expoアカウントを作成
![expo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206877/f9cc5189-0fcc-d2d4-0870-a839883fe94a.png)

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

#### Expo Clientをインストール
![expo-client.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206877/d7bc8c35-df6a-71a0-b07a-9cb05f518eee.png)

1. 使用するiOS/Android端末に[App Store](https://apps.apple.com/jp/app/expo-client/id982107779)/[Google play](https://play.google.com/store/apps/details?id=host.exp.exponent&hl=ja)からインストール。
2. 作成したExpoアカウントでログインしておく。

#### Expo-Cliのインストール
npmもしくはyarnでインストールします。

```bash
# npm
$ npm install -g expo-cli

# yarn
$ yarn global add expo-cli
```

## Expoプロジェクト
### 作成
appの部分は任意のExpoプロジェクトフォルダ名を指定します。

```
$ expo init app
```
テンプレートを選択します。

```bash
# expo init app
? 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プロジェクトの表示名を聞かれます。

```bash
? 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でインストール実行。(nを選択するとnpmでパッケージをインストールします）

```bash
? Yarn v1.17.3 found. Use Yarn to install dependencies? (Y/n)
```
これでExpoプロジェクトのひな型が作成されました。
ちなみにExpoプロジェクト作成後のディレクトリ構成は以下のようになります。

```
例
ReactNative（大元のプロジェクトフォルダ）
├─ app（Expoプロジェクトフォルダ）
　　├─ .expo
　　├─ .expo-shared
　　├─ assets
　　├─ node_moodules
　　├─ .gitignore
　　├─ .watchmanconfig
　　├─ App.js
　　├─ app.json
　　├─ babel.config.js
　　├─ package.json
　　├─ yarn.lock
```

### 起動
#### 環境変数
Expoサーバ起動時のIPを設定します。
デフォルトではUbuntuの方のIPを使用し、CONNECTIONをLANで接続するため、Expo Clientから接続することができません。（一応、サーバ起動後にCONNECTIONをTunnelにすることで接続することは可能です）

Ubuntu側で以下を`~/.profile`など各種profileのいずれかに追記

```
export REACT_NATIVE_PACKAGER_HOSTNAME=(Windows側のIP)
```

各種profileの読み込み

```
例
source ~/.profile
```

#### Expoサーバ起動
以下のいずれかでExpoサーバとして起動。

```
$ expo start

$ npm start

$ yarn start
```
しばらくするとQRコードが表示されるとともに、Expo DevTools（localhost:19002）がブラウザで自動的に立ち上がります。
![expo-start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206877/2eb3852b-5fa7-47fe-39f7-fa0ba9faeae7.png)

## 動作確認
### 実機確認
Expoサーバ起動時に表示されたQRを、iOS/Android端末で読み込むことで、Expo Clientが立ち上がりビルドが始まります。
なお、注意点として、**ExpoサーバになるPCとiOS/Android端末は同じネットワークにつないでいる必要があります。**
しばらくしてビルドが終わると初期ガイドが表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206877/c8913c91-bb40-59db-7f8b-ad7f19b856a7.png" width=40% alt="app-guide">

ガイドを消すと、Expoアプリの画面が表示されます。これが実行結果になります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206877/166ca1e6-edbe-162f-6b50-6de647d07c0c.png" width=40% alt="app-preview.png">

なお、この状態でコードを変更すると、即座に再読み込みが走り画面に反映されます。
ライブリロードが走っているそうです。（ホットリロードとの違いがよくわかってません）

### エミュレータでの確認
Windowsなので、Androidのエミュレータのみを書いておきます。

#### Android Studioのインストール
![android-studio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206877/3a88371f-49c7-5b3d-6e70-08014b10351b.png)

1.[公式](https://developer.android.com/studio/?gclid=Cj0KCQjwoKzsBRC5ARIsAITcwXGiwraGK65ftU272vVgpSefKsvKGk1cKZQ1RtwuZ7UgHf4KmtVwVPsaAiqvEALw_wcB)からダウンロード。

2.ダウンロードしたインストーラを起動して、インストール。(少し時間がかかります）

3.インストールしたAndroid Studioを起動。初回はセットアップウィザードがあるので、案内に沿って進めていきます。
必要に応じてインストールするSDKを選択します。`Andoroid SDK Build-Tools`や`Android Emulator`、`Andoroid SDK Platform-Tools`、`Android SDK Tools`などは最初からチェックが入っているかと思います。
(選択したSDKをインストールするのに時間がかかります）

あとからSDKを追加したい場合は、トップ画面の右下の「Configure」→「SDK Manager」からSDKの一覧画面へ行けます。

#### 環境変数の設定
1.Android Studioのトップ画面の右下の「Configure」→「SDK Manager」からSDKの一覧画面へ

2.Android SDK Locationを控えておく

3.環境変数を追記
Windowsのシステム環境変数に追記

```
ANDROID_SDK ... (※2でコピーしたパス）
PATH ... %ANDROID_SDK%\emulator と %ANDROID_SDK%\pratform_tools を追加
```

4.`emulator`コマンドと`adb`コマンドが使えるか確認

#### Virtual Deviceの用意
1.Android Studioトップ画面の「Configure」→「AVD Manager」を選択

2.「Create Virtual Device」を選択

3.デバイスを選択して、システムイメージを選択して作成

#### エミュレータの起動
1.Android Studioトップ画面の「Configure」→「AVD Manager」からデバイス一覧へ

2.Actionsのプレイボタンを選択して起動

なお、コマンドでエミュレータを起動する場合は以下のコマンドでいけます。

```bash
# デバイス名の一覧確認
$ emulator -list-avds

# 指定デバイスのエミュレータの起動
$ emulator -avd (デバイス名)
```

3.Expoサーバを起動し、Expo DevTools（localhost:19002）の「Run on Android device/emulator」を選択
初回のみエミュレータにExpo Clientのインストールがあります。
また、エミュレータでも同様に、コードを変更すると再読み込みが走ります。

---
WSLで無事環境が作れたのはよかったのですが、Expoサーバを起動後にしばらくしてネットが繋がらなくなる？（一応繋がってはいるが、ネット上のページにアクセスできない）状態になるのが謎です...。PCを再起動したら直ります。
もしかしたらExpo関係ないかもしれないですけど、Expoのサーバ立ち上げたときしかその現象起きないんですよね。これさえなければいいのになぁ。
↓
2019/10/7追記
これについて調べたことを記事に書きました。
[WSLでexpo startして20～30分後にネットワーク不具合が起こる現象について調べたこと](https://qiita.com/h-yoshikawa/items/518e8f6e0b700b65b0fa)