[備忘録] React，Express，MongoDB Atlasを用いたアプリをHerokuにデプロイする際の注意点

# Herokuとは
Herokuとは，クラウド上でアプリケーションを開発，実行，管理するためのプラットフォームであり，Salesforce.comによって開発されたPlatform as a Service（PaaS）の一種です．
要するに，Herokuを用いて誰でも簡単にアプリを公開することができます．

※この記事では，React，Express，MongoDB Atlasを用いたアプリをHerokuにデプロイする際の注意点を書いています．備忘録ですが，参考になれば幸いです．

# デプロイまでの流れ
以下が大まかなHerokuにデプロイするまでの流れです．
この記事では，太字になっている箇所での注意点(するべきこと)をまとめています．
太字以外に関しては，公式ドキュメントや[この記事](https://qiita.com/DogK0625/items/12178fdc3dd607088ff0#heroku%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E4%BD%9C%E6%88%90heroku-toolbelt-cli%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4)を見るとわかりやすいと思います．

herokuアカウント作成(クレジット登録)
↓
Heroku CLI をインストール
↓
__heroku用にローカルで作成したアプリを編集__
↓
__環境変数やビルドパックを追加__
↓
gitでHerokuにデプロイ

# heroku用にローカルで作成したアプリを編集
以下のように編集することでHerokuにデプロイできるアプリになります．

1. ルートディレクトリにProcfileを追加
2. package.jsonにheroku-postbuildを追加
3. ルーティングをheroku仕様に変更

1つずつ説明していきます．

## ルートディレクトリにProcfileを追加
Procfileは，Herokuのデプロイプロセスで自動的に解釈され，指定されたプロセスを起動するためのものです．Procfileの中身は，プロセスの名前とコマンドラインの起動コマンドから構成されており，例として以下のように記述します．

```Procfile.
web: node server.js
```
上記の例では，nodeコマンドでserver.jsを実行し，Webサーバを起動しています．
しかし，このままデプロイしてもバックエンド側しか起動しません．
そこで，バックエンド側のpackage.jsonにheroku-postbuildを追加することで，
フロントエンド側も起動することができます．

## package.jsonにheroku-postbuildを追加
以下のコードのようにバックエンド側のpackage.jsonのscriptにheroku-postbuildを追加します．

```package.json
{
  "name": "renshu",
  "version": "1.0.0",
  "description": "renshu",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "heroku-postbuild": "cd frontend && npm install && npm run build"
  },
  "author": "renshu",
  "dependencies": {
    "express": "^4.18.2",
    以下省略
  },
}
```
heroku-postbuildスクリプトは，ReactをHeroku上で正常に実行するために必要なビルドプロセスを自動化するために使っています．
コマンドの中身の説明としては，cd frontend でfrontendのディレクトリに移動し，npm installで必要なパッケージをインストールしています．
その後，npm run buildでReactアプリケーションのビルドをしています．
npm run buildによって，最低限のファイルにまとめることで，サイトの読み込みを速くすることができます．

## ルーティングをheroku仕様に変更
バックエンドとフロントエンドの両方において，ローカルで作成していたルーティングをheroku仕様に変更しないといけません．
デプロイ環境で動かす場合は，server.jsでは，
```app.listen(process.env.PORT);```
と，上記のようにprocess.env.PORTと記述し，Heroku側で用意されているポートで起動する必要があります．


```server.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const PORT = 5000;
require("dotenv").config();

//データベース接続
mongoose.connect(process.env.MONGOURL)
.then(() => {
    console.log("DBと接続中・・・");
})
.catch((err) => {
  console.log(err);
});

app.get('/', (req, res) => {
  res.header(200).send("Hello World!")
})

app.listen(process.env.PORT, () => console.log("サーバーが起動しました"));
```
他にもReact側では，```http://localhost:5000/get```などのローカルホストへのリクエストから，herokuへのリクエスト```https://example.herokuapp.com/get```に変更しないといけません．
以下は変更例になっています．

```
[変更前] await axios.get(`http://localhost:5005/get`);
[変更後] await axios.get(`https://example.herokuapp.com/get`);
[環境変数を使う場合] await axios.get(`${process.env.REACT_APP_API_URL}/get`);
```
一通りローカルホストへのリクエストからherokuへのリクエストに変更したら
heroku用にローカルで作成したアプリを編集する作業は終わりです．

# 環境変数やビルドパックを追加
次に，herokuで環境変数やビルドパックを追加を行います．
環境変数の設定では，以下の画像のように設定します．
ローカル環境でenvファイルに記述しているものをここで設定してください．
![config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949779/ca3db4b7-e11a-da30-46df-5d9f6f3dc518.png)

ビルドパックの設定では，以下の画像のように設定します．
今回ではnode.jsのビルドパックを追加しています．
![スクリーンショット 2023-05-16 11.19.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949779/6ef2bf94-2f21-e657-0248-b83d06293e82.png)


# おまけ
ディレクトリ構成の例を書いておきます．
ルートディレクトリには必ず，Procfileとpackage.jsonファイルは置いてください．

```
 .
 ├ frontend
 |  ├ package.json
 |  ├ package-lock.json
 |  └─ src/
 |    ├ App.js
 |    └─ ...
 ├ routes
 |  ├ users.js
 |  └─ ...
 ├ server.js
 ├ package.json
 ├ package-lock.json
 └─ Procfile
   
```

# おわりに
ここまで読んでいただきありがとうございました．
ここに書いていることを設定すれば，ローカル環境からデプロイ環境への移行は終了です．
あとはgitでherokuにデプロイしてみてください！

--
自分は，アプリ開発初心者なので，間違っている点もあるかもしれません．
もし間違いにお気づきになられたら，コメントよろしくお願いします．

# 参考文献
https://qiita.com/DogK0625/items/12178fdc3dd607088ff0#heroku%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E4%BD%9C%E6%88%90heroku-toolbelt-cli%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4