Giter Club home page Giter Club logo

django-webpack-loader's Introduction

django-webpack-loader

Build Status Coverage Status pyversions djversions

Integrate Webpack bundles in Django templates by using a simple template tag:

{% load render_bundle from webpack_loader %}

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

Behind the scenes, Django Webpack Loader consumes a stats file generated by webpack-bundle-tracker and lets you use the generated bundles in Django.

A changelog is available.

Compatibility

Generally, Python, Django, and Node LTS releases will be supported until EOL. Check tests/tox.ini for details.
Versions not listed in tests/tox.ini may still work, but maintainers will not test them, nor solve issues with them.
Examples below are in Webpack 5.

Install

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

pip install django-webpack-loader

Configuration

For kick-starting a full example project with opinionated development and production settings, you can check the django-react-boilerplate. For a more flexible configuration, keep reading.

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(__dirname, "assets/webpack_bundles/"),
    publicPath: "auto", // necessary for CDNs/S3/blob storages
    filename: "[name]-[contenthash].js",
  },
  plugins: [
    new BundleTracker({ path: __dirname, 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 frontend 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 stats file with the information regarding the bundles and assets (webpack-stats.json) will be stored in the project root. You may add webpack-stats.json to your .gitignore.

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

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

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

Note that you must set the path where you're keeping your static assets and Webpack bundles in STATICFILES_DIRS.

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 paths in memory. If CACHE=False, we'll always read the stats file to get the assets paths.

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 backend side.

During development, the stats file will change often, therefore we want to always poll for its updated version (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.

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.

Compiling the frontend assets

Using Webpack, you must generate the frontend bundle along with the stats file using webpack-bundle-tracker before using django-webpack-loader in Django templates. Note you'll probably want different configurations in development vs. production. The pipeline should look like this:

flowchart TD
    A("Run webpack")
    A --> |CSS, JS, imgs, fonts| B(Collect compiled assets)
    A --> |webpack-stats.json| C(Read on Django templates)

In development, we can simply do:

# in one shell
npx webpack --mode=development --watch

# in another shell
python manage.py runserver

Check the full example for development here.

Aditionally, hot reload is available through a specific config. Check this section.

⚠️ For compiling and serving the frontend assets in production, check this section.

Usage

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

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

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

Using in tests

To run tests where render_bundle shows up, since we don't have webpack-bundle-tracker at that point to generate the stats file, the calls to render the bundle will fail. The solution is to use the FakeWebpackLoader in your test settings:

WEBPACK_LOADER['DEFAULT']['LOADER_CLASS'] = 'webpack_loader.loaders.FakeWebpackLoader'

Using in Production

The recommended apporach is to have a production pipeline that generates the frontend bundle along with the stats file during the deployment phase. We recommend keeping the generated bundles and the stats file outside the version control. In other words, add webpack-stats.json and assets/webpack_bundles/ to your .gitignore.

Assuming static files is properly configured using Django built-ins or something like django-storages, a simple production deployment can use Django's own collectstatic. Remember the Django settings values of STATICFILES_DIRS, BUNDLE_DIR_NAME, STATS_FILE, and Webpack's output.path must all be compatible:

// webpack.config.js
module.exports = {
  // ...
  context: __dirname,
  output: {
    // Emit bundle files at "assets/webpack_bundles/":
    path: path.resolve(__dirname, "assets/webpack_bundles/"),
    publicPath: "auto", // necessary for CDNs/S3/blob storages
    filename: "[name]-[contenthash].js",
  },
  plugins: [
    // Emit 'webpack-stats.json' in project root for Django to find it:
    new BundleTracker({ path: __dirname, filename: "webpack-stats.json" }),
  ],
};
# app/settings.py

BASE_DIR =  ... # set to project root

STATICFILES_DIRS = (
   # make Django collect all "assets/" and "assets/webpack_bundles"
   # to be served at "my-static-url.com/asset-name.png"
   # and "my-static-url.com/webpack_bundles/main.js"
   os.path.join(BASE_DIR, 'assets'),
)

WEBPACK_LOADER = {
    'DEFAULT': {
        # Bundle directory, like in "my-static-url.com/webpack_bundles/main.js":
        'BUNDLE_DIR_NAME': 'webpack_bundles/',
        # Absolute path to where 'webpack-stats.json' is in Django project root:
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
        # ...
    }
}

In your deployment script, you must first run your Webpack build in production-mode, before calling collectstatic:

NODE_ENV=production webpack --progress --bail --mode=production
python manage.py collectstatic --noinput

This means we're building the assets and, since we have webpack-bundle-tracker in our Webpack building pipeline, the webpack-stats.json stats file is also populated. If you followed the default configuration, the webpack-stats.json will be at Django's project root (BASE_DIR) and the render_bundle template tag will be able to use it.

However, production usage for this package is fairly flexible, as the entire Django-Webpack integration depends only on the webpack-stats.json file.

⚠️ Heroku is one platform that automatically runs collectstatic for you, so you need to set the DISABLE_COLLECTSTATIC=1 environment var and manually run collectstatic after running Webpack. In Heroku, this is achieved with a post_compile hook. Here's an example.

Advanced Usage

Hot reload

Hot reload (Hot Module Replacement) is critical for a improving the development workflow. In case you wish to enable for your project, please check out this example, in particular how webpack.config.js is configured. The key is to set the publicPath and devServer.

Dynamic Imports

In case you wish to use Dynamic Imports, please check out this example, in particular how webpack.config.js is configured.

Extra options for webpack-bundle-tracker

Check webpack-bundle-tracker README for all supported options, such as relative paths, integrity hashes, timestamp logging, etc.

Extra WEBPACK_LOADER settings in Django

Set those extra settings inside like this:

WEBPACK_LOADER = {
    'DEFAULT': {
       # settings go here
    }
  • 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

  • INTEGRITY is flag enabling Subresource Integrity on rendered <script> and <link> tags. Integrity hash is get from stats file and configuration on side of BundleTracker, where configuration option integrity: true is required.

  • 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.loaders.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.loaders import WebpackLoader

class ExternalWebpackLoader(WebpackLoader):
    def load_assets(self):
        url = self.config['STATS_URL']
        return requests.get(url).json()
  • SKIP_COMMON_CHUNKS (Default: False) is a flag which prevents already generated chunks from being included again in the same page. This should only happen if you use more than one entrypoint per Django template (multiple render_bundle calls). By enabling this, you can get the same default behavior of the HtmlWebpackPlugin. The same caveats apply as when using skip_common_chunks on render_bundle, see that section below for more details.

Rendering by file extension

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

{% load render_bundle from webpack_loader %}

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

Using preload

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

{% load render_bundle from webpack_loader %}

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

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

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

Accessing other webpack assets

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

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

{% load webpack_static from webpack_loader %}

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

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

Please note that this approach will use the original asset file, and not a post-processed one from the Webpack pipeline, in case that file had gone through such flow (e.g.: You've imported an image on the React side and used it there, the file used within the React components will probably have a hash string on its name, etc. This processed file will be different than the one you'll grab with webpack_static).

Use skip_common_chunks on render_bundle

You can use the parameter skip_common_chunks=True or skip_common_chunks=False to override the global SKIP_COMMON_CHUNKS setting for a specific bundle.

In order for this option to work, django-webpack-loader requires the request object to be in the template context. The request object is passed by default via the django.template.context_processors.request context processor, so make sure you have that.

If you don't have request in the context for some reason (e.g. using Template.render or render_to_string directly without passing the request), you'll get warnings on the console and the common chunks will remain duplicated.

Appending file extensions

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

{% load render_bundle from webpack_loader %}
<html>
  <head>
    <meta charset="UTF-8">
    <title>Example</title>
    {% render_bundle 'main' 'css' %}
  </head>
  <body>
    {% render_bundle 'main' 'js' suffix='.gz' %}
  </body>
</html>

Multiple Webpack configurations

django-webpack-loader also supports multiple Webpack configurations. Assuming you have different Webpack configs, each with a different output.path, the following configuration defines 2 Webpack stats files in settings and uses the config argument in the template tags to influence which stats file to load the bundles from:

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

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

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

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

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

File URLs instead of HTML tags

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

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

Each object in the returned list has 2 properties:

  1. name, which is the name of a chunk from the stats file;
  2. url, which can be:
  3. The publicPath if the asset has one;
  4. The path to the asset in the static files storage, if the asset doesn't have a publicPath.

For example:

{% load get_files from webpack_loader %}

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

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

Jinja2 Configuration

If you need to output your assets in a jinja template, we provide a Jinja2 extension that's compatible with django-jinja.

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

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

Then in your base jinja template, do:

{{ render_bundle('main') }}

Note: get_files in Jinja2 is called webpack_get_files.

Migrating from version < 1.0.0

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

Contributing

This project includes a Makefile that provides several useful commands for building, installing, and publishing the project. Please feel free to open PRs or create issues!

Available Commands

  • clean: Removes generated files and directories.
  • build: Cleans the project and builds the distribution packages.
  • test: Run the tests.
  • install: Installs the project's build dependencies. Will initialize a virtual environment if one does not exist.
  • publish: Builds the distribution packages and publishes them to the specified repository.
  • register: Registers the package on the specified repository.

To execute a command, run make <command> in the project's root directory.

Virtual Environment Settings

  • ENV: The name of the virtual environment. (Default: venv)
  • REPOSITORY: The repository to publish the distribution packages to. (Default: pypi)

Special Thanks

Django Webpack Loader was originally created by Owais Lone and received contributions from more than 50 developers since its inception, as well as many others who assisted with issues, comments, articles, talks, etc. Thanks for everyone who's been part of Django Webpack Loader community!

Commercial Support

alt text

This project is currently maintained by Vinta Software and is used in products of Vinta's clients. We are always looking for exciting work, so if you need any commercial support, feel free to get in touch: [email protected]

django-webpack-loader's People

Contributors

alphashuro avatar amy-mac avatar aouaki avatar basicdays avatar browniebroke avatar chocoelho avatar dependabot[bot] avatar destos avatar fjsj avatar fladi avatar hyshka avatar joaopslins avatar joshjo avatar karolyi avatar marzab avatar matthiask avatar michael-yin avatar michaeljones avatar mikeengland avatar mlorant avatar mogost avatar ntucker avatar owais avatar pierrei avatar rangelfinal avatar rvlb avatar ssteinerx avatar teamteatime avatar thejoeejoee avatar wongcht avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-webpack-loader's Issues

Hosting webpack bundle on seperate server

What if I want to host my webpack bundle on another server (either a docker container or normal nginx server) how would I go about doing this? do I just specify a url for the 'STATS_FILE' in the settings?

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:
    #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'








Multiple STATS_FILE support

I'm working on a project that has multiple webpack config files (one for each django app), so I was thinking to add support for multiple webpack-stats.json files...
something like:

WEBPACK_LOADER = {
    ...
    'STATS_FILE': ('webpack-stats-app1.json', 'webpack-stats-app2.json'),
    ...
}

Is it ok for you if I add this feature and submit a PR?
Or do you think there is a better way to deal with multiple webpack config files?

Thanks

ERROR in ./assets/js/index.jsx Module build failed: SyntaxError:

Am very new to webpack, was following the web blog to setup and run webpack but getting the following errors. Running Django 1.9.1.

ERROR in ./assets/js/index.jsx
Module build failed: SyntaxError: /Users/yensheng/virtualenvs/1fotograf/fotograf/static/assets/js/index.jsx: Unexpected token (4:13)
2 | var App = require('./app')
3 |
4 | React.render(<App/>, document.getElementById('react-app'))

My index.jsx, exactly the same as per the tutorial.

var React = require('react')
var App = require('./app')

React.render(<App/>, document.getElementById('react-app'))

Error is pointing at the "<" before "App". Tried with my own react code and getting the same error at the same place. Did I missed out anything?

Bizarre accident on live server

First off, thanks for the package ! Very useful. I've built and deployed hundreds of times.

I've been using node 4.2.1 for development and my project's node_modules were built against that, but today I accidentally did my webpack build with 6.9.1 activated. It built fine. I didn't take the time to start the server locally because I was deploying python only changes and had already test those.

Deployed to the live server, and somehow webpack_loader detected the 4.2.1 vs 6.9.1 conflict and then tried to rebuild the sass files.

Django Version: 1.8.15
Exception Type: WebpackError
Exception Value:    
            Error in 
            Missing binding /Users/crucial/Sites/nestseekers/frontend/node_modules/node-sass/vendor/darwin-x64-48/binding.node
Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js 6.x

Found bindings for the following environments:
  - OS X 64-bit with Node.js 4.x

This usually happens because your environment has changed since running `npm install`.
Run `npm rebuild node-sass` to build the binding for your current environment.

Exception Location: /home/nestseekers/venv/local/lib/python2.7/site-packages/webpack_loader/loader.py in get_bundle, line 89

This is on my personal computer: /Users/crucial/Sites/nestseekers

These errors were thrown on the live server.

There is no node on the server, no node_modules. The generated webpack-state-productions.json does not make any reference to node versions.

I can't figure out what caused it to try to find these bindings at that path or why it decided to build sass.

It only took a few minutes to do figure it out, rebuild and deploy.

WebpackLoaderBadStatsError

Hi,

I am occasionally getting a 500 error when requesting pages that are using webpack-loader:

WebpackLoaderBadStatsError at /admissions/application/new/
The stats file does not contain valid data. Make sure webpack-bundle-tracker plugin is enabled and try to run webpack again.

It does not happen all of the time, which is puzzling.

Here are the contents of webpack-stats.json:

{"status":"done","chunks":{"main":[{"name":"main-fbfb6b94425602ed6e8a.js","path":"/path/to/main-fbfb6b94425602ed6e8a.js"}]}}

And here are the permissions:

-rw-r--r-- 1 www-data ...

Is there any way to troubleshoot what is causing this error? Any help would be appreciated!

Issues experienced

Hey @owais

Your project's definitely appealing - having written far too many python wrappers in my time, there's definitely got to be a better way. While I've generally tried to keep things as minimalistic as possible, the disconnect between processes makes it extremely difficult to maintain a small footprint. The lack of an easily understandable codebase results in wrapper APIs which lag behind the core and overly complicate build processes.

I haven't really mused over it yet, but I'm curious do you have any reflections regarding your approach? Any identified issues, etc?

Issue with creating production bundles

Hi,

Thanks very much for publishing this and the supplementary guide. It is very very helpful.

For webpack.prod.config.js, I had to remove the last curly brace. I also had to add the following two lines:

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

When I run

./node_modules/.bin/webpack --config webpack.prod.config.js

it expects additional parameters. Am I doing something wrong?

Convenience management command

Hey, thanks for the work you did with webpack loader. It's working great.

I have a feature suggestion. Maybe we could include a convenience management command for running webpack --watch along with runserver. Something along the lines of

python manage.py webpack

which will start webpack in watch mode along with runserver.

This is how I used to do it with grunt. https://github.com/mixxorz/generator-django-kaiju/blob/master/app/templates/kaiju/apps/core/management/commands/gruntserver.py

It's so that you don't need two terminals running when you want your live reloading static assets along with Django's development server.

WEBPACK_LOADER example doesn't work

The following config, based on the example at http://owaislone.org/blog/webpack-plus-reactjs-and-django/ didn't work for me. I got the following error:

ERRORS:
django.conf.settings.WEBPACK_LOADER: (django-webpack-loader.E001) Error while parsing WEBPACK_LOADER configuration
    HINT: Is WEBPACK_LOADER config valid?
WEBPACK_LOADER = {
    'BUNDLE_DIR_NAME': 'bundles/',
    'STATS_FILE': join(SITE_ROOT, 'webpack-stats.json')
}

I had to set it like so to make it work:

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

DWL with vue.js does not work (the bundle itself works...)

I have been running DWL for couple of months now and working great! I now tried to include vue.js in my bundle and do not get it working. However it does work when I copy the main-[hash].js bundle to the Django static folder and reference it with:

<script type="text/javascript" src="{% static 'vuejs/main-[hash].js' %}"></script>

Furthermore, (several) other libraries and css and sass included in the bundle DO get through when using DWL. So it seems something particular makes DWL not work with vue.js. As there is some issues with django template tags and vue tags both being {{ }}, it is 'common' to change vue tags into [[ ]] ; I tried whether changing it into something else, like {* *}would solve my issue, but that did not solve it.

Further details:
testhtml:

{% load staticfiles %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Webpack Sample Project</title>

{% load render_bundle from webpack_loader %}


</head>

<body>
{% render_bundle 'main' %}


<h3>[[ message ]]</h3>
kiekeboe


<!-- Vue.JS -->

{#<script type="text/javascript" src="{% static 'vuejs/main-890ab68c2f63dd3f9a2a.js' %}"></script>#}

</body>
</html>

Request for example pre-rendering React components with model data on the server

Hey,

I'm a huge fan of this tool, and thanks for documenting it so clearly. I don't have any issue with the code, but I was wondering if you might be able to provide an example that demonstrates how to pass data from Django views to react components when they render on the server? I've been trying to figure this out myself for a week now, but I'm new to webpack and so far have had no luck. Any guidance you could give would be deeply appreciated.

Thanks again for making this!

Best,
Jonathan

KeyError in loader.py upon error.

get_bundle defines the following:

            error = u"""
            {error} in {file}
            {message}
            """.format(**assets)

However, upon some webpack errors, my assets dict contained the following:

{
'file': '', 
'message': '(1,24): error TS2307: Cannot find module 'react'.', 
'status': 'error'
}

Therefore, django-webpack-loader crashed, shadowing the root cause of the crash. Was quite frustrating.
I can PR a simple fix that stubs error if it's not in there, but it seems like it's very much supposed to be in there.

Ability to specify file in template tag

Hi.

So I'm currently using django-webpack-loader in order to make react-hot-loader work. The thing is, is I have 2 entry points which both output their own file. I would like the ability to specify a specific file, rather than (what I think I would have to do) create an entirely different webpack config file & associated npm scripts to go with it.

Normally this wouldn't make sense (e.g. why not just build the files and reference them directly in the template) however again... I'm using react-hot-loader. Any advice on how to proceed?

using python-react

what are the changes to be made if python-react is to be used alongside with the tutorial given in your blog for setting up with django?

What's the reccomended way of accessing packaged assets like images?

I have webpack configured to bundle up some images that are associated with my react components using file-loader. They are stored with my JS bundle, but require(..) just gives me the file name, not the full path.

Workaround at the moment is to hardcode in STATIC_PATH from django in addition to filename, or use url-loader instead to inline image data.

What's the suggested approach here?

Not rendering the hello world example in 'webpack-plus-reactjs-and-django

I have a react app working in django and am looking to use webpack to re-factor and streamline its ongoing development and maintenance.

Using the blog entry, all went well until I got to the actual presentation in Django.

I've copied the code pretty much verbatim save for putting it in a 'front_end' folder (paths etc. updated appropriately). The app.jsx file exports the class object fine but the render method on the object is never called (inserted console.log does not appear). In my other app example I use ReactDOM.render rather than React.render but apart from that it looks pretty similar.

The rest of the template comes up fine and it has included the bundle js correctly.

As the React debugger does not come up in Firefox and everything is mushed into the bundle (without any issues), I'm not sure where to go from here in terms of debugging.

Hashes in the path are not allowed

I'm able to do the following in webpack:

module.exports = {
    ...
    output: {
        path: path.resolve('../webpack_bundles/[hash]'),
        filename: '[name].js',
    },
    ...
};

But django-webpack-loader doesn't allow that. Here you expect to have a path to the chunk. But if the hash is in the path, it's not known in advance.

Can't we add, say, BUNDLE_DIR_PATH and do something along these lines?

import os.path
if 'BUNDLE_DIR_PATH' in self.config:
    relpath = os.path.relpath(chunk['path'], self.config['BUNDLE_DIR_PATH'])

fails to find bundle from webpack commonschunkplugin

Hello,
I am experiencing a problem where " {% render_bundle 'commons' %}" fails to find commons-bundle, which is located in the same directory as my other bundle. Tried both "commons-bundle" and "commons". When I disable plugin - it is able to find another bundle through {% render_bundle 'servicesList' %}. Some details below:

  • Django Version: 1.8.6
  • Exception Type: KeyError
  • Exception Value: 'commons'
  • Python Version: 3.5.0
  • django-webpack-loader==0.2.2
  • webpack: 1.12.9
  • webpack-bundle-tracker: 0.0.8

webpack configuration:

var path = require("path");
var webpack = require('webpack');
var CommonsChunkPlugin = require("./node_modules/webpack/lib/optimize/CommonsChunkPlugin");
var BundleTracker = require('webpack-bundle-tracker');


module.exports = {
    context: __dirname,
    entry: {
        servicesList: "./src/servicesList.jsx"
    },
    output: {
        path: path.resolve("./specto/dist"),
        filename: "[name]-bundle.js"
    },
    module: {
      loaders: [
          {
              //regex for file type supported by the loader
              test: /\.(jsx)$/,
              exclude: /node_modules/,
              //type of loader to be used
              //loaders can accept parameters as a query string
              loader: 'babel-loader',
              query:
              {
                  plugins: ['transform-runtime'],
                  presets:['react', 'es2015']
              }
          },
          {
              test: /\.js$/, loader: 'babel-loader'
          }
      ]
    },
    plugins: [
        new BundleTracker({filename: './webpack-stats.json'}),
        new CommonsChunkPlugin("commons-bundle.js")
    ]
};

settings.py

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'specto/static/specto'),
)

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

}

TypeError when manifest is not ready

When manifest is not ready, webpack_loader raised ugly TypeError,

TypeError: 'NoneType' object is not iterable
  File "django/core/handlers/base.py", line 164, in get_response
    response = response.render()
  File "django/template/response.py", line 158, in render
    self.content = self.rendered_content
  File "django/template/response.py", line 135, in rendered_content
    content = template.render(context, self._request)
  File "django/template/backends/django.py", line 74, in render
    return self.template.render(context)
  File "django/template/base.py", line 209, in render
    return self._render(context)
  File "django/template/base.py", line 201, in _render
    return self.nodelist.render(context)
  File "django/template/base.py", line 903, in render
    bit = self.render_node(node, context)
  File "django/template/base.py", line 917, in render_node
    return node.render(context)
  File "django/template/loader_tags.py", line 135, in render
    return compiled_parent._render(context)
  File "django/template/base.py", line 201, in _render
    return self.nodelist.render(context)
  File "django/template/base.py", line 903, in render
    bit = self.render_node(node, context)
  File "django/template/base.py", line 917, in render_node
    return node.render(context)
  File "django/template/base.py", line 1195, in render
    return func(*resolved_args, **resolved_kwargs)
  File "webpack_loader/templatetags/webpack_loader.py", line 36, in render_bundle
    return render_as_tags(_get_bundle(bundle_name, extension, config))
  File "webpack_loader/templatetags/webpack_loader.py", line 18, in render_as_tags
    for chunk in bundle:
  File "webpack_loader/templatetags/webpack_loader.py", line 11, in filter_by_extension
    for chunk in bundle:

But I think it's better to raise some custom exception instead of TypeError.

Generating the correct path for images

(This is more a question around understanding and clarification rather than a proposal for a specific fix).

Going off this guide: is there a reason why a file-loader is not needed in the production webpack config?

When I don't include it and I use a require('.../img.png') in my application code, webpack correctly finds the image, renames it based on the hash, dumps it in the right place, and sets the path correctly. In other words, everything works OK.

Per all the documentation I've read on webpack, there are explicit recommendations to put the following in one's config file:

  module: {
    loaders: [
      { 
...
      { test: /\.(png|jpg)$/, loader: 'file-loader'} 
    ],
  },

If I include the above, webpack generates another file that's either malformed or just some dummy stub.

issue running in django project

Performing system checks...

Unhandled exception in thread started by <function wrapper at 0x7ff64938a848>
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line 229, in wrapper
fn(_args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/runserver.py", line 114, in inner_run
self.validate(display_num_errors=True)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 469, in validate
return self.check(app_configs=app_configs, display_num_errors=display_num_errors)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 528, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:

ERRORS:
django.conf.settings.WEBPACK_LOADER: (django-webpack-loader.E001) Error while parsing WEBPACK_LOADER configuration
HINT: Is WEBPACK_LOADER config valid?

System check identified 1 issue (0 silenced).

Typo & suggestion for production webpack config

Hi again,

  1. In the blog post here, at the very bottom under the webpack.prod.config.js section, the following edit should be made:

config.output.pathName => config.output.publicPath

  1. This is more of a suggestion but it wasn't obvious to me what I had to do to remove the hot loader from the production webpack config. Perhaps a line like so

config.entry = ['./assets/js/index']

might be helpful. That way, regardless of whether people are hot loading or not in their development webpack config, their production config won't contain it.

Just want to reiterate a big thank you to @owais. Your guide and plugin have been tremendously useful.

Manish

Singleton manifest

Hey @owais

I was hoping to use your lib with a decoupled app which ships with pre-built bundles. As far as I can tell, it only allows you to use a single manifest, which looks like it'd preclude any other apps from trying to use the loader.

Is there anyway to override the manifest path?

Something like the following would be cool

import os
from webpack_loader.utils import read_bundle_from_manifest

manifest_path = os.path.join(os.path.dirname(__file__), 'webpack-manifest.json')

bundle = read_bundle_from_manifest(manifest_path)

bundle.render_css()
bundle.render_js()

or even

{% load render_bundle from webpack_loader %}

{% render_bundle 'main' 'css' path_to_manifest %}
{% render_bundle 'main' 'js' path_to_manifest %}

render_bundle template tag cannot be used to load gzipped files

If you want to serve gzipped files (say, those created by https://github.com/webpack/compression-webpack-plugin), the render_bundle template tag cannot serve these.

Even if you specify js.gz as the extension, e.g. {% render_bundle 'main' 'js.gz' %}, the render_as_tags function will not pick up these files. This is because chunk['name'].endswith('.js') and chunk['name'].endswith('.css') are used. I suggest this is changed to allow for '.js.gz' and '.css.gz' files as well.

As a temporary work around, a direct link to the content can be used, e.g. <script type="text/javascript" src="/static/bundles/main.js.gz"></script>
but this is not ideal.

webpack_static documentation

There's no documentation about what webpack_static does (or even that it exists -- I stumbled across it looking at the source for render_bundle).

In particular it appears to completely bypass the error/compiling steps in get_bundle() -- is this intended?

Long Term Caching

Is there anyway of having django-webpack-loader or webpack-tracker to clear out old hashed files in the output directory?

add async parameter to compiled webpack file

My file is getting compiled and loading fine with following configuration:-

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

However when I change it to following to add async behavior its not loading on the page:-

{% load render_bundle from webpack_loader %}
{% render_bundle 'main' 'js' 'DEFAULT' attrs='async charset="UTF-8"' %}
{% javascript 'wlhome'  %}

Can you please help me on this?

Tag to specify a single target URL

I have a use-case where I need to specify the URL to a generated CSS file within a Javascript options object. I therefore need the publicPath without the HTML tags.

I have created a working implementation here but maybe there is a better way to do it.
https://github.com/sbaechler/django-webpack-loader/blob/tag/webpack_loader/templatetags/webpack_loader.py

I am using the new tag in the CKeditor config. 'editor' is the name of the CSS bundle:

CKEDITOR.config.contentsCss = '{% bundle_item_url 'editor' 'css' %}';

LICENCE file gets installed outside of the wheel, easily conflicting with own Licence files

Steps to reproduce:

virtualenv webpack_issue
cd webpack_issue
echo "Free as in beer" > LICENSE
./bin/pip install django-webpack-loader
cat LICENSE

the expected output is "Free as in beer" The actual output is the MIT LICENSE

I've looked up the docs for the data_files option and I didn't find a way to define it relative to the wheel location.
Maybe include_package_data would do the trick to add the LICENSE to a better location

Render bundle do not add static_url prefix

I'm trying to run my test configuration. I expect that bundles will we added with static prefix

My config:

STATIC_URL="/static/"
WEBPACK_LOADER = {
    'EDITOR': {
        'BUNDLE_DIR_NAME': 'viewer/build/',  # end with slash
        'STATS_FILE': os.path.join(PROJECT_DIR, 'commons', 'viewer', 'build', 'bundle-stats.json'),
    }
}
{% load render_bundle from webpack_loader %}
...
{% render_bundle 'main' config='EDITOR' %}
...

webpack stats

{
  "status": "done",
  "chunks": {
    "main": [
      {
        "name": "main.js",
        "publicPath": "/viewer/build/main.js",
        "path": "/home/dariusz/PROJECTS/viewer/build/main.js"
      }
    ]
  },
  "publicPath": "/viewer/build/"
}

That what I get in output:

<script type="text/javascript" src="/viewer/build/main.js" ></script>

What I expect is

<script type="text/javascript" src="/static/viewer/build/main.js" ></script>

Is it desired behavior? When I looked at templates tag's code there isnt anything that can handle it.

Issue with react router

Somehow I cant get this working with react router.

So following is my routing code:-

import { Router, Route, browserHistory, IndexRoute } from 'react-router';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import About from './About';
import Contact from './Contact';
import Home from './Home';


ReactDOM.render((
     <Router history={browserHistory}>
      <Route path="/" component={App}>
       <IndexRoute component={Home}/>
       <Route path="/about" component={About}/>
       <Route path="/contact" component={Contact}/>
  </Route>
  </Router>
), document.getElementById('app'));

Following is the App component:-

class App extends React.Component{
  render(){
  var href = this.props.history.createHref('/about');
  return(
        <div>
                <div>hello router</div>
                <Link to='/about'>About</Link>
                 <Link to="/contact">Contact</Link>
                {this.props.children}
        </div>
  )
}
}

So the issue I am facing is when i click on about the link changes but the content does not. However now if i press browser back I reach home and then i press browser forward I reach about again and this time both url and content change.

So to check this out i used the same generated bundled js file in a static html and tried to access to that file after npm start, it worked fine over there. However when I used the same file in django using web pack loader here I see the issue mentioned above

Output CSS can't find font assets

This might be something I've screwed up, but for some reason the CSS that webpack outputs to the views can't find fonts loaded via CSS @font-face.

Example:

@font-face {
  font-family: 'proxima_nova_rgbold';
  src: url(f1269047cfeba0c5afee919b40d06db4.eot);
 }

This is the correct output and webpack does bundle the needed assets into the correct output folder, so it should for all intents and purposes be working. But it just isn't.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.