React + Flask をExe化して動かしてみる

  • 2020.12.26
  • 2021.01.24
  • Flask
NO IMAGE


簡単なReact + Flask をExe化して動かしてみたいと思います。

コードの詳細が見たい方はこちらから見てください。
Flask + React でHello World

フォルダの階層はこんな感じです。

app
  ├── backend
      └── main.py
  └── frontend
        ├── node_modules
        ├── package.json
        ├── public
        ├── README.md
        ├── yarn.lock
        └── src
            ├── その他省略...
            ├── App.js
            └── index.js

FrontendのReact側


こちらはjsファイルをbuildして、できたファイルをbackend側に埋め込んでいきます。

ターミナル操作でapp/frontend/src下に移動しましょう。

$ cd app/frontend/src

buildを行います。

$ yarn build index.js

成功したらapp/frontend/buildフォルダが仕上がると思います。

このbuildフォルダをapp/backend下にコピぺしましょう。

いま現在のフォルダ構成はこんな感じになっています。(変更された場所に「← new」を入れてあります)

app
  ├── backend
      ├── build ← new
      └── main.py
  └── frontend
        ├── build ← new
        ├── node_modules
        ├── package.json
        ├── public
        ├── README.md
        ├── yarn.lock
        └── src
            ├── その他省略...
            ├── App.js
            └── index.js

BackendのFlask側


先ほどbuildしたのでapp/backend/build/index.htmlが出来てます。

そのindex.htmlを返すようにapp/backend/main.pyに変更を加えます。

import sys # 追加
from flask import Flask, request, make_response, jsonify, render_template # 編集
from flask_cors import CORS

# -- 追加 ここから ---------
ROUTE = sys.path[1] if 2 == len(sys.path) else '.'
TEMPLATES = ROUTE + '/build'
STATIC = ROUTE + '/build/static'
# -- ここまで ---------

app = Flask(name, static_folder=STATIC, template_folder=TEMPLATES) # 編集
CORS(app)
# -- 追加 ここから ---------
@app.route('/')
def index():
    return render_template('index.html')
# -- ここまで ---------

@app.route('/hello', methods = ['GET'])
def hello():
    text = 'Hello World'
    response = {'result': text}
    return make_response(jsonify(response))


@app.route('/helloworld', methods = ['GET', 'POST'])
def helloworld():
    text = 'Hello World'
    response = {'result': text}
    return make_response(jsonify(response))


@app.route("/post", methods=['GET','POST'])
def parse():
    data = request.get_json()
    text = data['post_text']
    response = {'result': text}
    return make_response(jsonify(response))


if name == 'main':
    app.run(debug=True, port=5000, threaded=True)

render_templateを追加して、index.htmlを返すよう編集しました。

少しコードの解説をしますと、
Exeで動く場合は実行される場所が違うのでif文で確認してます。
どこで実行されているかを確認するために、print(ROUTE)で確認してみてもいいかもです。

# -- 追加 ここから ---------
ROUTE = sys.path[1] if 2 == len(sys.path) else '.'
TEMPLATES = ROUTE + '/build'
STATIC = ROUTE + '/build/static'
# -- ここまで ---------
# print('ROUTE: ' + ROUTE)


これで準備完了です。

pyinstallerを使ってExe化します。
インストールがまだな方はinstallしてください。

$ pip install pyinstaller

ターミナル操作でapp/backendまで移動します。

$ cd ../../backend

main.pyをpyinstallerします。

$ pyinstaller -F --add-data "build:build" --onefile --clean main.py

最後の行に「3790 INFO: Building EXE from EXE-00.toc completed successfully.」と表示されたら成功です。

新たにapp/backend/dist/mainができます。
このmainファイルが実行可能なExeになっています。

あとはダブルクリックで実行して動かしてみるだけです。

無事に動けばこういう表示がされます。

  * Serving Flask app "main" (lazy loading)
  * Environment: production
    WARNING: Do not use the development server in a production environment.
    Use a production WSGI server instead.
  * Debug mode: on
  * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
  * Restarting with stat 

Chrome等で、http://localhost:5000にアクセスしたらページが表示されるはずです。

最後に


pyinstallerの説明はこちらの方がもう少し詳しく載せてますので、うまくいかない場合等は見てみてください。
Flaskファイルをpyinstallerを使ってExe化してみよう

reactもexe化をする気でしたが、yarn build main.pyで出来た。
「react exe化」が、なかなか良い記事にヒットせずにググるのにも時間がかかりました。

「flask react exe」とかで検索してもなかなか出てこないので出来るまでが大変でした。

時間はかかったが、なんとか出来て良かった!!


以上で、React + Flask をExe化して動かしてみるでした。

Flaskカテゴリの最新記事