[Solved]-Django/Webpack – How to serve generated webpack bundles with webpack dev server

11πŸ‘

βœ…

Let’s analyze the issue:

We have 2 servers and we want to route requests to one or the other based on the path requested:

"/static/webpackbundles/** ==> webpack dev server

other paths ==> django dev server

This is exactly the job of a proxy server, it can be achieved with a third server (haproxy, nginx …), but that might seem like an overkill, especially if we know that webpack dev server can be used as a proxy! (https://webpack.js.org/configuration/dev-server/#devserverproxy)

webpack.config.js

const path = require('path');

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: '/path/to/django_project/django_project/static/webpackbundles',
    publicPath: '/static/webpackbundles/',
  },
  devServer: {
    contentBase: '/path/to/django_project/django_project/static/webpackbundles',
    hot: true,
    proxy: {
      '!/static/webpackbundles/**': {
        target: 'http://localhost:8000', // points to django dev server
        changeOrigin: true,
      },
    },
  },
};

In your django template:

<script type="text/javascript" src="{% static 'webpackbundles/main.js' %}"></script>

Now access your django app/site using webpack dev server address:
ex: http://localhost:8081

With this simple config you’ll have browser auto refresh and hot module replacement.
You will not need to change anything in django, also no need for django-webpack-loader

πŸ‘€Ejez

0πŸ‘

Building on @Ejez answer, i was able to configure webpack-dev-server to serve all static files (including, media files)

webpack.config.js

module.exports = {
    // project root (usually package.json dir)
    context: path.dirname(path.resolve(__dirname)),
    output: {
        path: path.resolve('./path/to/bundles/'), 
        filename: "[name]-[hash].js"
    },
    resolve: {
        extensions: ['.ts', '.js' ]
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.ts$/,
                use: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        new BundleTracker({filename: '/path/to/webpack-stats.json'})
    ],
    optimization: {
        splitChunks: {
            chunks: 'all',
            name: 'lib'  // bundle all their party libraries in lib.js
        }
    },
    devServer: {
    // if you do not mind webpack serving static files of other apps
    // collect them (with django collectstatic) into /static_root/static/ 
    // this way webpack-dev-server can serve from your own app's /static/
    // directory and also /static_root/static/ directory (which contains
    // static files of other apps
        contentBase: [path.resolve('./project'), path.resolve('./project/static_root')],

        // webpack bundles will be served from http://locahost:3000/static/project/bundles/
        publicPath: '/static/project/bundles/',

        port: 3000,

        // proxy all request except (static and media files) to django dev server
        proxy: [{
            context: ['**', '!/static/**', '!/media/**'],
            target: 'http://localhost:8000',
            changeOrigin: true,
        }]
    }
}

Now you can access your project from webpack-dev-server url localhost:3000. Do not forget to start both dev servers (webpack and django)

πŸ‘€myke

0πŸ‘

Is generally not justified using STATICFILES_DIRS,
instead use STATIC_ROOT.
If You have permission to copy static files to the project folder then use STATIC_ROOT.

πŸ‘€J. G.

Leave a comment