Pyramid Webpack

A Pyramid extension for managing assets with Webpack.

Code lives here: https://github.com/stevearc/pyramid_webpack

User Guide

Getting Started

Install cookiecutter

Create a new project:

$ cookiecutter gh:stevearc/pyramid-cookiecutter-webpack

Install and set up necessary packages:

$ cd <your project>
$ virtualenv env
$ source env/bin/activate
$ pip install --upgrade pip
$ pip install -e .
$ npm install

Start the webpack build:

$ npm run watch

In a separate terminal, start the Pyramid server:

$ pserve --reload development.ini

Configuration

Options

webpack.debug

Argument: bool, inherits, default False

If True the server will re-read the stats file for each request and requests will block while webpack is running. See webpack.timeout to configure how long the requests will wait for webpack.

webpack.static_view

Argument: bool, default True

If True, pyramid_webpack will automatically set up the static view(s) for you. Disable this if you want to call add_static_view yourself (e.g. if you need to pass in custom parameters).

webpack.bundle_dir

Argument: str

The directory that contains the compiled webpack bundles. This may be in three forms:

  • raw_relative_path - This path will be relative to your root project package
  • package:relative_path - This is a path relative to a package location
  • /absolute/path - An absolute path on disk

You will almost always need to supply a bundle_dir, but if you are using an external webserver for webpack.static_view_name, then you don’t need to provide it.

webpack.static_view_name

Argument: str, default webpack-DEFAULT

This will be the name argument passed to add_static_view.

webpack.cache_max_age

Argument: int, inherits, default 0 or 3600

This will be the cache_max_age argument passed to add_static_view. It defaults to 0 when webpack.debug is true, and 3600 when false. Additionally, you can use the special value future to set it for 10 years in the future.

webpack.stats_file

Argument: str, default webpack-stats.json

The location of the webpack stats file generated by the webpack-bundle-tracker plugin. This path may be in the same three formats as webpack.bundle_dir.

webpack.timeout

Argument: float, inherits, default 0

Requests will block for this many seconds while waiting for webpack to finish compiling (if webpack.debug = True). A value of 0 will wait indefinitely.

webpack.ignore

Argument: list, inherits, default *.hot-update.js, *.map

When getting a bundle, ignore chunks that match these patterns. Uses glob matching.

webpack.ignore_re

Argument: list, inherits

When getting a bundle, ignore chunks that match these patterns. Uses PCRE matching.

webpack.configs

Argument: list

List of names of other webpack configurations to load. See the section below for more detail.

Multiple Configs

If you have multiple instances of webpack running and generating bundles, you can load them as well by giving them names and adding them to the webpack.configs option. You can then configure those instances by prefixing the same options in the config file with webpack.<name>.. For example:

webpack.debug = True
webpack.bundle_dir = webpack/bundles
webpack.stats_file = webpack/stats.json
webpack.configs =
    other

webpack.other.bundle_dir = webpack/other/bundles
webpack.other.stats_fie = webpack/other/stats.json

For any of the options that are marked as inherits (for example, webpack.debug), it will default to whatever value was provided to the default configuration. For example, the value of webpack.other.debug in the above example will default to True because webpack.debug = True.

For information on how to render bundles from different configs, see the docs on Rendering bundles into templates.

Static View Examples

Here we’ll go over a couple of example configurations for the asset static views and how they differ.

The simplest version can be used in development or production, and will serve the static assets using pyramid:

webpack.bundle_dir = webpack/bundles

If you’re running in production and want to serve the assets from a CDN, you can instead use a static_view_name:

# Don't need a webpack.bundle_dir
webpack.static_view_name = //my.cdn.com/

And if you want to full control over how the static views are set up, you can disable them:

webpack.static_view = False

And set it up yourself:

for config_name, state in config.registry.webpack.iteritems():
    # You should use state.static_view_path as the path.
    # That value is used to generate the urls via request.static_url()
    config.add_static_view(name="//my.cdn.com/" + config_name,
                           path=state.static_view_path,
                           cache_max_age=64000)

Rendering bundles into templates

Jinja2

Rendering bundles into jinja2 uses the webpack tag.

{% webpack 'main' %}
  <script type="text/javascript" src="{{ ASSET.url }}"></script>
{% endwebpack %}

Inside of the webpack block you will have access to an ASSET variable that has a url, name, and path. The text inside of the block will be repeated once per chunk that is in the bundle.

To use a different webpack config, prefix the name of the bundle with that config name and a colon:

{% webpack 'other_config:mybundle' %}
  <script type="text/javascript" src="{{ ASSET.url }}"></script>
{% endwebpack %}

And if you would like to filter the bundle by one or more file extensions, you can pass that in as a second argument (space delimited string).

{% webpack 'mybundle', '.js .js.gz' %}
  <script type="text/javascript" src="{{ ASSET.url }}"></script>
{% endwebpack %}

Chameleon

Chameleon templates should just make a call directly to the get_bundle() method.

<script type="text/javascript"
  tal:repeat="asset request.webpack().get_bundle('main')"
  src="${asset.url}">
</script>

To use a different webpack config, pass in the name of that config to request.webpack():

<script type="text/javascript"
  tal:repeat="asset request.webpack('other_config').get_bundle('main')"
  src="${asset.url}">
</script>

And if you would like to filter the bundle by one or more file extensions, you can pass them in as the second argument to get_bundle():

<script type="text/javascript"
  tal:repeat="asset request.webpack().get_bundle('main', ['.js', '.js.gz'])"
  src="${asset.url}">
</script>

Changelog

0.1.3 - 2017/9/5

  • Fix loading stats file in python 3.5 PR #6

0.1.2 - 2017/9/3

0.1.1 - 2016/10/27

  • Add cache_max_age config option

0.1.0 - 2016/10/23

  • Initial release

API Reference

pyramid_webpack package

Submodules

pyramid_webpack.jinja2ext module

Jinja2 extension for pyramid_webpack

class pyramid_webpack.jinja2ext.WebpackExtension(environment)[source]

Bases: jinja2.ext.Extension

Extension for jinja2.

Examples

{% webpack 'main' %}
    <link rel="stylesheet" type="text/css" href="{{ ASSET.url }}">
{% endwebpack %}
{% webpack 'other_config:main', 'js', 'js.gz' %}
    <script type="text/javascript" src="{{ ASSET.url }}"></script>
{% endwebpack %}
identifier = 'pyramid_webpack.jinja2ext.WebpackExtension'[source]
parse(parser)[source]
tags = set([u'webpack'])[source]

Module contents

pyramid_webpack

class pyramid_webpack.StaticResource(path)[source]

Bases: object

Wrapper around a filepath or asset path

classmethod create(path, root_package)[source]

Create a StaticResource, setting the package if needed

open()[source]

Open a stream object to the resource data

class pyramid_webpack.Webpack(request, name='DEFAULT')[source]

Bases: object

Wrapper object for the public webpack API

get_bundle(bundle_name, extensions=None)[source]

Get all the chunks contained in a bundle

stats[source]

Load and cache the webpack stats file

class pyramid_webpack.WebpackState(settings, root_package_name='pyramid_webpack', name='DEFAULT')[source]

Bases: object

Wrapper for all webpack configuration and cached data

load_stats(cache=None, wait=None)[source]

Load and cache the webpack-stats file

pyramid_webpack.get_webpack(request, name='DEFAULT')[source]

Get the Webpack object for a given webpack config.

Called at most once per request per config name.

pyramid_webpack.includeme(config)[source]

Add pyramid_webpack methods and config to the app

Indices and tables