MCPcopy Index your code
hub / github.com/django-webpack/django-webpack-loader

github.com/django-webpack/django-webpack-loader @3.2.4

Chat with this repo
repository ↗ · DeepWiki ↗ · release 3.2.4 ↗ · + Follow
133 symbols 581 edges 84 files 42 documented · 32% 2 cross-repo links
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

django-webpack-loader

Build Status Coverage Status pyversions djversions

Integrate Webpack bundles in Django templates by using a simple template tag:

{% load render_bundle from webpack_loader %}

<html>
  <head>
    {% render_bundle 'main' 'css' %}
  </head>
</html>

Behind the scenes, Django Webpack Loader consumes a stats file generated by webpack-bundle-tracker and lets you use the generated bundles in Django.

A changelog is available.

Compatibility

Generally, Python, Django, and Node LTS releases will be supported until EOL. Check tests/tox.ini for details.
Versions not listed in tests/tox.ini may still work, but maintainers will not test them, nor solve issues with them.
Examples below are in Webpack 5.

Install

npm install --save-dev webpack-bundle-tracker

pip install django-webpack-loader

Configuration

For kick-starting a full example project with opinionated development and production settings, you can check the django-react-boilerplate. For a more flexible configuration, keep reading.

Configuring webpack-bundle-tracker

Before configuring django-webpack-loader, let's first configure what's necessary on webpack-bundle-tracker side. Update your Webpack configuration file (it's usually on webpack.config.js in the project root). Make sure your file looks like this (adapt to your needs):

const path = require("path");
const webpack = require("webpack");
const BundleTracker = require("webpack-bundle-tracker");

module.exports = {
  context: __dirname,
  entry: "./assets/js/index",
  output: {
    path: path.resolve(__dirname, "assets/webpack_bundles/"),
    publicPath: "auto", // necessary for CDNs/S3/blob storages
    filename: "[name]-[contenthash].js",
  },
  plugins: [
    new BundleTracker({ path: __dirname, filename: "webpack-stats.json" }),
  ],
};

The configuration above expects the index.js (the app entrypoint file) to live inside the /assets/js/ directory (this guide going forward will assume that all frontend related files are placed inside the /assets/ directory, with the different kinds of files arranged within its subdirectories).

The generated compiled files will be placed inside the /assets/webpack_bundles/ directory and the stats file with the information regarding the bundles and assets (webpack-stats.json) will be stored in the project root. You may add webpack-stats.json to your .gitignore.

Configuring the Django settings file

First of all, add webpack_loader to INSTALLED_APPS.

INSTALLED_APPS = (
    ...
    'webpack_loader',
    ...
)

Below is the recommended setup for the Django settings file when using django-webpack-loader.

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'assets'),
)

WEBPACK_LOADER = {
    'DEFAULT': {
        'BUNDLE_DIR_NAME': 'webpack_bundles/',
        'CACHE': not DEBUG,
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
        'POLL_INTERVAL': 0.1,
        'IGNORE': [r'.+\.hot-update.js', r'.+\.map'],
    }
}

Note that you must set the path where you're keeping your static assets and Webpack bundles in STATICFILES_DIRS.

For that setup, we're using the DEBUG variable provided by Django. Since in a production environment (DEBUG = False) the assets files won't constantly change, we can safely cache the results (CACHE=True) and optimize our flow, as django-webpack-loader will read the stats file only once and store the assets paths in memory. If CACHE=False, we'll always read the stats file to get the assets paths.

The STATS_FILE parameter represents the output file produced by webpack-bundle-tracker. Since in the Webpack configuration file we've named it webpack-stats.json and stored it on the project root, we must replicate that setting on the backend side.

During development, the stats file will change often, therefore we want to always poll for its updated version (every 0.1s, as defined on POLL_INTERVAL).

⚠️ In production (DEBUG=False), we'll only fetch the stats file once, so POLL_INTERVAL is ignored.

IGNORE is a list of regular expressions. If a file generated by Webpack matches one of the expressions, the file will not be included in the template.

Compiling the frontend assets

Using Webpack, you must generate the frontend bundle along with the stats file using webpack-bundle-tracker before using django-webpack-loader in Django templates. Note you'll probably want different configurations in development vs. production. The pipeline should look like this:

flowchart TD
    A("Run webpack")
    A --> |CSS, JS, imgs, fonts| B(Collect compiled assets)
    A --> |webpack-stats.json| C(Read on Django templates)

In development, we can simply do:

# in one shell
npx webpack --mode=development --watch

# in another shell
python manage.py runserver

Check the full example for development here.

Aditionally, hot reload is available through a specific config. Check this section.

⚠️ For compiling and serving the frontend assets in production, check this section.

Usage

In order to render the frontend code into the Django templates, we use the render_bundle template tag.

Its behavior is to accept a string with the name of an entrypoint from the stats file (in our case, we're using main, which is the default) and it'll proceed to include all files under that entrypoint. You can read more about the entrypoints concept here.

⚠️ You can also check an example on how to use multiple entry values here.

Below is the basic usage for render_bundle within a template:

{% load render_bundle from webpack_loader %}

<html>
  <head>
    {% render_bundle 'main' 'css' %}
  </head>
</html>

That will render the proper <script> and <link> tags needed in your template.

Using in tests

To run tests where render_bundle shows up, since we don't have webpack-bundle-tracker at that point to generate the stats file, the calls to render the bundle will fail. The solution is to use the FakeWebpackLoader in your test settings:

WEBPACK_LOADER['DEFAULT']['LOADER_CLASS'] = 'webpack_loader.loaders.FakeWebpackLoader'

Using in Production

The recommended apporach is to have a production pipeline that generates the frontend bundle along with the stats file during the deployment phase. We recommend keeping the generated bundles and the stats file outside the version control. In other words, add webpack-stats.json and assets/webpack_bundles/ to your .gitignore.

Assuming static files is properly configured using Django built-ins or something like django-storages, a simple production deployment can use Django's own collectstatic. Remember the Django settings values of STATICFILES_DIRS, BUNDLE_DIR_NAME, STATS_FILE, and Webpack's output.path must all be compatible:

// webpack.config.js
module.exports = {
  // ...
  context: __dirname,
  output: {
    // Emit bundle files at "assets/webpack_bundles/":
    path: path.resolve(__dirname, "assets/webpack_bundles/"),
    publicPath: "auto", // necessary for CDNs/S3/blob storages
    filename: "[name]-[contenthash].js",
  },
  plugins: [
    // Emit 'webpack-stats.json' in project root for Django to find it:
    new BundleTracker({ path: __dirname, filename: "webpack-stats.json" }),
  ],
};
# app/settings.py

BASE_DIR =  ... # set to project root

STATICFILES_DIRS = (
   # make Django collect all "assets/" and "assets/webpack_bundles"
   # to be served at "my-static-url.com/asset-name.png"
   # and "my-static-url.com/webpack_bundles/main.js"
   os.path.join(BASE_DIR, 'assets'),
)

WEBPACK_LOADER = {
    'DEFAULT': {
        # Bundle directory, like in "my-static-url.com/webpack_bundles/main.js":
        'BUNDLE_DIR_NAME': 'webpack_bundles/',
        # Absolute path to where 'webpack-stats.json' is in Django project root:
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
        # ...
    }
}

In your deployment script, you must first run your Webpack build in production-mode, before calling collectstatic:

NODE_ENV=production webpack --progress --bail --mode=production
python manage.py collectstatic --noinput

This means we're building the assets and, since we have webpack-bundle-tracker in our Webpack building pipeline, the webpack-stats.json stats file is also populated. If you followed the default configuration, the webpack-stats.json will be at Django's project root (BASE_DIR) and the render_bundle template tag will be able to use it.

However, production usage for this package is fairly flexible, as the entire Django-Webpack integration depends only on the webpack-stats.json file.

⚠️ Heroku is one platform that automatically runs collectstatic for you, so you need to set the DISABLE_COLLECTSTATIC=1 environment var and manually run collectstatic after running Webpack. In Heroku, this is achieved with a post_compile hook. Here's an example.

Advanced Usage

Hot reload

Hot reload (Hot Module Replacement) is critical for a improving the development workflow. In case you wish to enable for your project, please check out this example, in particular how webpack.config.js is configured. The key is to set the publicPath and devServer.

Dynamic Imports

In case you wish to use Dynamic Imports, please check out this example, in particular how webpack.config.js is configured.

Extra options for webpack-bundle-tracker

Check webpack-bundle-tracker README for all supported options, such as relative paths, integrity hashes, timestamp logging, etc.

Extra WEBPACK_LOADER settings in Django

Set those extra settings inside like this:

WEBPACK_LOADER = {
    'DEFAULT': {
       # settings go here
    }
  • TIMEOUT is the number of seconds webpack_loader should wait for Webpack to finish compiling before raising an exception. 0, None or leaving the value out of settings disables timeouts

  • INTEGRITY is a flag enabling Subresource Integrity on rendered <script> and <link> tags. Integrity hash is fetched from the stats of BundleTrackerPlugin. The configuration option integrity: true is required.

  • CROSSORIGIN: If you use the integrity attribute in your tags and you load your webpack generated assets from another origin (that is not the same host:port as the one you load the webpage from), you can configure the CROSSORIGIN configuration option. The default value is '' (empty string), where an empty crossorigin attribute will be emitted when necessary. Valid values are: '' (empty string), 'anonymous' (functionally same as the empty string) and use-credentials. For an explanation, see https://shubhamjain.co/2018/09/08/subresource-integrity-crossorigin/. A typical case for this scenario is when you develop locally and your webpack-dev-server runs with hot-reload on a local host/port other than that of django's runserver.

  • CSP_NONCE: Automatically generate nonces for rendered bundles from django-csp. Default False. Set this to True if you use django-csp and and 'strict-dynamic' CSP mode.

  • LOADER_CLASS is the fully qualified name of a python class as a string that holds the custom Webpack loader. This is where behavior can be customized as to how the stats file is loaded. Examples include loading the stats file from a database, cache, external URL, etc. For convenience, webpack_loader.loaders.WebpackLoader can be extended. The load_assets method is likely where custom behavior will be added. This should return the stats file as an object.

Here's a simple example of loading from an external URL:

```py import requests from webpack_loader.loaders import WebpackLoader

class ExternalWebpackLoader(WebpackLoader): def load_assets(self): url = self.config['STATS_URL'] return requests.get(url).j

Core symbols most depended-on inside this repo

Shape

Method 86
Function 28
Class 15
Route 4

Languages

Python97%
TypeScript3%

Modules by API surface

tests/app/tests/test_webpack.py62 symbols
webpack_loader/loaders.py16 symbols
tests_webpack5/app/tests/test_webpack.py12 symbols
webpack_loader/utils.py10 symbols
tests/app/tests/test_custom_loaders.py7 symbols
webpack_loader/exceptions.py5 symbols
webpack_loader/templatetags/webpack_loader.py4 symbols
webpack_loader/contrib/jinja2ext.py4 symbols
webpack_loader/apps.py3 symbols
webpack_loader/config.py1 symbols
setup.py1 symbols
examples/simple/manage.py1 symbols

Used by 2 indexed graphs manifest dependencies, hub-wide

For agents

$ claude mcp add django-webpack-loader \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page