(This article is one year old and things changed quite a bit regarding React. Check out React and SASS with Flask-Webpack.)

Last year during my master thesis intership at CERN, I’ve spent quite some time fiddling with React within a Flask application. Flask is a microframework to build web application in Python and React a powerful library to create web components coming from the Facebook folks. You may find some examples around. To my knowledge none of them are addressing the production phase.

In the following tutorial, we will build a simple web page that uses React through Require.js and produces an almost production ready configuration. We will also use Require.js to deal with JavaScript dependencies.

A sample Flask application

Let’s be on the safe side of the force and create a virtual environment for our application. It means that packages will be installed locally rather than globally.

We won’t go into setup.py fun here and install everything directly. Having a setup.py will enable you to package, distribute, etc. your application. DigitalOcean has a good introduction article on “How To Package And Distribute Python Applications.”

Great, we can now create the application itself. You may create the files src/app.py and src/templates/index.html as follow. The templates are using Jinja2 syntax by default.

React.js plus some Require.js

When building web applications, getting organized may be quite messy. The Asynchronous Module Definition (AMD) let us have separate modules that are requiring each other in a way that let us organize code in logical modules.

Note: Node.js uses the CommonJS approach which is less browser friendly and requires extra steps. Fell free to explore browserify.

We will manage the JavaScript libraries using Bower. A tool from Twitter that helps with downloading Front-End resources. It is, as well as RequireJS, installed through NPM (the package manager for Node.js).

The .bowerrc trick lets us define to what location those files end up being downloaded. It’s quite handy to have them directly in the static folder.

Now that everything is ready, let’s react!

There is many files here, but they are simple to understand:

index.html the template that calls the JavaScript loader (require.js), its configuration (config.js) and the application itself (app.js).

require.js comes from some downloaded code and will manage the loading and execution of the JavaScript code.

config.js tells Require.js some important informations like where are located some libraries (paths represent some kind of shortcuts) and that we wanted to use the .jsx extension for our JSX files.

app.js is the application. It requires jQuery, React and the Main module and applies it. As you can see there is a jsx! before the main file. Its goal is to inform that this file has to go through some kind of filter beforehand.

main.jsx is the main (and only in our case) React.js component. We could imagine that Main was requiring other libraries or React.js component. It could be done via a simple require(“jsx!name”).

Run it through and visit the given URL: python src/app.py

Going into production

The application as it is runs in development mode. Each file is loaded asynchronously and create a lot of HTTP requests. In production, we would like to minimise those and probably rely on CDN’s for some very popular libraries like jQuery.

We will now put in use the installed stuff we didn’t use yet. We’ve installed Flask-Assets (via pip), require.js (via npm) and almond.js (via bower). Flask-Assets will use require.js to compile (on the fly, as needed) our application using r.js. almond.js is a very basic and light require.js for the browser that cannot do asynchronous loading of modules.

The changes are quite small but yet important.

Let’s go file per file:

app.py defines a Bundle coming from the Flask-Assets module. This bundle is responsible of compiling the source file into a shrinken version. If we had a config.js file for the Front-End, the build.js defines how we will compile it here.

build.js is like the config.js file with some changes. We don’t want jQuery from the local library but will use one from a CDN, so “empty:”. UglifyJS will clean up the combined file. stubModules will prevent the util modules to be included in the final file (the .jsx files are being compiled).

index.html now includes the different files depending on the setup. In the case of ASSETS_DEBUG is True, then the source files of the bundle will be used, otherwise the minified file will be.

Conclusion

We’ve seen how to create a basic Flask application that can work with raw JavaScript files (here AMD and JSX from React) and be compiled into a small production ready file. A same approach can be done for CSS (less, scss or sass). The nice thing about it is that you can start by doing it in development mode and then think about how you’ll actually compile and merge everything. No extra software beside Flask is imho good.

This solution may appear heavy to developers that rely on gulp, grunt or other similar tools to compile their JavaScript libraries (and do even much more). In our case, the main benefits were that it didn’t introduce a new tool that wasn’t required otherwise. Bower is already enough to deal with. Moreover, it’s possible to compile the files from the command line via Flask-Script and package them in a wheel without the vendors as they are only useful for the development environment.

In the case of the CERN, one requirement was to handle a very modular architecture where various modules may need a similar set of libraries. So the bundles made sense in our case as we can define the JavaScript dependencies from the Python files (or the templates) themselves. But that’s another story.