Transparently use webpack with django

Overview

django-webpack-loader

Build Status Coverage Status pyversions djversions

Read http://owaislone.org/blog/webpack-plus-reactjs-and-django/ for a detailed step by step guide on setting up webpack with django using this library.

Use webpack to generate your static bundles without django's staticfiles or opaque wrappers.

Django webpack loader consumes the output generated by webpack-bundle-tracker and lets you use the generated bundles in django.

A changelog is also available.

Compatibility

Test cases cover Django>=2.0 on Python>=3.5. 100% code coverage is the target so we can be sure everything works anytime. It should probably work on older version of django as well but the package does not ship any test cases for them.

Install

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

pip install django-webpack-loader

Migrating from version < 1.0.0

In order to use django-webpack-loader>=1.0.0, you must ensure that [email protected] is being used on the JavaScript side. It's recommended that you always keep at least minor version parity across both packages, for full compatibility.

This is necessary because the formatting of webpack-stats.json that webpack-bundle-tracker outputs has changed starting at version 1.0.0-alpha.1. Starting at django-webpack-loader==1.0.0, this is the only formatting accepted here, meaning that other versions of that package don't output compatible files anymore, thereby breaking compatibility with older webpack-bundle-tracker releases.


Configuration


Assumptions

Assuming BASE_DIR in settings refers to the root of your django app.

import sys
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

Assuming assets/ is in settings.STATICFILES_DIRS like

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

Assuming your webpack config lives at ./webpack.config.js and looks like this

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

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

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

Default Configuration

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': [r'.+\.hot-update.js', r'.+\.map'],
        'LOADER_CLASS': 'webpack_loader.loader.WebpackLoader',
    }
}

CACHE

WEBPACK_LOADER = {
    'DEFAULT': {
        'CACHE': not DEBUG
    }
}

When CACHE is set to True, webpack-loader will read the stats file only once and cache the result. This means web workers need to be restarted in order to pick up any changes made to the stats files.


BUNDLE_DIR_NAME

WEBPACK_LOADER = {
    'DEFAULT': {
        'BUNDLE_DIR_NAME': 'bundles/' # end with slash
    }
}

BUNDLE_DIR_NAME refers to the dir in which webpack outputs the bundles. It should not be the full path. If ./assets is one of your static dirs and webpack generates the bundles in ./assets/output/bundles/, then BUNDLE_DIR_NAME should be output/bundles/.

If the bundle generates a file called main-cf4b5fab6e00a404e0c7.js and your STATIC_URL is /static/, then the <script> tag will look like this

<script src="/static/output/bundles/main-cf4b5fab6e00a404e0c7.js"/>

NOTE: If your webpack config outputs the bundles at the root of your staticfiles dir, then BUNDLE_DIR_NAME should be an empty string '', not '/'.


STATS_FILE

WEBPACK_LOADER = {
    'DEFAULT': {
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json')
    }
}

STATS_FILE is the filesystem path to the file generated by webpack-bundle-tracker plugin. If you initialize webpack-bundle-tracker plugin like this

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

and your webpack config is located at /home/src/webpack.config.js, then the value of STATS_FILE should be /home/src/webpack-stats.json


IGNORE

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.


POLL_INTERVAL

POLL_INTERVAL is the number of seconds webpack_loader should wait between polling the stats file. The stats file is polled every 100 milliseconds by default and any requests to are blocked while webpack compiles the bundles. You can reduce this if your bundles take shorter to compile.

NOTE: Stats file is not polled when in production (DEBUG=False).


TIMEOUT

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.


LOADER_CLASS

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.loader.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:

# in app.module
import requests
from webpack_loader.loader import WebpackLoader

class ExternalWebpackLoader(WebpackLoader):

  def load_assets(self):
    url = self.config['STATS_URL']
    return requests.get(url).json()


# in app.settings
WEBPACK_LOADER = {
  'DEFAULT': {
      'CACHE': False,
      'BUNDLE_DIR_NAME': 'bundles/',
      'LOADER_CLASS': 'app.module.ExternalWebpackLoader',
      # Custom config setting made available in WebpackLoader's self.config
      'STATS_URL': 'https://www.test.com/path/to/stats/',
  }
}

Usage


Manually run webpack to build assets.

One of the core principles of django-webpack-loader is to not manage webpack itself in order to give you the flexibility to run webpack the way you want. If you are new to webpack, check one of the examples, read my detailed blog post or check webpack docs.

Settings

Add webpack_loader to INSTALLED_APPS

INSTALLED_APPS = (
    ...
    'webpack_loader',
)

Templates

{% load render_bundle from webpack_loader %}

{% render_bundle 'main' %}

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

render_bundle also takes a second argument which can be a file extension to match. This is useful when you want to render different types for files in separately. For example, to render CSS in head and JS at bottom we can do something like this,

{% load render_bundle from webpack_loader %}

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

Preload

The is_preload=True option in the render_bundle template tag can be used to add rel="preload" link tags.

{% load render_bundle from webpack_loader %}

<html>
  <head>
    {% render_bundle 'main' 'css' is_preload=True %}
    {% render_bundle 'main' 'js' is_preload=True %}

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

  <body>
    {% render_bundle 'main' 'js' %}
  </body>
</html>

Appending file extensions

The suffix option can be used to append a string at the end of the file URL. For instance, it can be used if your webpack configuration emits compressed .gz files.

qwe

{% load render_bundle from webpack_loader %}

<html>
  <head>
    <meta charset="UTF-8">
    <title>Example</title>
    {% render_bundle 'main' 'css' %}
  </head>

  <body>
    {% render_bundle 'main' 'js' suffix='.gz' %}
  </body>
</html>

Multiple webpack projects

Version 2.0 and up of webpack loader also supports multiple webpack configurations. The following configuration defines 2 webpack stats files in settings and uses the config argument in the template tags to influence which stats file to load the bundles from.

WEBPACK_LOADER = {
    'DEFAULT': {
        'BUNDLE_DIR_NAME': 'bundles/',
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
    },
    'DASHBOARD': {
        'BUNDLE_DIR_NAME': 'dashboard_bundles/',
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats-dashboard.json'),
    }
}
{% load render_bundle from webpack_loader %}

<html>
  <body>
    ....
    {% render_bundle 'main' 'js' 'DEFAULT' %}
    {% render_bundle 'main' 'js' 'DASHBOARD' %}

    <!-- or render all files from a bundle -->
    {% render_bundle 'main' config='DASHBOARD' %}

    <!-- the following tags do the same thing -->
    {% render_bundle 'main' 'css' 'DASHBOARD' %}
    {% render_bundle 'main' extension='css' config='DASHBOARD' %}
    {% render_bundle 'main' config='DASHBOARD' extension='css' %}

    <!-- add some extra attributes to the tag -->
    {% render_bundle 'main' 'js' 'DEFAULT' attrs='async charset="UTF-8"'%}
  </body>
</head>

File URLs instead of html tags

If you need the URL to an asset without the HTML tags, the get_files template tag can be used. A common use case is specifying the URL to a custom css file for a Javascript plugin.

get_files works exactly like render_bundle except it returns a list of matching files and lets you assign the list to a custom template variable. For example,

{% get_files 'editor' 'css' as editor_css_files %}
CKEDITOR.config.contentsCss = '{{ editor_css_files.0.publicPath }}';

<!-- or list down name, path and download url for every file -->
<ul>
{% for css_file in editor_css_files %}
    <li>{{ css_file.name }} : {{ css_file.path }} : {{ css_file.publicPath }}</li>
{% endfor %}
</ul>

Refer other static assets

webpack_static template tag provides facilities to load static assets managed by webpack in django templates. It is like django's built in static tag but for webpack assets instead.

In the below example, logo.png can be any static asset shipped with any npm package.

{% load webpack_static from webpack_loader %}

<!-- render full public path of logo.png -->
<img src="{% webpack_static 'logo.png' %}"/>

The public path is based on webpack.config.js output.publicPath.


From Python code

If you want to access the webpack asset path information from your application code then you can use the function in the webpack_loader.utils module.

>>> utils.get_files('main')
[{'url': '/static/bundles/main.js', u'path': u'/home/mike/root/projects/django-webpack-loader/tests/assets/bundles/main.js', u'name': u'main.js'},
 {'url': '/static/bundles/styles.css', u'path': u'/home/mike/root/projects/django-webpack-loader/tests/assets/bundles/styles.css', u'name': u'styles.css'}]
>>> utils.get_as_tags('main')
['<script src="/static/bundles/main.js" ></script>',
 '<link href="/static/bundles/styles.css" rel="stylesheet" />']

How to use in Production

It is up to you. There are a few ways to handle this. I like to have slightly separate configs for production and local. I tell git to ignore my local stats + bundle file but track the ones for production. Before pushing out newer version to production, I generate a new bundle using production config and commit the new stats file and bundle. I store the stats file and bundles in a directory that is added to the STATICFILES_DIR. This gives me integration with collectstatic for free. The generated bundles are automatically collected to the target directory and synched to S3.

./webpack_production.config.js

var config = require('./webpack.config.js');
var BundleTracker = require('webpack-bundle-tracker');

config.output.path = require('path').resolve('./assets/dist');

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

// override any other settings here like using Uglify or other things that make sense for production environments.

module.exports = config;

settings.py

if not DEBUG:
    WEBPACK_LOADER.update({
        'BUNDLE_DIR_NAME': 'dist/',
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats-prod.json')
    })



You can also simply generate the bundles on the server before running collectstatic if that works for you.

Extra

Jinja2 Configuration

If you need to output your assets in a jinja template we provide a Jinja2 extension that's compatible with the Django Jinja module and Django 1.8.

To install the extension add it to the django_jinja TEMPLATES configuration in the ["OPTIONS"]["extension"] list.

from django_jinja.builtins import DEFAULT_EXTENSIONS
TEMPLATES = [
    {
        "BACKEND": "django_jinja.backend.Jinja2",
        "OPTIONS": {
            "extensions": DEFAULT_EXTENSIONS + [
                "webpack_loader.contrib.jinja2ext.WebpackExtension",
            ],
        }
    }
]

Then in your base jinja template:

{{ render_bundle('main') }}


Enjoy your webpack with django :)

Alternatives to Django-Webpack-Loader

Below are known projects that attempt to solve the same problem:

Note that these projects have not been vetted or reviewed in any way by me. These are not recommendation. Anyone can add their project to this by sending a PR.

Comments
  • render_entrypoint tag

    render_entrypoint tag

    render_entrypoint tag renders all chunks related to an entrypoint. This allows us to make use of Webpack 4 code splitting functionality.

    The corresponding PR for webpack-bundle-tracker (necessary for this feature to work) can be found here

    opened by alihazemfarouk 27
  • Code Splitting

    Code Splitting

    When bundles get large, which happen fairly easily with the inclusion of React, Redux, Component libraries etc.

    The next step to reduce the file size is code splitting based on routes.

    Here is an example:

    https://reactjs.org/docs/code-splitting.html

    Can this be supported by Django Webpack Loader?

    opened by viperfx 21
  • WebpackLoaderBadStatsError during bundling

    WebpackLoaderBadStatsError during bundling

    I'm trying to bundling my asset files in production server. Everything works fine except that during building the bundle which takes about 20 seconds, anyone trying to visit the site will get 500 error. The error is as follows as far as it is concerned with webpack_loader:

    File ".../lib/python3.5/site-packages/webpack_loader/contrib/jinja2ext.py" in 9. environment.globals["render_bundle"] = lambda *a, **k: jinja2.Markup(render_bundle(*a, **k))

    File ".../lib/python3.5/site-packages/webpack_loader/templatetags/webpack_loader.py" in render_bundle 40. return render_as_tags(_get_bundle(bundle_name, extension, config), attrs)

    File ".../lib/python3.5/site-packages/webpack_loader/templatetags/webpack_loader.py" in _get_bundle 32. bundle = get_loader(config).get_bundle(bundle_name)

    File ".../lib/python3.5/site-packages/webpack_loader/loader.py" in get_bundle 97. "The stats file does not contain valid data. Make sure "

    I should mention that in production settings, I already have set webpack loader cache to True: WEBPACK_LOADER['DEFAULT']['CACHE'] = True

    opened by mehdipourfar 17
  • Add custom LOADER_CLASS support

    Add custom LOADER_CLASS support

    This project has been a huge value add for us, and I'd like to help address some of the issues around adding custom loader class support. It sounds like the approach outlined in #83 gives the most flexibility for extending the loader. #202 looks like it's pretty close to that implementation, but given that it's been almost three months since opening (without any edits), and the change is relatively small, I'd like to open a new PR in hopes of getting these changes upstream.

    Changes: LOADER_CLASS on the WEBPACK_CONFIG setting is now where the loader class is defined. To retain backward compatibility and to keep getting started simple, this defaults to the existing WebpackLoader class.

    WebpackLoader._load_assets has been renamed to WebpackLoader.load_assets. This keeps the API extendable when creating custom webpack loaders

    Documentation has been updated to include how to extend the WebpackLoader using the loader class.

    Tests have also been added.

    I'm happy to implement any feedback or discuss the design choices! I have the bandwidth.

    opened by rhyneav 14
  • Improve error message when template is rendered without request context

    Improve error message when template is rendered without request context

    Django provides the ability to render templates outside the request context even if the django.template.context_processors.request middleware is activated (see Template.render or render_to_string).

    So it took me a bit to figure out the cause of the following error happened after updating from 1.3.0 to 1.4.0 (see https://github.com/Integreat/integreat-cms/pull/956):

    Traceback
    Traceback (most recent call last):
      File "/home/circleci/project/src/cms/tests/views/view_test_utils.py", line 25, in test_function
        response = self.client.get(url)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/test/client.py", line 742, in get
        response = super().get(path, data=data, secure=secure, **extra)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/test/client.py", line 398, in get
        **extra,
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/test/client.py", line 473, in generic
        return self.request(**r)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/test/client.py", line 714, in request
        response = self.handler(environ)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/test/client.py", line 145, in __call__
        response = self.get_response(request)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 130, in get_response
        response = self._middleware_chain(request)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 49, in inner
        response = response_for_exception(request, exc)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 114, in response_for_exception
        response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 153, in handle_uncaught_exception
        return callback(request)
      File "/home/circleci/project/src/cms/views/error_handler/error_handler.py", line 112, in handler500
        return HttpResponseServerError(render_error_template(context))
      File "/home/circleci/project/src/cms/views/error_handler/error_handler.py", line 25, in render_error_template
        return render_to_string("error_handler/http_error.html", context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/loader.py", line 62, in render_to_string
        return template.render(context, request)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
        return self.template.render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/base.py", line 170, in render
        return self._render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/test/utils.py", line 100, in instrumented_test_render
        return self.nodelist.render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/base.py", line 938, in render
        bit = node.render_annotated(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
        return self.render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
        return compiled_parent._render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/test/utils.py", line 100, in instrumented_test_render
        return self.nodelist.render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/base.py", line 938, in render
        bit = node.render_annotated(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
        return self.render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
        return compiled_parent._render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/test/utils.py", line 100, in instrumented_test_render
        return self.nodelist.render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/base.py", line 938, in render
        bit = node.render_annotated(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
        return self.render(context)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/library.py", line 192, in render
        output = self.func(*resolved_args, **resolved_kwargs)
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/webpack_loader/templatetags/webpack_loader.py", line 39, in render_bundle
        if not hasattr(context['request'], '_webpack_loader_used_tags'):
      File "/home/circleci/project/.venv/lib/python3.7/site-packages/django/template/context.py", line 83, in __getitem__
        raise KeyError(key)
    KeyError: 'request'
    

    Source: https://app.circleci.com/pipelines/github/Integreat/integreat-cms/2610/workflows/c4feb10f-3d0d-48b8-b094-681db5a6d8d0/jobs/19913

    I would suggest to throw a more helpful error in this case, stating that it's not possible to use Template.render without passing the current request to the template context. (Or, if somehow possible, allow the rendering without the request object...) Thanks!

    opened by timoludwig 13
  • Added support for assets

    Added support for assets

    Assets may be accessible on the tag get_asset, therefore, anything that goes in webpack in exported-assets.js may be accessible here, by the same url linked into the js file retrieving the public_path of the file

    opened by EmilLuta 13
  • Multiple entrypoints on the same page causes chunks to be sourced multiple times

    Multiple entrypoints on the same page causes chunks to be sourced multiple times

    Description When using multiple bundles on the same page, shared dependencies are included more than once. For example, when using a "global" bundle and a specific app on the same page, shared chunks between them are sourced multiple times. This is especially problematic when global libraries like bootstrap are in those shared chunks.

    Expected When rendering a template or set of templates (extension), shared chunks are sourced only once

    Actual Shared chunks are included on the rendered page more than once, breaking libraries that rely on only having one instance.

    Basic example Given 2 bundles global and pageapp and shared chunk chunk...

    {% load render_bundle from webpack_loader %}
    {% render_bundle 'global' 'js' %}
    {% render_bundle 'pageapp' 'js' %}
    

    output currently is

    <script type="text/javascript" src="http://localhost:8001/chunk.js"></script>
    <script type="text/javascript" src="http://localhost:8001/global.js"></script>
    <script type="text/javascript" src="http://localhost:8001/chunk.js"></script>
    <script type="text/javascript" src="http://localhost:8001/pageapp.js"></script>
    
    opened by EthanZeigler 12
  • Entrypoint-based loading

    Entrypoint-based loading

    In my fork of django-webpack-loader, there is a bit of added functionality, cleaned up code, etc. Primarily, the new webpack versions are supported and the concept of entrypoint-based resource management.

    I maintain the PyPi package django-webpack5-loader.

    Purpose of this Fork

    This package aims not only to support webpack 4 and 5, introduce additional loading of entrypoints in templates, but also adds a framework for structuring django projects into pages using webpack_loader.contrib.pages. See below.

    The initial webpack 4 port was made possible thanks to

    • Svetoslav Dekov
    • Ali Farouk
    • Nikolaus Piccolotto

    apart from the original package author Owais Lone.

    under-review 
    opened by MrP01 12
  • Using Webpack splitChunks and cacheGroups

    Using Webpack splitChunks and cacheGroups

    Hi, is it possible to use splitChunks and cacheGroups while having "name: false"?

    Currently I have the following webpack configuration: entry: { Homepage: './react/Homepage', vendors: ['react'], }, optimization: { splitChunks: { name: false, cacheGroups: { commons: { name: 'vendors', chunks: 'all', test: /[\\/]node_modules[\\/]/, priority: -10, }, }, }, }

    This creates a specific chunk file called "vendors" in addition to all other chunk files that are defined as entry points ("Homepage" in this example).

    Now in order to display the entry point Homepage, i have to include both bundles via template tags into the html file: {% render_bundle 'vendors' %} {% render_bundle 'Homepage' %}

    This behaviour is quite useful, as the vendors file can be cached and so when other pages are loaded, the vendors file does not have to be downloaded again.

    Now my problem: Webpack 4 recommends using "name: false" to optimise the loading and caching of resources across multiple entry points. By doing this, the "vendors" file can be split into multiple smaller files, and then the entry point configuration changes from:

    Entrypoint Homepage = vendors-4f65a9a5a66defc0a60b.js Homepage-4f65a9a5a66defc0a60b.js

    to

    Entrypoint Homepage = 0-77b58caa5e7acecf0a4e.js 1-77b58caa5e7acecf0a4e.js Homepage-77b58caa5e7acecf0a4e.js

    So now instead of loading the huge vendors file with the first load, the user only has to load 2 smaller files.

    But now I cannot use the 0-hash and 1-hash files in the webpack-bundle-loader, as {% render_bundle '0' %} etc. cannot find these chunks (they don't have chunk names in the webpack compile summary). Additionally, the names (0, 1, etc) would change every time new dependencies get added.

    Is there a way to render complete entry points together with all their chunks? I would assume {% render_bundle 'Homepage' %} would look up the entry point 'Homepage' instead of the chunkname and then render all required chunks based on that.

    Any suggestions? Or am I missing something?

    opened by SchubmannM 12
  • Can not get it running properly

    Can not get it running properly

    I spend a lot of time on setting it up (following amongst others your post here): http://owaislone.org/blog/webpack-plus-reactjs-and-django/ , tackling several minor issues:

    • looks like babel-core needs to be installed as well otherwise I get errormessages
    • this issue: https://github.com/owais/django-webpack-loader/issues/22

    Still it is not working 'as expected'. Part of the problem is I do not exactly know what to expect. The purposes of separating Django world from JS (webpack) world seems sensible to me. But the exact separation is not clear and not working for me. My background is mainly the Django world in which I could get JS and CSS working from a staticfolder. I am not -until recently- very familiar with the npm, webpack, js world of things and I do have a couple of questions that when answered might shed some light on the problems I'm having:

    1. I read in one of the closed issues that Django-webpack-loader solution is aimed at .js and .css ; So not images and other static items. Is that correct y/n? If yes, how should you treat 'other items': the Django way, or the JS way (or choose?). Does it makes sense to just 'build a bridge' for js and css ?
    2. Following the article it says "If you left webpack running in watch mode, it should automatically pick up the changes and compile a new bundle." I tried a simple Django project to make things more clear for myself, but automatic rebuilding is not happening... It just compiles the same bundle once (no new hash), no error... nothing new.
    3. I did manage to have webpack build script run and then have new bundles compiled (when I imported new js libraries), so that seems to work fine; also the bundle-tracker gets new correct hash, so that seems fine. However, I tried to incorporate the js and css into a page, it does not work I think. Part of the problem is I do not know if I test correctly. Your article gives the setup/framework but no real proof of working js or css as far as I can see. In my setup for sure I only see html layout so the css is not coming through from the bundle...
    4. I do not know exactly how the css should work. It seems that it should be included into the main-hash.js bundle and is import into html from that bundle... Is that correct? Could there be a detailed example of how to go about. For example I would like to use bootstrap which consists of bootstrap.js and bootstrap.css; Do I import both from the index.js and then they will be included in the bundle and then using the {% load render_bundle from webpack_loader %} {% render_bundle 'main' %} ? An example with bootstrap and/ or materialcss would be very helpful. Also when I have a custom.css, how do I include it?
    5. I do not really need the react part; I assume that is not a dealbreaker and using django-webpack-loader still makes sense?!
    6. After you made a bundle with webpack and want to go live, do you include the bundle in a 'normal Django static folder'? It seems to be explained somewhere but it is still not really clear to me.

    Here is my config:

    //Webpack.config.js

    var path = require('path');
    var webpack = require('webpack');
    var BundleTracker = require('webpack-bundle-tracker');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var Clean = require('clean-webpack-plugin');
    var bootstrapPath = path.join(__dirname, 'node_modules/bootstrap/dist/css');
    var sourcePath = path.join(__dirname, 'assets');
    
    module.exports = {
        devtool: 'eval-source-map',
        context: __dirname,
        entry: './assets/js/index', // entry point of our app. .assets/js/index.js should require other js modules and dependencies it needs
        output: {
            path: path.resolve('./assets/bundles/'),
            filename: '[name]-[hash].js'
        },
        node: {
            console: true,
            fs: 'empty'
        },
        plugins: [
            new webpack.ProvidePlugin({
                $: 'jquery',
                jQuery: 'jquery'
            }),
            new BundleTracker({filename: './webpack-stats.json'}),
            new webpack.BannerPlugin('Banner!!!! todo'),
            new HtmlWebpackPlugin({
                template: __dirname + '/assets/index.tmpl.html'
            }),
            new webpack.HotModuleReplacementPlugin(),
            new Clean(['assets/bundles'])
        ],
        module: {
            loaders: [
                {
                    test: /\.js[x]?$/,
                    loader: 'babel',
                    exclude: /(node_modules|bower-components)/,
                    query: {
                        presets: ['es2015', 'stage-0']
                    }
                },
                {
                    test: /\.json$/,
                    loader: 'json-loader'
                },
                {
                    test: /\.js$/,
                    include: path.resolve(__dirname, 'node_modules/mapbox-gl/js/render/shaders.js'),
                    loader: 'transform/cacheable?brfs'
                },
                {
                    test: /\.js$/,
                    include: path.resolve(__dirname, 'node_modules/webworkify/index.js'),
                    loader: 'worker'
                },
                {
                    test: /\.css$/,
                    loader: 'style!css?modules!postcss'
                },
                {
                    test: /\.scss$/,
                    loaders: ['style', 'css?sourceMap', 'sass?sourceMap']
                },
                {test: /\.woff(\?v=\d+\.\d+\.\d+)?2?$/, loader: 'url-loader'},
                {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader'},
                {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader'},
                {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader'}
            ]
        },
        postcss: [
            require('autoprefixer')
        ],
        resolve: {
            modulesDirectories: ['node_modules', 'bower_components', bootstrapPath, sourcePath],
            extensions: ['', '.js', '.jsx', '.css'],
            alias: {
                webworkify: 'webworkify-webpack',
                '$': 'jquery',
                'jQuery': 'jquery'
            }
        },
        devServer: {
            contentBase: './assets',
            colors: true,
            historyApiFallback: true,
            inline: true,
            hot: true
        }
    };
    
    
    
    
    

    //index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Webpack Sample Project</title>
    </head>
    <body>
    <div id='root'>
    </div>
    <script src="main-4809d8e09cbc474f2d6a.js"></script></body>
    </html>
    
    
    
    

    //assets/js/index.js

    import '../star-rating';
    import '../../node_modules/turf/turf';
    import '../ie10-viewport-bug-workaround';
    import '../../node_modules/jquery/src/jquery.js';
    //import '../../node_modules/materialize-css/dist/js/materialize.js';
    //import '../../node_modules/materialize-css/dist/css/materialize.css';
    //import '../../node_modules/materialize-css/js/init.js';
    import '../../node_modules/bootstrap/dist/js/bootstrap.js';
    import '../../node_modules/bootstrap/dist/css/bootstrap.min.css';
    import '../css/custom';
    
    
    

    //head_css.html

    {% load staticfiles %}
    
    {% load render_bundle from webpack_loader %}
    
    {% render_bundle 'main' %}
    
    <link href="{% static 'css/font-awesome.min.css' %}" rel="stylesheet">
    
    <!--Import materialize.css-->
    {#<link type="text/css" rel="stylesheet" href="css/materialize.min.css" media="screen,projection"/>#}
    
    {#<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">#}
    {#<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">#}
    <!-- Custom styles for this template -->
    {#<link href="{% static 'css/navbar-static-top.css' %}" rel="stylesheet">#}
    {#    <link href="{% static 'css/star-rating.min.css'%}" media="all" rel="stylesheet" type="text/css">#}
    {#<link href="{% static 'css/star-rating.css' %}" media="all" rel="stylesheet" type="text/css">#}
    {#<link href="{% static 'css/custom.css' %}" rel="stylesheet">#}
    
    
    
    

    //settings/common.py

    
    
    # -*- coding: utf-8 -*-
    """
    Django settings for myapp project.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/dev/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/dev/ref/settings/
    """
    # from __future__ import absolute_import, unicode_literals   # python 3 toch?
    import environ  # in baserequirements as django-environ
    
    ROOT_DIR = environ.Path(__file__) - 3  # (/a/b/myfile.py - 3 = /)
    APPS_DIR = ROOT_DIR.path('myapp')
    
    env = environ.Env()
    environ.Env.read_env()
    
    # WEBPACK LOADER CONFIG
    WEBPACK_LOADER = {
        'DEFAULT': {
            'BUNDLE_DIR_NAME': 'bundles/',
            'STATS_FILE': str(ROOT_DIR.path('webpack-stats.json'))
        }
    }
    
    # print(WEBPACK_LOADER['STATS_FILE'])
    
    # APP CONFIGURATION
    # ------------------------------------------------------------------------------
    DJANGO_APPS = (
        # Default Django apps:
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    
        # category: Admin apps
        'flat',
        'django.contrib.admin',
    )
    
    THIRD_PARTY_APPS = (
        'crispy_forms',  # Form layouts
        'allauth',  # registration
        'allauth.account',  # registration
        'allauth.socialaccount',  # registration
    
        'webpack_loader',  # Django-webpack-loader
    
        'localflavor'
    )
    
    # Apps specific for this project go here.
    LOCAL_APPS = (
        'myapp.users',  # custom users app
        # Your stuff: custom apps go here
        'newsletter',
        'jobs',
        'likes',
        'matches',
        'profiles',
        'questions',
    )
    
    
    # See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
    INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS + ALLAUTH_PROVIDER_APPS
    
    # MIDDLEWARE CONFIGURATION
    # ------------------------------------------------------------------------------
    MIDDLEWARE_CLASSES = (
        # Make sure djangosecure.middleware.SecurityMiddleware is listed first
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    )
    
    # MIGRATIONS CONFIGURATION
    # ------------------------------------------------------------------------------
    MIGRATION_MODULES = {
        'sites': 'myapp.contrib.sites.migrations'
    }
    
    # DEBUG
    # ------------------------------------------------------------------------------
    # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
    DEBUG = env.bool("DJANGO_DEBUG", False)
    
    # FIXTURE CONFIGURATION
    # ------------------------------------------------------------------------------
    # See: https://docs.djangoproject.com/en/dev/ref/settings/
    # std:setting-FIXTURE_DIRS
    FIXTURE_DIRS = (
        str(APPS_DIR.path('fixtures')),
    )
    
    
    # TEMPLATE CONFIGURATION
    # ------------------------------------------------------------------------------
    # See: https://docs.djangoproject.com/en/dev/ref/settings/#templates
    TEMPLATES = [
        {
            # See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
            'DIRS': [
                str(APPS_DIR.path('templates')),
            ],
            'OPTIONS': {
                # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
                'debug': DEBUG,
                # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
                # https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types
                'loaders': [
                    'django.template.loaders.filesystem.Loader',
                    'django.template.loaders.app_directories.Loader',
                ],
                # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.template.context_processors.i18n',
                    'django.template.context_processors.media',
                    'django.template.context_processors.static',
                    'django.template.context_processors.tz',
                    'django.contrib.messages.context_processors.messages',
                    # Your stuff: custom template context processors go here
                ],
            },
        },
    ]
    
    # See: http://django-crispy-forms.readthedocs.org/en/latest/install.html#template-packs
    CRISPY_TEMPLATE_PACK = 'bootstrap3'
    
    # STATIC FILE CONFIGURATION
    # ------------------------------------------------------------------------------
    # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
    # Dit is waar uiteindelijk de staticfiles 'echt heen gaan' op de server (dmv collectstatic).
    STATIC_ROOT = str(ROOT_DIR.path('staticfiles'))
    
    # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
    # This is the URL reference:
    STATIC_URL = '/static/'
    
    # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
    # Dit zijn de staticfiles 'als onderdeel van je project development'; collectstatic copieert van
    # STATICFILES_DIRS naar STATIC_ROOT !!
    STATICFILES_DIRS = (
        str(APPS_DIR.path('static')),
        '/home/usr/myapp/assets/bundles')
    
    # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
    STATICFILES_FINDERS = (
        'django.contrib.staticfiles.finders.FileSystemFinder',
        'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    )
    
    # MEDIA CONFIGURATION
    # ------------------------------------------------------------------------------
    # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
    MEDIA_ROOT = str(APPS_DIR('media'))
    
    # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
    MEDIA_URL = '/media/'
    
    # URL Configuration
    # ------------------------------------------------------------------------------
    ROOT_URLCONF = 'config.urls'
    
    
    
    
    
    
    
    
    
    opened by musicformellons 12
  • Implement Jazzband guidelines for django-webpack-loader

    Implement Jazzband guidelines for django-webpack-loader

    This issue tracks the implementation of the Jazzband guidelines for the project django-webpack-loader

    It was initiated by @owais who was automatically assigned in addition to the Jazzband roadies.

    See the TODO list below for the generally required tasks, but feel free to update it in case the project requires it.

    Feel free to ping a Jazzband roadie if you have any question.

    TODOs

    • [x] Fix all links in the docs (and README file etc) from old to new repo #251
    • [x] Add the Jazzband badge to the README file #251
    • [x] Add the Jazzband contributing guideline to the CONTRIBUTING.md or CONTRIBUTING.rst file #251
    • [x] Check if continuous testing works (e.g. Travis CI, CircleCI, AppVeyor, etc) #251
    • [x] Check if test coverage services work (e.g. Coveralls, Codecov, etc)
    • [x] Add jazzband account to PyPI project as maintainer role (e.g. URL: https://pypi.org/manage/project/django-webpack-loader/collaboration/) #251
    • [x] Create Read the Docs project #251
    • [x] Add jazzband-bot as maintainer to the Read the Docs project (e.g. URL: https://readthedocs.org/dashboard/django-webpack-loader/users/) #251
    • [ ] Add incoming GitHub webhook integration to Read the Docs project (e.g. URL: https://readthedocs.org/dashboard/django-webpack-loader/integrations/)
    • [x] Fix project URL in GitHub project description #251
    • [ ] Review project if other services are used and port them to Jazzband
    • [ ] Port to Travis-CI or GitHub actions from Circle CI.
    • [ ] Decide who is project lead for the project (if at all)
    • [ ] Set up CI for Jazzband project releases if needed and open ticket if yes

    Project details

    Description Transparently use webpack with django
    Homepage
    Stargazers 2171
    Open issues 79
    Forks 292
    Default branch master
    Is a fork False
    Has Wiki True
    Has Pages False
    opened by jazzband-bot 11
  • Generated path in HTML not getting updated

    Generated path in HTML not getting updated

    Hi everyone, I installed your incredible package today, but I'm facing an issue.

    I modified the base package.config.json in order to change the output dir and replace "webpack_bundles" by builds :

    // /webpack.config.js
    // ... imports are there
    module.exports = {
     context: __dirname,
     entry: './static/app',
     output: {
       // I mainly changed this line
       path: path.resolve('./static/builds/'),
       filename: "[name]-[hash].js"
     },
     plugins: [
       new BundleTracker({filename: './webpack-stats.json'})
     ],
    }
    

    It seems this change is correctly applied when building my output assets, the path seems correct. /webpack-stats.json

    {
      "status": "done",
      "assets": {
        "main-b0a9e492033007ae27eb.js": {
          "name": "main-b0a9e492033007ae27eb.js",
          "path": "/app/static/builds/main-b0a9e492033007ae27eb.js"
        }
      },
      "chunks": {
        "main": [
          "main-b0a9e492033007ae27eb.js"
        ]
      }
    }
    

    My settings in Django are the default one provided by your tutoriel. In my case DEBUG=1 so CACHE=0 :

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

    And in my HTML template I import the following inside my tag :

    {% load render_bundle from webpack_loader %}
    {% render_bundle 'main' %}
    

    Then I build by asset by running the following command :

    npx webpack --mode=development --config webpack.config.js
    

    Bug when I run the page, I still have an old path for the script tag, resulting in a 404 error :

    <script src="/static/webpack_bundles/main-b0a9e492033007ae27eb.js" ></script>
    

    Am I missing something ? Shouldn't it be using the new path with the builds dir ?

    I tried to restart the Django server, I also cleared the __pycache__ folders of all my apps. Nothing changes.

    Is it a bug or a misunderstanding from me ?

    Thanks a lot

    opened by petegore 0
  • An proposal for a  better `webpack_static`

    An proposal for a better `webpack_static`

    It would be really helpful if webpack_static had a twin which had the ability to take a static file then perform the same magic that happens by default with render_bundle.

    For example:

    {% render_bundle "js/myBundle.js %}
    

    outputs

    <script src="https://localhost.dev/static/myBundle.22e6caaab91a7c8e5758.js" integrity="sha256-dwhlwjqtPE+IiaX9FOmAAaMA0d+CqSq2kiQ7OcFm1aM=" ></script>
    

    but an "unbundled" static file

    {% webpack_static "js/myAsset.js" %}
    

    outputs

    /static/myAsset.js
    

    Could there be a middle ground called asset_bundle where running

    {% asset_bundle "js/myAsset.js" %}
    

    would output

    <script src="https://localhost.dev/static/myAsset.22e6caaab91a7c8e5758.js" integrity="sha256-dwhlwjqtPE+IiaX9FOmAAaMA0d+CqSq2kiQ7OcFm1aM=" ></script>
    

    Pretty please 🙏

    opened by culshaw 1
  • Document better publicPath need for code splitting

    Document better publicPath need for code splitting

    We need to document better that publicPath should be used when using code splitting. Right now this is only documented as a comment in the code splitting example. We need to explain that setting publicPath to STATIC_URL is needed because that's the only case where webpack needs to know about STATIC_URL.

    When people need to integrate publicPath with the S3 assets path when using Django for collectstatic, they get confused by that: https://github.com/django-webpack/django-webpack-loader/issues/287

    opened by fjsj 0
  • Fix CircleCI for non-maintainers PRs or migrate to GH Actions

    Fix CircleCI for non-maintainers PRs or migrate to GH Actions

    https://app.circleci.com/pipelines/github/django-webpack/django-webpack-loader?branch=pull%2F290 https://circleci.com/developer/orbs/orb/coveralls/coveralls https://discuss.circleci.com/t/circleci-2-1-config-overview/26057

    opened by fjsj 0
  • WebpackBundleLookupError in version 1.0.0 when files outside of entry points change

    WebpackBundleLookupError in version 1.0.0 when files outside of entry points change

    I've recently upgraded to version 1.0.0 of django_webpack_loader and webpack-bundle-tracker.

    I have a project set up something like:

    - frontend/
      - webpack.config.js
      - assets/
      - cypress/
    

    The config includes:

    entry: {
      index: ['./assets/js/index.jsx'],
    },
    

    When I edit files in the cypress directory, while running webpack-dev-server, no rebuild is triggered since the files aren't within the index entry point, but a new stats JSON is generated, and django_webpack_loader blows up with: WebpackBundleLookupError: Cannot resolve bundle index

    Python error looks like this:

    Screen Shot 2021-05-17 at 11 20 36 am

    Do I need to change my configuration to somehow avoid new stats files getting generated when I edit files in frontend/cypress, or is this a bug? I couldn't find any exclude or ignore options in webpack-bundle-tracker. Didn't seem to be an issue with previous versions of these packages.

    opened by DrMeers 9
Releases(1.8.0)
  • 1.8.0(Dec 9, 2022)

  • 1.7.0(Nov 14, 2022)

  • 1.6.0(Jun 20, 2022)

  • 1.5.0(Apr 6, 2022)

    What's Changed

    • Use assertNotEqual instead of assertNotEquals for Python 3.11 compatibility. by @tirkarthi in https://github.com/django-webpack/django-webpack-loader/pull/302
    • Readme revamp by @rvlb in https://github.com/django-webpack/django-webpack-loader/pull/298
    • Fix small typo in README.md by @amy-mac in https://github.com/django-webpack/django-webpack-loader/pull/303
    • Use r-prefixed strings in IGNORE by @fjsj in https://github.com/django-webpack/django-webpack-loader/pull/306
    • Fix get_files on readme by @rvlb in https://github.com/django-webpack/django-webpack-loader/pull/311
    • Bump django from 3.2.7 to 3.2.12 by @dependabot in https://github.com/django-webpack/django-webpack-loader/pull/314
    • Added support for Subresource Integrity by @thejoeejoee in https://github.com/django-webpack/django-webpack-loader/pull/315

    New Contributors

    • @tirkarthi made their first contribution in https://github.com/django-webpack/django-webpack-loader/pull/302
    • @amy-mac made their first contribution in https://github.com/django-webpack/django-webpack-loader/pull/303
    • @fjsj made their first contribution in https://github.com/django-webpack/django-webpack-loader/pull/306
    • @thejoeejoee made their first contribution in https://github.com/django-webpack/django-webpack-loader/pull/315

    Full Changelog: https://github.com/django-webpack/django-webpack-loader/compare/1.4.1...1.5.0

    Source code(tar.gz)
    Source code(zip)
  • 1.4.1(Oct 4, 2021)

  • 1.4.0(Sep 24, 2021)

  • 1.3.0(Aug 30, 2021)

    • Add option for rel="preload" in JS/CSS tags #203
    • Add option for extension appending in the url files #135
    • Fixes RemovedInDjango41Warning #290
    • Applies IGNORE setting before checking assets #286
    • Removed type from link and script tags per #152

    NOTE: Skipped version 1.2.0 to match webpack-bundle-tracker version

    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Jul 14, 2021)

  • 1.0.0(May 12, 2021)

  • 0.7.0(Feb 24, 2020)

  • 0.3.2(Jul 24, 2016)

  • 0.3.0(Feb 21, 2016)

    New class based loader implementation

    • Potentially Breaking Changes

      This release introduces a new CACHE setting which when set to true makes the loader cache the contents of the stats files in memory. This means if set to True, the server will have to be restarted every time the stats file contents change or it'll keep serving old, cached URLs. CACHE defaults to not DEBUG by default.

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Sep 10, 2015)

    Upgrading to 0.2

    Pre-0.2 settings

    WEBPACK_LOADER = {
            'BUNDLE_DIR_NAME': 'bundles/',
            'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json')
    }
    

    0.2 settings

    WEBPACK_LOADER = {
        'DEFAULT': {
            'BUNDLE_DIR_NAME': 'bundles/',
            'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
        }
    }
    

    New stuff

    • get_files template tag. Thanks to @sbaechler, we can now fetch a list of files from a bundle and constuct custom tags or use the file URLs in javascript.
    • Multiple webpack configurations Thanks to @cybercase, webpack loader can now consume the output of multiple stats files in the same project!
    Source code(tar.gz)
    Source code(zip)
  • 0.0.8(May 25, 2015)

    Introducing render by file extension feature.

    render_bundle can take second argument that is a file extension. If the file extension is provided, only files matching that extension will be rendered by the tag. For example,

    {% load render_bundle from webpack_loader %}
    
    <html>
      <head>
        {% render_bundle 'main' 'css' %}
      </head>
      <body>
        ....
        {% render_bundle 'main' 'js' %}
      </body>
    </head>
    

    will render CSS files in <head> and JS files just before </body>

    Source code(tar.gz)
    Source code(zip)
  • 0.0.6(May 24, 2015)

    This release introduces the BUNDLE_DIR_NAME setting and removed BASE_URL setting.

    BUNDLE_DIR_NAME is the name, actually relative path of the directory in which webpack will store the bundles. It is relative to it's parent static dir.

    For example, if ./assets/ is your static dir and bundles are stored in ./assets/bundles/, then your BUNDLE_DIR_NAME should be bundles/

    Source code(tar.gz)
    Source code(zip)
  • 0.0.4.1(May 20, 2015)

A django compressor tool that bundles css, js files to a single css, js file with webpack and updates your html files with respective css, js file path.

django-webpacker's documentation: Introduction: django-webpacker is a django compressor tool which bundles css, js files to a single css, js file with

MicroPyramid 72 Aug 18, 2022
Compresses linked and inline javascript or CSS into a single cached file.

Django Compressor Django Compressor processes, combines and minifies linked and inline Javascript or CSS in a Django template into cacheable static fi

2.6k Jan 03, 2023
Transparently use webpack with django

django-webpack-loader Read http://owaislone.org/blog/webpack-plus-reactjs-and-django/ for a detailed step by step guide on setting up webpack with dja

2.4k Jan 06, 2023
Asset management for Python web development.

Asset management application for Python web development - use it to merge and compress your JavaScript and CSS files. Documentation: https://webassets

Michael Elsdörfer 912 Dec 25, 2022
Photonix Photo Manager - a photo management application based on web technologies

A modern, web-based photo management server. Run it on your home server and it will let you find the right photo from your collection on any device. Smart filtering is made possible by object recogni

Photonix Photo Manager 1.5k Jan 01, 2023
https://django-storages.readthedocs.io/

Installation Installing from PyPI is as easy as doing: pip install django-storages If you'd prefer to install from source (maybe there is a bugfix in

Josh Schneier 2.3k Jan 05, 2023
Manage your activities as well as possible.

ToDo-List Manage your activities as well as possible. Create workspace Create many boards for different topics Add unlimited tasks About me Full name:

Matin Ardestani 10 Sep 11, 2022
HTML minifier for Python frameworks (not only Django, despite the name).

django-htmlmin django-html is an HTML minifier for Python, with full support for HTML 5. It supports Django, Flask and many other Python web framework

Cobra Team 536 Dec 25, 2022
Peak.py - An awesome tool to keep you up about servers and websites status

An In-house API Powered GUI App To Check Server Stats, Generate Logs And More Features To Be Added Soon.

3 Feb 24, 2022
Pipeline is an asset packaging library for Django.

Pipeline Pipeline is an asset packaging library for Django, providing both CSS and JavaScript concatenation and compression, built-in JavaScript templ

Jazzband 1.4k Dec 26, 2022
Compresses linked and inline javascript or CSS into a single cached file.

Django Compressor Django Compressor processes, combines and minifies linked and inline Javascript or CSS in a Django template into cacheable static fi

2.6k Jan 03, 2023
A faster collectstatic command.

Collectfast A faster collectstatic command. Features Efficiently decide what files to upload using cached checksums Parallel file uploads Supported St

Anton Agestam 405 Dec 27, 2022
django-systemjs

Django SystemJS Django SystemJS brings the Javascript of tomorrow to Django, today. It leverages JSPM (https://jspm.io) to do the heavy lifting for yo

Sergei Maertens 42 Jan 11, 2022
Python bindings to webpack

Unmaintained This project is unmaintained as it's a complicated solution to a simple problem. You should try using either https://github.com/owais/dja

Mark Finger 62 Apr 15, 2022