Pythonスキルの習得

FlaskとReact(TypeScript)で、SPA Webアプリを実装する方法

FlaskとReact(TypeScript)で、SPA Webアプリを実装する方法

こんにちは、Zero-Cheeseです。

本記事では、

  • フロントエンドにReact(TypeScript)
  • バックエンドにFlask

を使用する「SPA WEBアプリ」の実装方法を、ご紹介します。

Reactは、リリース前にビルドするのが、通常です。

しかし、 「ビルド済React(TypeScript) + Flask」 の情報がネット上に少ないため、その実装方法について、今回取り上げました

本記事は、

  • React(TypeScript)
  • Flask

初心者以上の方を、対象にしています。

本記事で作成する、Webアプリ

本記事で作成するWebアプリの「フロントエンド」側は、簡潔化のために、

  • 「npx create-react-app (アプリ名)」コマンド(TypeScriptの場合は、npx create-react-app –template typescript (アプリ名))で作成した、初期状態を使用します。

すなわち、下記画面が、表示される状態です。

本記事で紹介する、フォルダ構成

本記事で紹介する、フォルダ構成は以下の通りです。

  • Flaskアプリは、直下のapp.pyのみ
  • React関連は全て、「frontend」フォルダに格納

Flaskから、呼出す方法

全体手順は、以下の通りです。

  1. React(TypeScript)をビルドする
  2. Flaskから呼出す

① React(TypeScript)をビルドする

Reactが入っているフォルダ(本記事の場合、「frontend」フォルダ)に移動し、以下のコマンドを実行し、「ビルド」します。

npm run build

「frontend」下に、「build」フォルダが作成され、その配下に必要ファイルが作成されます。

Flaskのファイル構成から考えると、画像ファイル類は「static」フォルダ下に、配置するのが望ましいです。

そのため、以下のようにファイルを移動します。

※ 一部のファイル、フォルダを省略しています。

また、それに合わせて、index.htmlファイルを、以下のように変更して下さい。

下記コードの、6, 10, 11行目の、href属性値の先頭に

  • /static/ 

を追記します。

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <link rel="icon" href="/static/favicon.ico" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="Web site created using create-react-app" />
    <link rel="apple-touch-icon" href="/static/logo192.png" />
    <link rel="manifest" href="/static/manifest.json" />
    <title>React App</title>
    <script defer="defer" src="/static/js/main.c8248ffc.js"></script>
    <link href="/static/css/main.073c9b0a.css" rel="stylesheet">
</head>

<body><noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
</body>

</html>

この手順は、ビルドするたびに、行う必要があります。

それが手間だと感じる場合は、「public」フォルダ下のindex.htmlを、変更する事で対応できます。

そのファイルが、ビルドのベースとなるため、毎回の変更が不要になります。

② Flaskから呼出す

Flaskに、HTMLファイルや画像ファイルの保存場所を、さきほど作成した「build」フォルダだと、教える必要があります。

下記コードを、ご参照ください。(4, 5行目の、template_folder、static_folder引数で、フォルダ場所を、教えています。)

from flask import Flask
from flask import render_template

app = Flask(__name__, template_folder='./frontend/build',
            static_folder='./frontend/build/static')


@app.route('/')
def home():
    return render_template('index.html'), 200


if __name__ == '__main__':
    app.run(debug=True)

Flaskを実行してみると、Reactで作成した画面が、表示されます。

ただし、React上でルーティングを設定している場合は、Flaskのコードを以下のように変更します。

これにより、全てのエンドポイントが、home( )関数に紐づけられます。

from flask import Flask
from flask import render_template

app = Flask(__name__, template_folder='./frontend/build',
            static_folder='./frontend/build/static')


@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def home(path):
    return render_template('index.html'), 200


if __name__ == '__main__':
    app.run(debug=True)

ビルド前のReact(TypeScript)と、連携したい場合

リリースする前に、ローカル上で動作確認する場合は、ReactもFlaskもlocalhost上で実行し、挙動を確認することが一般的です。

しかし、その際にReactのWebページから、FlaskのURLを叩くと、CORSエラーが発生します。

CORS(Cross-Origin Resource Sharing)は、異なるオリジン間でのリソース共有を可能にする仕組みです。

ReactとFlaskをlocalhostで実行すると、ポート番号が異なるため、別のオリジンとみなされます。

その結果、リソースの共有が、セキュリティ観点から制限されます。

このCORSエラーを回避するためには以下の手順を行います。

ただしセキュリティ上、リリース前に、下記コードは無効にするようにしてください。

まず、pipを使用してCORS関連のパッケージをインストールします。

pip install flask-cors

その上で、Flaskのコードを、以下のように変更します。(3, 7行目を、追加しています。)

from flask import Flask
from flask import render_template
from flask_cors import CORS

app = Flask(__name__, template_folder='./frontend/build',
            static_folder='./frontend/build/static')
CORS(app)


@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def home(path):
    return render_template('index.html'), 200


if __name__ == '__main__':
    app.run(debug=True)

最後に

本記事では、理解しやすさを優先して、簡単な構成で説明しました。

プロジェクトが大規模になると、もう少し複雑なフォルダ構成とビルドプロセスが、必要になります。

たとえば、ビルドされたReactアプリケーションを別のサーバーにデプロイする場合、フロントエンドとバックエンドのコードは、異なるリポジトリで管理することが一般的です。

そして、フロントエンドとバックエンドは異なるCI/CDパイプラインを通じて、デプロイする事になるかと思います。

しかし、小規模なプロジェクトやプロトタイプを作成する際や、ReactとFlaskを学ぶ初期段階では、同一のリポジトリ内で両方を管理し、一緒に実行する方が、簡単で便利です。

FlaskとReactの統合には多くの方法があります。

本記事で紹介した方法は一つの例としてご理解ください。

Flaskを使用する場合、標準では「jinja」を用いますが、Reactを採用することで、プログラミングを活用したHTMLの生成が可能となり、その魅力は大いにあります。

少し前(執筆時:2023年7月)に、「Qiita記事を分析して、オススメのUdemy講座をランキング講座で紹介するサイト」を作りました。

このサイトの分析結果を見ていると、React系の講座が常にランキング上位にあり、一般的にも、その魅力が認知されていることを実感しました。

本記事を最後までお付合い頂き、ありがとうございました。

それではまた、お会いしましょう!