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)

Owner
null
Django-static-site - A simple content site framework that harnesses the power of Django without the hassle

coltrane A simple content site framework that harnesses the power of Django with

Adam Hill 57 Dec 6, 2022
A Django application that provides country choices for use with forms, flag icons static files, and a country field for models.

Django Countries A Django application that provides country choices for use with forms, flag icons static files, and a country field for models. Insta

Chris Beaven 1.2k Jan 7, 2023
A Django application that provides country choices for use with forms, flag icons static files, and a country field for models.

Django Countries A Django application that provides country choices for use with forms, flag icons static files, and a country field for models. Insta

Chris Beaven 1.2k Dec 31, 2022
Radically simplified static file serving for Python web apps

WhiteNoise Radically simplified static file serving for Python web apps With a couple of lines of config WhiteNoise allows your web app to serve its o

Dave Evans 2.1k Dec 15, 2022
A Django app that allows visitors to interact with your site as a guest user without requiring registration.

django-guest-user A Django app that allows visitors to interact with your site as a guest user without requiring registration. Largely inspired by dja

Julian Wachholz 21 Dec 17, 2022
Generate generic activity streams from the actions on your site. Users can follow any actors' activities for personalized streams.

Django Activity Stream What is Django Activity Stream? Django Activity Stream is a way of creating activities generated by the actions on your site. I

Justin Quick 2.1k Dec 29, 2022
A handy tool for generating Django-based backend projects without coding. On the other hand, it is a code generator of the Django framework.

Django Sage Painless The django-sage-painless is a valuable package based on Django Web Framework & Django Rest Framework for high-level and rapid web

sageteam 51 Sep 15, 2022
Build reusable components in Django without writing a single line of Python.

Build reusable components in Django without writing a single line of Python. {% #quote %} {% quote_photo src="/project-hail-mary.jpg" %} {% #quot

Mitchel Cabuloy 277 Jan 2, 2023
With Django Hijack, admins can log in and work on behalf of other users without having to know their credentials.

Django Hijack With Django Hijack, admins can log in and work on behalf of other users without having to know their credentials. Docs 3.x docs are avai

null 1.2k Jan 5, 2023
Django API without Django REST framework.

Django API without DRF This is a API project made with Django, and without Django REST framework. This project was done with: Python 3.9.8 Django 3.2.

Regis Santos 3 Jan 19, 2022
Coltrane - A simple content site framework that harnesses the power of Django without the hassle.

coltrane A simple content site framework that harnesses the power of Django without the hassle. Features Can be a standalone static site or added to I

Adam Hill 58 Jan 2, 2023
Realtime data read and write without page refresh using Ajax in Django.

Realtime read-write with AJAX Hey,this is the basic implementation type of ajax realtime read write from the database. where you can insert or view re

Mehedi Hasan 3 Dec 13, 2022
Use Database URLs in your Django Application.

DJ-Database-URL This simple Django utility allows you to utilize the 12factor inspired DATABASE_URL environment variable to configure your Django appl

Jacob Kaplan-Moss 1.3k Dec 30, 2022
Use heroicons in your Django and Jinja templates.

heroicons Use heroicons in your Django and Jinja templates. Requirements Python 3.6 to 3.9 supported. Django 2.2 to 3.2 supported. Are your tests slow

Adam Johnson 52 Dec 14, 2022
Django project starter on steroids: quickly create a Django app AND generate source code for data models + REST/GraphQL APIs (the generated code is auto-linted and has 100% test coverage).

Create Django App ?? We're a Django project starter on steroids! One-line command to create a Django app with all the dependencies auto-installed AND

imagine.ai 68 Oct 19, 2022
Application made in Django to generate random passwords as based on certain criteria .

PASSWORD GENERATOR Welcome to Password Generator About The App Password Generator is an Open Source project brought to you by Iot Lab,KIIT and it brin

IoT Lab KIIT 3 Oct 21, 2021
Get inside your stronghold and make all your Django views default login_required

Stronghold Get inside your stronghold and make all your Django views default login_required Stronghold is a very small and easy to use django app that

Mike Grouchy 384 Nov 23, 2022
DCM is a set of tools that helps you to keep your data in your Django Models consistent.

Django Consistency Model DCM is a set of tools that helps you to keep your data in your Django Models consistent. Motivation You have a lot of legacy

Occipital 59 Dec 21, 2022
Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards and optional settings files.

Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards in settings file paths and mark setti

Nikita Sobolev 940 Jan 3, 2023