React and Flask for Side Projects
November 25th, 2018
This week, I finally got a basic version of React working with Flask. I’ve had a lot of trouble with this, not because it was technically difficult, but the overwhelming amount of choice in the JavaScript world.
Why Flask?
What I love about Flask is the same thing I love about Python: expressiveness. I felt the same kind of joy writing my first line of Python:
print 'Hello, World'
as writing my first Flask app:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, World'
Both are like legos: you don’t need to read the whole manual to start playing. For the same reasons, I’ve adopted a lot of other tools like Flask-SQLAlchemy, Flask-Login, Redis. Modern apps, however, require you have a semi-thick client. Having experienced the luxuries of a good JavaScript development environment at Sentry and Numeracy, I wanted the luxuries of modern JavaScript, JSX, transpilation, and reasonable stack traces in development.
Here’s the experience I’ve wanted to have:
templates/index.html
<h1>Regular HTML</h1>
<div id="fancy-javascript-component"></div>
<script type="text/javascript" src='app.js'></script>
app.js
class FancyComponent extends React.Component {
render() {return <div>Encapsulating some complex behavior</div>}}
ReactDOM.render(<FancyComponent />, document.getElementById('fancy-javascript-component'))
Why not create-react-app
?
The most obvious choice is create-react-app, but it was very unclear how user/session management would work, unless I planned on having a Node backend.
This then plays into the reason I use Python and specifically, Flask. It’s obvious both Python and Flask have very real limitations, but with my side projects, my greatest priority is expressiveness. I think in Python, and I don’t think that’s going to change anytime soon.
Another undesirable effect of create-react-app is…I’m suddenly building two apps: a API backend and a JS frontend. While de-coupling these two might be the “right” pattern for companies, it’s a huge pain for side projects.
I like React components, but I don’t want to start off with single page apps. 80% of my pages only need HTML/CSS, so I’d prefer to selectively add React components and over time, have a library of components that if I want to later migrate to a SPA, it’d be pretty easy.
Finding my Lego
I finally landed on Parcel. Here’s my blueprint.
static/
∟ src/
∟ index.js
∟ helloMessage.jsx
∟ index.scss
templates/
∟ index.html
.babelrc
Pipfile
app.py
package.json
Note: I’m using pipenv
for managing my Python environment, so the Pipfile details the dependencies.
My template index.html
points to /static/dist/index.js
, which imports other components. This means if more than one page requires React components, say login.html
, you just need to create /static/src/login.js
, and link to it in the template.
To start up the development environment:
pipenv run flask run
npm run watch
Production
I use dokku
In the post-deploy config,
npm run build
pipenv lock -r > requirements.txt
Tada! This is my first pass, so hopefully, I’ll be contining to update the repo as I learn more.