Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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()?

like image 267
Simon Johansson Avatar asked Apr 25 '18 18:04

Simon Johansson


1 Answers

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.

like image 181
discover Avatar answered Nov 19 '22 07:11

discover