React Router付のReact AppをFirebase Hostingでホストする

Firebase Hositing は SPA を上げることが前提となっているので、Reactなどと相性が良い。また /index.html へすべてのルーティングを回してくれるので、React RouterでURLのパスとSPAを対応つけることもできる。

Create React App がデフォルトで build フォルダにすべてを出力するところをちゃんとFirebase Hostingと関連付けてあげれば基本的にそれだけですべて行くので、手順だけを健忘禄的にメモしておく。

### 参考にした公式ドキュメント

- [Firebase Hosting](https://firebase.google.com/docs/hosting?authuser=0)
- [Create React App: Quick Start](https://facebook.github.io/create-react-app/docs/getting-started)
- [React Router : Quick Start](https://reacttraining.com/react-router/web/guides/quick-start)

### 完成品
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2382/5d2d34a3-eb32-cc71-4528-6d97faea8e9c.png)

最終的にこんな感じにホスティングできる。

[https://router-study.firebaseapp.com/topics/components](https://router-study.firebaseapp.com/topics/components)

上記URLのサイトでは index.html しかないけれども、ルーティングに合わせてコンテンツが変わるSPAになっている。

### ソースコード

[https://github.com/sifue/router-study](https://github.com/sifue/router-study)


# Firebase で ReactApp / React Routerをホスティングするための手順

### React App を作る
環境は

```
vagrant@ubuntu-bionic:~/localworkspace/router-study$ npm -v
6.4.1
vagrant@ubuntu-bionic:~/localworkspace/router-study$ node -v
v8.16.0
```

まずは Create React App をインストールして動作確認。

```
npm install -g create-react-app
create-react-app router-study
cd router-study

yarn start
```

[http://localhost:3000/](http://localhost:3000/)

動いていればOK。

### React App を Firebase に対応させる。

```
npm install -g firebase-tools
firebase login
firebase init
```

今後のための設定として

- Firestore
- Functions
- Hosting
- Storage

選んでおくと便利。セキュリティルールやインデックスのファイルを作っておいてくれる。

アップロードするプロジェクトを選択or作成。

- firestore.roles
- firestore.indexes.json

作成。Fuctionsの言語はご自由に。ここでは、

- JavaScript

で、ESLintは強制 y を選択。

**出力フォルダは、`public` ではなく リソースは `build` ディレクトリ を入力する。ここが一番重要。**

すべてのURLを index.html にするのはデフォルトの設定。
storage.rulesも作っておくと便利。

```
firebase serve --only hosting -o 0.0.0.0
```

でhosting起動。

[http://localhost:5000/](http://localhost:5000/)

アクセスして、Firebase のデフォルトHTMLが動いていればOK。

React App をビルドして、Firebaseローカルサーバーでホスティング。

```
yarn build && firebase serve --only hosting -o 0.0.0.0
```

[http://localhost:5000/](http://localhost:5000/)

これで、React Appが起動できてればOK

Datastore/Firestore、Storage、Functionsをそれぞれ

[https://console.firebase.google.com/](https://console.firebase.google.com/)

で開いて設定しておく。

```
firebase deploy
```

[https://${自分のプロジェクト}.firebaseapp.com](https://${自分のプロジェクト}.firebaseapp.com)

などにアクセス。React Appが動いていることを確認。

##### React Routerをインストールして動かしていく。

```
yarn add react-router-dom
```

src/App.js を [Example: Nested Routing](https://reacttraining.com/react-router/web/guides/quick-start) に編集。

```jsx

import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

function App() {
  return (
    <Router>
      <div>
        <Header />

        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/topics" component={Topics} />
      </div>
    </Router>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return <h2>About</h2>;
}

function Topic({ match }) {
  return <h3>Requested Param: {match.params.id}</h3>;
}

function Topics({ match }) {
  return (
    <div>
      <h2>Topics</h2>

      <ul>
        <li>
          <Link to={`${match.url}/components`}>Components</Link>
        </li>
        <li>
          <Link to={`${match.url}/props-v-state`}>Props v. State</Link>
        </li>
      </ul>

      <Route path={`${match.path}/:id`} component={Topic} />
      <Route
        exact
        path={match.path}
        render={() => <h3>Please select a topic.</h3>}
      />
    </div>
  );
}

function Header() {
  return (
    <ul>
      <li>
        <Link to="/">Home</Link>
      </li>
      <li>
        <Link to="/about">About</Link>
      </li>
      <li>
        <Link to="/topics">Topics</Link>
      </li>
    </ul>
  );
}

export default App;
```

```
yarn start
```

で webpack の Webローカルサーバーで動作確認。これだとエラーを教えてくれる。

[http://localhost:3000/](http://localhost:3000/)

にて Router がちゃんと動いてくれていることをチェック。ちゃんとURLパスと内容の連動を確認。

最後にビルドして、 firebase にデプロイ。

```
yarn build && firebase deploy
```

[https://${自分のプロジェクト}.firebaseapp.com](https://${自分のプロジェクト}.firebaseapp.com)

などにアクセス。ちゃんと動いていれば完成。

# 感想
Create React Appが過去、バージョン依存関係の関係上設定が難しかった Webpack/Babel/JSX/ESLint の設定を完全にやってくれてしかもローカル WebServer でリアルタイムビルド、エラーまで出してくれるようになって神。React.jsの進化に感動です。