Hot loading a ReactJS app in Django Part 3/3
In part two, we setup the link between Django
and ReactJS
with the help of Webpack
. We need to run three commands just to quickly reload a server and view UI changes. In this guide, we will setup react-hot-loader
to allow live changes to be reflected on our Django
application that is showing the react
components.
If needed, please revisit part two. You can also checkout the part3 branch here to continue.
Step 1: Update webpack config
We will need to update web pack config to use react-hot-loader
.
Update the entry
to this:
entry:[
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:3000/',
'webpack/hot/only-dev-server',
'./assets/static/js/index',
],
output
should be updated to:
output: {
path: path.resolve('./apps/static/bundles/'),
filename: '[name]-[hash].js',
publicPath: 'http://localhost:3000/static/bundles/',
},
Then finally plugins
to:
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new BundleTracker({filename: './webpack-stats.json'}),
],
What we are doing here are updating the config of webpack
to cater for react-hot-loader
. These are just a bunch of settings to follow. You can visit webpack and react-hot-loader to learn more. What you need to know is, during development, instead of going to usual directory to read static files, we are now going to localhost:3000
.
Since we are using react-hot-loader v3
we need to update .babelrc
:
{
"presets": ["react"],
"plugins": ["react-hot-loader/babel"]
}
Step 2: Watch for changes
Now instead of recompiling whenever we make a change, we will run a server to do it.
Create a server.js
file in root directory.
var webpack = require('webpack')
var WebpackDevServer = require('webpack-dev-server')
var config = require('./webpack.config')
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
inline: true,
historyApiFallback: true,
headers: {
'Access-Control-Allow-Origin': '*',
},
}).listen(3000, '0.0.0.0', function (err, result) {
if (err) {
console.log(err)
}
console.log('Listening at 0.0.0.0:3000')
})
Once that is completed, we can run the server with either of the command below:
$ node server.js #either this or
$ npm run watch #where we setup this in part 1
Step 3: Update the index.js
Now, because we are using react-hot-loader
, we need to update index.js
and move any component that could possibility change to another file.
Update index.js
to this:
import React from 'react';
import ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import App from './App'
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('app')
)
}
render(App)
if (module.hot) {
module.hot.accept('./App', () => { render(App) })
}
The above are the exact configuration we take from the github docs. Next, we will need to create a new App.js
that we are importing here.
import React from 'react';
const App = () => {
return (
<div>
<h1>Hello World!</h1>
</div>
);
}
export default App;
Thats all we need. Now ReactJS
component live inside Django
and with the help of webpack
and react-hot-loader
we can have a better development environment.
See hot loader in action:
Just run npm run watch
and another python manage.py runserver
.
Keep the two session running while coding. This is what we will see:
Use in Production
In production, we does not need to use react-hot-loader
. Therefore we should have a separate file called wepack.prod.config.js
. This is what i have inside it:
var path = require("path")
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
module.exports = {
context: __dirname,
entry: [
'./assets/static/js/index'
],
output: {
path: path.resolve('./assets/static/bundles/'),
filename: '[name]-[hash].js',
},
plugins: [
new BundleTracker({filename: './webpack.prod-stats.json'}),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}}),
new webpack.optimize.OccurrenceOrderPlugin(),
],
module: {
loaders: [
{ test: /\.jsx?$/, exclude: /node_modules/, loaders: ['babel-loader'], },
],
},
resolve: {
modules: [
'node_modules',
'bower_components'
],
extensions: ['.js', '.jsx']
}
}
Basically the different is there is no react-hot-loader
config and we also added a few plugin
to remove debug code.
To run on production, ensure that the step of npm run build-prod
is run before collectstatic
when in production.
References
Most of the content that I have here are gather from various sources when trying to implement ReactJS
into my Django
project.
- Using Webpack transparently with Django + hot reloading React components as a bonus - Owais Lone
- Set up a Django + ReactJS project with Webpack manager ยท GitHub
- Webpack2 Getting Started
- GitHub - ezhome/django-webpack-loader: Transparently use webpack with django
Where to go from here
ReactJS
is very much just another way to render view. It is not another MVC
framework. In order to show is full potential, it need to be somehow connected with a backend services. Here, I am directly rendering it with a Django
backend. However there are a lot more different setup, like using it with redux or flux.
Live Production Example!
In the very same blog, the App Page are build with the same setup that I described here.