create-react-appで作ったフロントとFlaskで作ったAPIをつなげる(サーバーをふたつ立ち上げる必要をなくす)方法の備忘録です。
こちらの動画を参考にさせていただきました。
Serving React with a Flask Backend
前提
ツリー構造はこんな感じ。
react-flask-app/
├─Flask-Backend
|   ├─static
|   ├─templates
|   └─app.py
└─React-Frontend
    ├─public
    ├─src
    ├─package.json
    └─yarn.lock
app.pyはこんな感じ。
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
    return render_template('index.html')
if __name__ == '__main__':
    app.run()
Webpack解放
$ cd React-Frontend
$ yarn eject
$ Are you sure you want to eject? This action is permanent. (y/N) y
React-Frontendフォルダの下にconfigフォルダが追加されます。
react-flask-app/
├─Flask-Backend
|   ├─static
|   ├─templates
|   └─app.py
└─React-Frontend
    ├─config
    |   └─jest
    |       ├─env.js
    |       ├─paths.js
    |       ├─webpack.config.js
    |       └─webpackDevServer.config.js
    ├─public
    ├─src
    ├─package.json
    └─yarn.lock
paths.js内で、buildフォルダを作成する場所のパスをbuildからFlask-Backend/static/reactに変更します。
(省略)
module.exports = {
    (省略)
    appBuild: resolveApp('../Flask-Backend/static/react'),
    (省略)
}
webpack.config.js内で、static/js/[name].[chunkhash:8].js -> js/[name].[chunkhash:8].jsのように、ファイル名のパスがstatic/から始まっているところを全て消します。
次に、HtmlWebpackPluginオブジェクト内にfilenameを追加し、Flask-Backendフォルダのtemplatesフォルダ下にindex.htmlをビルドするよう指定します。
(省略)
plugins: [
    new HtmlWebpackPlugin(
        Object.assign(
            {},
            {
                inject: true,
                template: paths.appHtml,
                filename: '../../templates/index.html' <-- 追加
            },
            (省略)
        )
    )
]
package.json内にhomepageの項目を追加し、buildフォルダ(ここではreactフォルダ)を指定します。
{
    "homepage": "/static/react",
}
ビルドして立ち上げる
yarn buildでビルドします。staticフォルダとtemplatesフォルダの下にビルド後のファイルが追加されます。
react-flask-app/
├─Flask-Backend
|   ├─static
|   |    └─react
|   |        ├─css
|   |        └─js
|   ├─templates
|   |    └─index.html
|   └─app.py
└─React-Frontend
    ├─config
    |   └─jest
    |       ├─env.js
    |       ├─paths.js
    |       ├─webpack.config.js
    |       └─webpackDevServer.config.js
    ├─public
    ├─src
    ├─package.json
    └─yarn.lock
$ cd Flask-Backend
$ python app.py
http://localhost:5000/ にアクセスします。
以上。
追記: ejectしない方法
yarn ejectしてwebpackの設定を弄らずともつなげられるようです。
React-Frontendに移動します。
yarn buildします。
React-Frontend内にbuildフォルダが追加されます。
app.py内でstaticフォルダとtemplatesフォルダのパスを指定します。
from flask import Flask, render_template
app = Flask(__name__, static_folder='../React-Frontend/build/static',
template_folder='../React-Frontend/build')
@app.route('/')
def index():
    return render_template('index.html')
if __name__ == '__main__':
    app.run()