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)

Django admin CKEditor integration.

Django CKEditor NOTICE: django-ckeditor 5 has backward incompatible code moves against 4.5.1. File upload support has been moved to ckeditor_uploader.

2.2k Dec 31, 2022
Official clone of the Subversion repository.

Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. All documentation is in the "docs" directo

Raymond Penners 3 May 06, 2022
Analytics services for Django projects

django-analytical The django-analytical application integrates analytics services into a Django project. Using an analytics service with a Django proj

Jazzband 1.1k Dec 31, 2022
Example project demonstrating using Django’s test runner with Coverage.py

Example project demonstrating using Django’s test runner with Coverage.py Set up with: python -m venv --prompt . venv source venv/bin/activate python

Adam Johnson 5 Nov 29, 2021
A reusable Django model field for storing ad-hoc JSON data

jsonfield jsonfield is a reusable model field that allows you to store validated JSON, automatically handling serialization to and from the database.

Ryan P Kilby 1.1k Jan 03, 2023
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
PEP-484 stubs for django-rest-framework

pep484 stubs for Django REST framework Mypy stubs for DRF 3.12.x. Supports Python 3.6, 3.7, 3.8 and 3.9. Installation pip install djangorestframework-

TypedDjango 303 Dec 27, 2022
Full control of form rendering in the templates.

django-floppyforms Full control of form rendering in the templates. Authors: Gregor Müllegger and many many contributors Original creator: Bruno Renié

Jazzband 811 Dec 01, 2022
A real-time photo feed using Django and Pusher

BUILD A PHOTO FEED USING DJANGO Here, we will learn about building a photo feed using Django. This is similar to instagram, but a stripped off version

samuel ogundipe 4 Jan 01, 2020
The friendly PIL fork (Python Imaging Library)

Pillow Python Imaging Library (Fork) Pillow is the friendly PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lund

Pillow 10.4k Jan 03, 2023
Add a help desk or knowledge base to your Django project with only a few lines of boilerplate code.

This project is no longer maintained. If you are interested in taking over the project, email Zapier 487 Dec 06, 2022

Utilities to make function-based views cleaner, more efficient, and better tasting.

django-fbv Utilities to make Django function-based views cleaner, more efficient, and better tasting. 💥 📖 Complete documentation: https://django-fbv

Adam Hill 49 Dec 30, 2022
Twitter-clone using Django (DRF) + VueJS

Twitter Clone work in progress 🚧 A Twitter clone project Table Of Contents About the Project Built With Getting Started Running project License Autho

Ahmad Alwi 8 Sep 08, 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
Official Python agent for the Elastic APM

elastic-apm -- Elastic APM agent for Python This is the official Python module for Elastic APM. It provides full out-of-the-box support for many of th

elastic 369 Jan 05, 2023
Streamlining Django forms to provide all the wins of single-page-applications without the pain.

nango Streamlining Django forms to provide all the wins of single-page-applications without the pain. Key features Available to all Django deployments

Nick Farrell 107 Dec 12, 2022
Customize the behavior of django.contrib.auth permissions.

Customizando o comportamento do django.contrib.auth. O que queremos? Não criar as permissões padrões automaticamente (add, delete, view, read). Criar

Henrique Bastos 7 Nov 26, 2022
CRUD with MySQL, Django and Sass.

CRUD with MySQL, Django and Sass. To have the same data in db: insert into crud_employee (first_name, last_name, email, phone, location, university) v

Luis Quiñones Requelme 1 Nov 19, 2021
Reusable workflow library for Django

django-viewflow Viewflow is a lightweight reusable workflow library that helps to organize people collaboration business logic in django applications.

Viewflow 2.3k Jan 08, 2023
Dashboad Full Stack utilizando o Django.

Dashboard FullStack completa Projeto finalizado | Informações Cadastro de cliente Menu interatico mostrando quantidade de pessoas bloqueadas, liberada

Lucas Silva 1 Dec 15, 2021