Django, ReactJS, Webpack hot reload
I've been trying to set up a React component inside Django with the help of Webpack 4.
To get me starting I went through and read:
-
Using Webpack transparently with Django + hot reloading React components as a bonus
-
Tutorial: Django REST with React (Django 2.0 and a sprinkle of testing)
Both these walkthroughs are great. At last, I got it almost working by following the second link even though I use Django 1.11.
The problem I had after following the second link was that hot reloading does not work when using a webpack-dev-server
. The problem is that Django cannot read the output file of the webpack-dev-server
(gives 404 error) while the main.js
can be read. I've read that the dev-server
files do only live in memory by default.
To overcome the issue with error 404 on the hot reload files I installed the package write-file-webpack-plugin
to write out the file each reloads. Then changed the webpack-config.js
to (I deleted some lines to keep it shorter....):
var path = require('path');
//webpack is not needed since I removed it from plugins
//const webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var WriteFilePlugin =require('write-file-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
]
},
entry: [
'./frontend/src/index',
],
output: {
path: path.join(__dirname, 'frontend/static/frontend'),
// Changing the name from "[name]-[hash].js" to not get 1000 files in the static folder.
filename: 'hotreloadfile.js'
},
plugins: [
//This line writes the file on each hot reload
new WriteFilePlugin(),
//This can be removed.
//new webpack.HotModuleReplacementPlugin(),
new BundleTracker({filename: './webpack-stats.json'})
],
mode:'development',
};
in my package.json
I have the follow line among the script tag:
"start": "webpack-dev-server --config ./webpack.config.js",
And in Django I installed webpack-loader
with the following lines in settings.py
:
STATIC_URL = '/static/'
WEBPACK_LOADER = {
'DEFAULT': {
'BUNDLE_DIR_NAME': 'frontend/',
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json')
}
}
Finally, in my root component called index.js
, I do not need the module.hot.accept();
line
Do you see any drawbacks to this approach? Except that I had to install another package?
Why didn't I get it to work with new webpack.HotModuleReplacementPlugin()
?
Here is another approach if you develop frontend in react and backend in django. I have django server running on port 8000 and react server running on port 3000.
If I add "proxy": "http://localhost:8000"
line in package.json of react code, localhost:3000 will do hot-reloading while api call goes to localhost:8000.