前提
開発環境
- mac OS X
- Python 3.7.1
- pip 19.3.1
- Pipenv, version 2018.11.26 (インストール:
python -m pip install pipenv
) - Flask
- Node.js v10.16.0
- Vue.js (@vue/cli v4.1.2)
- Herokuのアカウント、あるよ。
ディレクトリ構成の目標
[approute]
|-- [server] -- サーバーサイド(Flask app)
|-- [client] -- クライアントサイド(Vue app)
`-- サーバー起動にまつわる設定ファイル
サーバーサイドの準備
仮想空間の作成
$ pipenv install flask
→プロジェクト用の仮想空間&[Pipfile][Pipfile.lock]ファイルが作成される
[approute]
|-- Pipfile
`-- Pipfile.lock
(pc)Users/xxxxxx/virtualenvs/xxxxxxx
Flask appのシンプルな内容のコードを取り急ぎ置いてみる
HOME URLにやってきたら「Hello world」って返すだけ。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
hello = "Hello world"
return hello
if __name__ == "__main__":
app.run(debug=True)
仮想空間で実行するscriptを作成
packageは仮想空間にあるので、そちらを実行するようなスクリプトを作成
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
flask = "*"
[requires]
python_version = "3.7"
[scripts] //←追記
start = "python server/main.py" //←追記
$ pipenv run start
で実行できるようになる
Herokuにdeploy
gunicornをインストール
HerokuのPythonサポートはgunicornというWEBサーバーを通して行なっている様です。
ということで $ pipenv install gunicorn
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
flask = "*"
gunicorn = "*" //←ここが追記された
[requires]
python_version = "3.7"
[scripts]
start = "python server/main.py"
そして、実行スクリプトを記載。server/main.py
のappを実行するには、↓のように書く
web: gunicorn server.main:app --log-file -
一応、ローカルでも$ gunicorn server.main:app
で実行確認してみる
Herokuでapp作成
Heroku( https://jp.heroku.com/ )でアカウントを作成して、appも作成。
そしたらdeploy手順が掲載されているので、順次実行していく。
$ heroku login // Herokuにログイン
$ cd approute //作業ルートに移動
$ git init //git初期化
$ heroku git:remote -a hogehoge //Herokuにリモートレポジトリ
$ git add .
$ git commit -am "make it better" //gitにコミット
$ git push heroku master //Herokuにpush
$ heroku open //デプロイしたアプリを開く
Herokuにデプロイしたappから「hello world」言われました。
世界が開けたようです。よかったよかった。
クライアントアプリを作成
Vue UIでプロジェクトを作成
Vue UI、使いやすいので活用しようと思います。
↑今回はアプリルートのgit使っているのでoffります。
これ以降のプリセットとかはとりあえず好きにすればいいと思う。
SPAなので、Routerは必須。
そしたら、しばらくダウンロードとかで待つと。。。
できあがるので、↓の画面から実行スクリプトも実行できますよと。
SPA
クライアントサイドでSPA作る
Vue UIの「プロジェクト設置>Vue CLI>アセットディレクトリ」からでも、
主導で設定ファイルを作ってでもいいので、staticファイルの書き出し先をstaticに設定。
module.exports = {
assetsDir: 'static'
}
で、Vue UIでも、termimnalでもいいから、$ npm run build
を実行→appがコンパイルされる
[approute]
|-- [client]
|--[dist] //←生成される
|--[static] //←jsとか書き出される
`--index.html //←rootのHTMLができる
|--[public]
|--[src]
|--vue.config.js
`--その他設定ファイル
サーバーサイドでクライアントアプリをテンプレートとして設定
結論として、こんな感じに書き換えます。
import os
from flask import Flask, render_template
app = Flask(__name__, static_folder='../client/dist/static', template_folder='../client/dist')
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
return render_template('index.html')
if __name__ == "__main__":
app.run()
ちっと分解。
from flask import Flask, render_template
(略)
return render_template('index.html')
↑Flaskのrendar_templateを追加しまして、Vueのapp側で書き出したルートファイルである[index.html]をセットします。
app = Flask(__name__, static_folder='../client/dist/static', template_folder='../client/dist')
↑Vueのapp側で書き出したstaticファイルの場所をこのファイルから見た相対パスで書きます。
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
↑どんなURLパスでやってきても、こちらで受け止めます、な感じ。
pipenv run start
→ お、世界に色が宿りました。
改めて、Herokuにpush
$ git add .
$ git commit -am "color from vue"
$ git push heroku master
$ heroku open
してみたら、、
500 Internal Server Error
jinja2.exceptions.TemplateNotFound: index.html
とのことで、ローカルでは見つかっていたVueによって生成されたindex.htmlが見つからない...ってことですかね?
世界が闇に包まれました。
Herokuにdeploy・改
複数のbuildpackに対応する
すでに、pipfileによって、自動的にpythonサーバーが起動する。
そこに、node.jsサーバーもたちあげたい。
$ heroku buildpacks:add --index 1 heroku/nodejs
$ heroku buildpacks
=== xxx Buildpack URLs
1. heroku/nodejs
2. heroku/python
で、このまま起動しても
remote: ! The 'heroku/nodejs' buildpack is set on this application, but was
remote: ! unable to detect a Node.js codebase.
remote: !
remote: ! A Node.js app on Heroku requires a 'package.json' at the root of
remote: ! the directory structure.
と言われるわけで、package.jsonをルートに持ってこいと言われます。
Vue.jsのアプリのディレクトリ構造を変更する
いったん書き出していた[dist]ディレクトリを削除して、[client]ディレクトリの中身をまるっとルートに移動させる
[approute]
===Flask===
|--[server] -- main.py
|--Pipfile
|--Procfile
|--その他設定ファイル
===Vue.js===
|--[public]
|--[src]
|--package.js
|--babel.config.js
|--vue.config.js
`--その他設定ファイル
それにともなって、書き換え
app = Flask(__name__, static_folder='../dist/static', template_folder='../dist')
Herokuにpushしてみたら、動いた!世界に光が戻りました。
ということで、このベースの世界から発展開発をしていきたいと思います。
結論
とりあえず、やったことを書いてみましたが。。
あったんだよね、先人の知恵
https://github.com/gtalarico/flask-vuejs-template
https://github.com/oleg-agapov/flask-vue-spa
なんか、ディレクトリ構成がね〜。
vue.config.jsとか設定して、1段掘れないかしら。