Building Web Apps with Django ,Webpack and React
Throughout this tutorial we are going to learn how to use React JavaScript library and Webpack with Django to create modern web applications .
Webpack is a module bundler and a build tool that bundles JavaScript and other assets for better consuming by web browsers .
The aim of this tutorial is to show you the steps for using React with Webpack as the front end of your Django web applications .
So lets get started !
Create a virtual environment
Lets start by creating a virtual environment using virtualenv so open your terminal then run :
virtualenv myenv
Next activate the environment with :
source myenv/bin/activate
Next install Django using pip :
pip install django
Then create a django project :
django-admin.py startproject django-react-demo
To be able to install npm modules we need to create an npm module .This can be done by adding a package.json with some information to a folder which marks the folder as an npm module .
Add package.json
Generate a package.json inside your project root folder using :
npm init
npm will ask you for some information ,enter them and hit Enter .
Now lets install the npm dependencies we need in our project
Installing and setting up Webpack
npm install webpack webpack-bundle-tracker babel babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev
So we have installed webpack and webpack-bundle-tracker which tracks bundles and saves information in json file (webpack-stats.json)
After installing the required dependencies we need a config file for Webpack to tell it what to do .
Navigate inside your project root folder then run :
touch webpack.config.js
Then add this :
var path = require("path")
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
module.exports = {
context: __dirname,
entry: './assets/js/index.js',
output: {
path: path.resolve('./assets/bundles/'),
filename: "[name]-[hash].js",
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
],
module: {
loaders: [
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },
{ test: /\.jsx$/, loader: 'babel-loader', exclude: /node_modules/ }
],
},
}
entry: the entry file of the files to bundle.
output: the location of the bundled file to be saved.
loaders: plugins to call for each .js and jsx file ,in our case it's babel-loader .
We exclude files in node_modules .
plugins : contain Webpack plugins .In our case we add the bundles tracker we installed earlier.
Make sure you create the folders assets and js for our assets :
mkdir -p assets/js
Installing and setting up babel
Babel is a Javascript compiler / transpiler that compiles ES6 to ES5 so we can use next JavaScript in actual browsers without worrying about current browser support .
label-loader is used to integrate babel in Webpack workfow .
Loaders are plugins used by Webpack to add functionality .
npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev
We installed babel , babel-core , babel-loader ,babel-preset-es2015 and babel-preset-react
babel-preset-es2015 and babel-preset-react are presets or babel plugins to add compiling support for ES6 and React features.
Now lets create a babel configuration file :
Navigate to your project root folder then execute
touch .babelrc
Then open it and add :
/*
./.babelrc
*/
{
"presets":[
"es2015", "react"
]
}
This will enable Babel to compile ES6 and react
Here is our project folder structure
PROJECT_ROOT/
├── manage.py
├── package.json
│── webpack.config.js
│── .babelrc.js
│── webpack-stats.json
├── node_modules/
├── assets/
│ └── js/
│ └── bundles/
Install React and create our React App
The next step is to install React and other dependencies :
npm install --save-dev react react-dom
Now lets create a simple React app to integrate it with Django as a front end .
in assets/js/ create index.js
cd ./assets/js
touch index.js
Then add :
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
render() {
return (
<div style=>
<h1>Helle Django + React = Awesomeness </h1>
</div>);
}
}
ReactDOM.render(<App />, document.getElementById('react-app'));
You can now test your setup to see of there is an error when running webpack .
In the root of your project run :
./node_modules/.bin/webpack --config webpack.config.js --watch
This will execute webpack in watch mode so whenever there are changes webpack will bundle and compile (with babel ) the files again .
Integration with Django
If you have no problem in running webpack and getting the bundle of your simple react app (in assets/bundles/) the next step would be integrating the bundle with Django .
Webpack with Babel take care of compiling and bundling our front end react app so Django has only to include the result bundle and serve the first page .
We are going to use a Django package to integrate Webpack seamlessly with Django
pip install django-webpack-loader
Django webpack loader consumes the output generated by webpack-bundle-tracker and lets you use the generated bundles in django.
Now lets configure django-webpack-loader in settings.py
First add it to installed apps :
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'webpack_loader'
]
Then add a configuration object for webpack loader to tell it where to find bundles and where to find stats file generated by webpack-bundle-tracker
WEBPACK_LOADER = {
'DEFAULT': {
'BUNDLE_DIR_NAME': 'bundles/',
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
}
}
We need also to add our assets folder to staticfiles_dirs :
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'assets'),
)
So we can access the bundle without running collectstatic in development mode .
The next thing is to create a Django view to serve the first page .
Create a Django App
First create a Django app called inventory for example
python manage.py startapp inventory
Add it to installed apps in settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'webpack_loader',
'inventory'
]
Next create a view function in inventory/views.py :
from django.shortcuts import render
def index(request):
return render(request, 'inventory/index.html', {})
Then create a template in inventory/templates/inventory/ folder :
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>React with Django </title>
</head>
<body>
<div id="react-app"></div>
{% render_bundle 'main' %}
</body>
</html>
render_bundle will render the proper