Django & Webpack

Table Of Contents

  1. Overview
  2. Environment Setup & Requirements
  3. Setup Webpack
  4. First Webpack Packaged Assets

Overview

I’ll assume that you already know Django and is already well versed with it and you just want to integrate Webpack into your project. If you already know what is Webpack and how it works please proceed to Environment Setup & Requirements. For those of you that is not quite sure what Webpack will bring into your Django project then please read on for brief introductory of it.

Ever wanted to create a single Javascript and CSS file out of several sources that you currently have in your project? While also doing that wouldn’t it be good to have them minified along the way? Well with Webpack you can do this. It will help you compile all of your Javascript & CSS file and since you would also be using npm along with it then you will also get a good package/module management tool. Webpack is not just limited to compiling and minifying your JS & CSS file because you can also add preprocessors to it to process TypeScripts, support es2015, embed css into you js files and others. That’s about it for the brief rundown of Webpack. To learn more, you can visit the Webpack site.

Environment Setup & Requirements

Before proceeding make sure that these are already installed in your system:

  • Python (>= 3.0.0)
  • virtualenv
  • nodejs
  • npm (>= 5.7.0)

As always let’s first create an isolated and separated environment for this project through virtualenv. If you don’t know how to you can follow this one to setup virtualenv with Python 3. Throughout this tutorial I’ll be using Python 3 so please stick to it unless you know what you’re doing.

Let’s activate our newly created environment. Install Django and django-webpack-loader. Then create a new Django project and app:

source env/bin/activate
pip install django django-webpack-loader
django-admin.py startproject djangowebpackproject
cd djangowebpackproject
python manage.py startapp djangowebpack

Add the newly created Django app in the project’s settings.py

#djangowebpackproject/settings.py

#...

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'djangowebpack',
]

#...

We should now have a working Django project with an empty app.

To verify if the project is really working you can run the Django debug webserver and access HTTP server through your browser.

python manage.py runserver 8000

This will start an HTTP server that is only accessible from the local machine. You can also enable access from a network for your Django project using this.

Setup Webpack

Let’s add django-webpack-loader into the INSTALLED_APPS in settings.py.

#... 

INSTALLED_APPS = [ 
    'django.contrib.admin', 
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'djangowebpack',
    'webpack_loader'
] #...

While on settings.py let’s add a webpack-loader config.

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

Also if you haven’t done it yet, add the necessary setting for media and static folders:

# Make sure that BASE_DIR is already declared and initialized in your settings.py
# If it's not yet then put these 2 lines at the top of your settings.py file
# import os
# BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

PUBLIC_DIR = os.path.join(BASE_DIR, 'public')
STATIC_ROOT = os.path.join(PUBLIC_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(PUBLIC_DIR, 'media')

Inside the root directory of the Django project create a webpack.config.js file. Open up the newly created file and add this configuration as your default webpack config:

var path = require('path');
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');

module.exports = {
  context: __dirname,
  entry: './djangowebpack/static/js/index.js',
  output: {
      path: path.resolve('./djangowebpack/static/webpack_bundles/'),
      filename: "[name]-[hash].js"
  },

  plugins: [
    new BundleTracker({filename: './webpack-stats.json'})
  ]
}

First 3 lines just declares what we require for this javascript to properly start. In line 6, entry is the first JS file that will be parsed by Webpack. Any files that was imported or required will also be parsed and they will all be minified and compiled into one JS file. Line 7-10 declares the output JS file location and filename format.

Now, let’s create our first page. First we need to create our own view and assign a template to it. Then assign it with a corresponding URL in urls.py.

In your djangowebpack app’s view.py add these to create a simple view implementation with an assigned template:

#view.py

from django.views.generic import TemplateView

class HomeView(TemplateView):
    template_name = "home.html"

Then set this up in urls.py

#....
from djangowebpack.views import HomeView

urlpatterns = [
#...
    path('/', HomeView.as_view()),
#...
]

Now create the templates directory in our djangowebpack app. Path should be

djangowebpack/templates/

Inside this newly created directory create an empty text file named home.html. Open up this new template then put these inside it:

{% load render_bundle from webpack_loader %}

{% render_bundle 'main' 'js' 'DEFAULT' %}

1st line loads the webpack_loader then on the 3rd line we’re requesting for webpack_loader to render the javascript it compiled from the DEFAULT settings – which we added in the settings.py earlier. As you can see we can separate our JS and CSS files into modules that we can insert on different templates or pages by just making another webpack_loader setup in settings.py . After setting these up we should now be ready on the Django side. Now the only remaining thing we need to do is setup Webpack through npm and build our assets. Let’s first initialize npm and then install Webpack. Execute this shell commands inside the djangowebpackproject root folder.

npm init -y
npm install --save-dev webpack webpack-bundle-tracker webpack-cli

Open up the generated package.json and add “build”: “webpack” to the scripts:

{
//..........
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack" // <<<<------- NEW LINE
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
//..........

Okay, that should be it. We now have a full setup of Webpack that is integrated with Django.

First Webpack Packaged Assets

Let’s create our first packaged assets now that we have the Webpack and Django setup. First create a javscript file named index inside djangowebpack app’s static folder. Path should be [djangowebpackproject]/djangowebpack/static/js/index.js. Open up this index.js file and let’s put something inside to verify that this setup is working.

console.log("Hello, world!");

Now go back to djangowebpackproject root directory and execute this command in the shell to start Webpack and build the javascript we’ve just created.

npm run build

You should have get a response that looks like this

Hash: ea661f0ec9b946af301d
Version: webpack 4.1.0
Time: 97ms
Built at: 3/7/2018 8:56:29 PM
                       Asset       Size  Chunks             Chunk Names
main-ea661f0ec9b946af301d.js  565 bytes       0  [emitted]  main
Entrypoint main = main-ea661f0ec9b946af301d.js
   [0] ./djangowebpack/static/js/index.js 22 bytes {0} [built]

This confirms that Webpack was able to compile our index.js into main-ea661f0ec9b946af301d.js as indicated in line 6. Now start django dev server so we can check if this will be rendered on the template:

python manage.py runserver 8000

Open up your favorite browser and also open its javascript console. Then access the django dev server through localhost:8000. After the page is loaded you should see a Hello, World! text in the javascript console of your browser. This verifies that the script built by Webpack was properly referenced on our Django’s home page.

5 Comments

  1. Meenakshi

    Thank You So much!!!

  2. zafroth

    Awesome tutorial saved me a great deal of time everything worked except that
    I had to include the djangowebpack urls in djangowebpackproject urls.py:

    from django.urls import path,include
    urlpatterns = [
    path(”, include(‘djangowebpack.urls’)),
    ]

  3. zafroth

    Awesome tutorial saved me a great deal of time everything worked except that
    I had to include the djangowebpack urls in djangowebpackproject urls.py:

    from django.urls import path,include
    urlpatterns = [
    path(”, include(‘djangowebpack.urls’)),
    ]

    Not sure if it was a mistake on my part or I am using a newer version of Django.

  4. Adrian

    Great job James. Your example worked only with a js file but what if I have multiple js files? I need to create different webpack config for each one of the file?

    What I need to change to work with CSS files, I have 7 css files for different pages and app sections. I can make a base.css and @import all of them but that means I need to load it in base.html

  5. adrian

    What about dev and prod config or a CSS bundle?

Leave a Reply

Your email address will not be published.

© 2024 James Baltar

Theme by Anders NorenUp ↑