If you use webpack to build your front-end resources, you can use the optional webpack-dev-server to automatically reload the webpage when your code changes. It’s similar to what you want to accomplish with tools like LiveReload or Browsersync.

The webpack-dev-server uses an Express.js server to serve your bundles and communicates changes with the browser using Socket.IO. If your project allows Hot Module Replacement, webpack-dev-server can also update modules live in the browser without reloading the entire page which is very cool.

Usually when you’re developing with Django, the static files will be served by the development server and you’ll have something like this in your templates:

{% load static %}

<script src="{% static 'project/js/bundle.js' %}"></script>

However, when you’re using webpack-dev-server you’ll have to serve your JS bundle from http://localhost:8080 (default host and port of webpack-dev-server) like this:

{% load static %}

{% if settings.WEBPACK_DEV_SERVER %}
    <script src="http://localhost:8080{% static 'project/js/bundle.js' %}"></script>
{% else %}
    <script src="{% static 'project/js/bundle.js' %}"></script>
{% endif %}

This works fairly OK if you have this setting exposed in your templates. The downside is that you manually have to change this setting each time you want to enable or disable webpack-dev-server during development, aside from starting webpack-dev-server.

To make life a little bit easier I’ve created a template tag that will serve the JS bundle from its normal location by default and automatically uses the webpack-dev-server version if that’s available:

# project/templatetags/project_tags.py

import requests
from django import template
from django.conf import settings

register = template.Library()

@register.inclusion_tag('partials/webpack.html')
def webpack(bundle):
    """
    NOTE: the webpack-dev-server host and port are hard-coded here and you
    should probably make this available via a setting.
    Also, I'm using the requests library but you can also use urllib of course.
    """
    use_dev_server = False

    if settings.WEBPACK_DEV_SERVER:
        try:
            request = requests.get(
                'http://localhost:8080/static/project/js/{}'.format(bundle)
            )
            if request.status_code == 200:
                use_dev_server = True
        except requests.ConnectionError:
            pass

    return {
        'bundle': bundle,
        'use_dev_server': use_dev_server,
    }
<!-- partials/webpack.html -->

{% load static %}

<script src="{% if use_dev_server %}http://localhost:8080{% endif %}{% static 'project/js/'|add:bundle %}"></script>

Then, add your webpack bundle to your templates like this:

{% load project_tags %}

{% webpack 'bundle.js' %}

It adds a neglible performance cost of 1 local HTTP request during development, but I definitely think it’s worth it have your site automatically use the webpack-dev-server bundle when it’s available instead of manual switching. Another benefit is that you don’t see broken pages when you forget to start webpack-dev-server because the regular bundle will always be served.