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

Overview

django-webpack-loader

Build Status Coverage Status pyversions djversions

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

Configuration

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('./assets/webpack_bundles/'),
    filename: "[name]-[hash].js"
  },
  plugins: [
    new BundleTracker({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 front-end 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 file with the information regarding the bundles and assets (webpack-stats.json) will be stored in the project root.

Compiling the front-end assets

You must generate the front-end bundle using webpack-bundle-tracker before using django-webpack-loader. You can compile the assets and generate the bundles by running:

npx webpack --config webpack.config.js --watch

This will also generate the stats file. You can also refer to how django-react-boilerplate configure the package.json scripts for different situations.

⚠️ Hot reload is available through a specific config. Check this section.

⚠️ This is the recommended usage for the development environment. For usage in production, please refer to this section

Configuring the 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.

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'],
  }
}

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 files paths in memory. From that point onwards, it will use these stored paths as the source of truth. If CACHE=False, we'll always read the stats file to get the assets paths.

⚠️ If CACHE=True, any changes made in the assets files will only be read when the web workers are restarted.

During development, when the stats file changes a lot, we want to always poll for its updated version (in our case, we'll fetch it 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.

While CACHE isn't directly related to POLL_INTERVAL, it's interesting to keep CACHE binded to the DEBUG logic value (in this case, the negation of the logic value) in order to only cache the assets in production, as we'd not continuously poll the stats file in that environment.

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 back-end side.

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.

Extra settings

  • 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 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:

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()

Rendering

In order to render the front-end 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 %}

{% render_bundle 'main' %}

That will render the proper

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)

Show how the redis works with Python (Django).

Redis Leaderboard Python (Django) Show how the redis works with Python (Django). Try it out deploying on Heroku (See notes: How to run on Google Cloud

Tom Xu 4 Nov 16, 2021
Django-discord-bot - Framework for creating Discord bots using Django

django-discord-bot Framework for creating Discord bots using Django Uses ASGI fo

Jamie Bliss 1 Mar 04, 2022
Utilities for implementing a modified pre-order traversal tree in django.

django-mptt Utilities for implementing Modified Preorder Tree Traversal with your Django Models and working with trees of Model instances. Project hom

2.7k Jan 01, 2023
✋ Auto logout a user after specific time in Django

django-auto-logout Auto logout a user after specific time in Django. Works with Python 🐍 ≥ 3.7, Django 🌐 ≥ 3.0. ✔️ Installation pip install django-a

Georgy Bazhukov 21 Dec 26, 2022
Django app for handling the server headers required for Cross-Origin Resource Sharing (CORS)

django-cors-headers A Django App that adds Cross-Origin Resource Sharing (CORS) headers to responses. This allows in-browser requests to your Django a

Adam Johnson 4.8k Jan 03, 2023
Serve files with Django.

django-downloadview django-downloadview makes it easy to serve files with Django: you manage files with Django (permissions, filters, generation, ...)

Jazzband 328 Dec 07, 2022
Wagtail - Vue - Django : The initial environment of full-stack local dev web app with wagtail and vue

Wagtail - Vue - Django : The initial environment of full-stack local dev web app with wagtail and vue. A demo to show how to use .vue files inside django app.

Quang PHAM 2 Oct 20, 2022
A fresh approach to autocomplete implementations, specially for Django.

A fresh approach to autocomplete implementations, specially for Django. Status: v3 stable, 2.x.x stable, 1.x.x deprecated. Please DO regularely ping us with your link at #yourlabs IRC channel

YourLabs 1.6k Dec 22, 2022
Django Course Project - TextCorrector

Django-TextUtils Django Course Project A tool for analyzing text data in Django backend. It is a project where you can do some of the things with you

1 Oct 29, 2021
🌟 A social media made with Django and Python and Bulma. 🎉

Vitary A simple social media made with Django Installation 🛠️ Get the source code 💻 git clone https://github.com/foxy4096/Vitary.git Go the the dir

Aditya Priyadarshi 15 Aug 30, 2022
A simple Django middleware for Duo V4 2-factor authentication.

django-duo-universal-auth A lightweight middleware application that adds a layer on top of any number of existing authentication backends, enabling 2F

Adam Angle 1 Jan 10, 2022
Django Login Api With Python

How to run this project Download and extract this project Create an environment and install all the libraries from requiements.txt pip freeze -r requi

Vikash Kisku 1 Dec 10, 2021
A simple Blog Using Django Framework and Used IBM Cloud Services for Text Analysis and Text to Speech

ElhamBlog Cloud Computing Course first assignment. A simple Blog Using Django Framework and Used IBM Cloud Services for Text Analysis and Text to Spee

Elham Razi 5 Dec 06, 2022
A Django app for working with BTCPayServer

btcpay-django A Django app for working with BTCPayServer Installation pip install btcpay-django Developers Release To cut a release, run bumpversion,

Crawford 3 Nov 20, 2022
a little task queue for python

a lightweight alternative. huey is: a task queue (2019-04-01: version 2.0 released) written in python (2.7+, 3.4+) clean and simple API redis, sqlite,

Charles Leifer 4.3k Dec 29, 2022
Per object permissions for Django

django-guardian django-guardian is an implementation of per object permissions [1] on top of Django's authorization backend Documentation Online docum

3.3k Jan 04, 2023
An airlines clone website with django

abc_airlines is a clone website of an airlines system the way it works is that first you add flights to the website then the users can search flights

milad 1 Nov 16, 2021
Keep track of failed login attempts in Django-powered sites.

django-axes Axes is a Django plugin for keeping track of suspicious login attempts for your Django based website and implementing simple brute-force a

Jazzband 1.1k Dec 30, 2022
Service request portal on top of Ansible Tower

Squest - A service request portal based on Ansible Tower Squest is a Web portal that allow to expose Tower based automation as a service. If you want

Hewlett Packard Enterprise 183 Jan 04, 2023
A quick way to add React components to your Django templates.

Django-React-Templatetags This django library allows you to add React (16+) components into your django templates. Features Include react components u

Fröjd Agency 408 Jan 08, 2023