New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

simple-nunjucks-loader

Package Overview
Dependencies
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

simple-nunjucks-loader

Webpack loader for Nunjucks

  • 1.0.4
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
6.3K
decreased by-8.89%
Maintainers
1
Weekly downloads
 
Created
Source

npm package Coverage Status node Build Status Dependencies Status

Nunjucks templates loader for Webpack

This Webpack loader compiles Nunjucks templates. html-webpack-plugin compatible.

Install

npm install --save-dev simple-nunjucks-loader

If you don't use dynamic assets in your code, then you could save a bit on optional glob dependency:

npm install --no-optional --save-dev simple-nunjucks-loader

Note on global variables

By default Nunjucks wrap templates to global window.nunjucksPrecompiled. Loader didn't expose window.nunjucksPrecompiled. If your code relied on this object, it will definitely break. Use imports of required template or adopt expose-loader to your build pipeline.

Usage

This loader will precompile Nunjucks templates. It also includes Nunjunks (slim) runtime for browser.

Add loader to your webpack config as follows:

webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: /\.njk$/,
                use: [
                    {
                        loader: 'simple-nunjucks-loader',
                        options: {}
                    }
                ]
            }
        ]
    }
};

template-example.njk

<p>Hello, {{ username }}!</p>

app.js

import template from './template-example.njk'

document.body.innerHTML = template({
  username: 'Mike'
})

Bundling of app.js above will render paragraph with text "Hello, Mike!" to the page.

With html-webpack-plugin

For using with html-webpack-plugin just add it to plugins array, all options from it would be available as htmlWebpackPlugin.options in Nunjucks template.

webpack.config.js

const HTMLWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    module: {
        rules: [
            {
                test: /\.njk$/,
                use: [
                    {
                        loader: 'simple-nunjucks-loader',
                        options: {}
                    }
                ]
            }
        ]
    },
    
    plugins: [
        new HTMLWebpackPlugin({
            template: 'src/page.njk',
            templateParameters: {
                username: 'Joe'
            }
        })
    ]
};

src/page.njk

<p>Hello, {{ username }}!</p>

Refer to html-webpack-plugin page for all available options.

With assets

To load static assets (like images, for example), this loader inserts own static global function. It works like static from Django/Jinja2 integration, but resolves paths via Webpack loaders. It just replace calls static('foo.jpeg') with static(importedViaWebpackSymbol). static itself just returns loaded module or default export of it.

webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: /\.njk$/,
                use: [
                    {
                        loader: 'simple-nunjucks-loader',
                        options: {
                            assetsPaths: [
                                'app_example_a/static',
                                'app_example_b/static',
                            ]
                        }
                    }
                ]
            },

            {
                test: /\.png$/,
                use: [{
                    loader: 'file-loader'
                }]
            }
        ]
    }
};

template.njk

<img
    src="{{ static('./image.png') }}"
    alt=""
/>

The code above will replace {{ static('./image.png') }} with hash, that file-loader returns.

Dynamic assets

Loader has limited support for dynamic assets. It was tested with expressions like:

{{ static('foo/' + bar) }}
{{ static('foo/' + bar + '.ext') }}

:warning: I advocate against using dynamic assets, because:

  1. I have to support hacky regular expressions :smile:
  2. It's hard to find usages of asset, because there is no import of it
  3. Final bundle could be bigger without proper maintaining

From my experience it's better to have some kind of map, that will match some variable to import:

{% set examplesMap = {
    'example-1': static('foo/bar/dynamic-example-1.md'),
    'example-2': static('foo/bar/dynamic-example-2.md')
} %}

{% for item in [1, 2] %}
    <p>{{ examplesMap['example-' + item] }}</p>
{% endfor %}

How it works

By default Nunjunks bundle all precompiled templates to window.nunjucksPrecompiled, then loads them via custom loader from this global object. If precompiled template reference some other template file, it is loaded from disk (in NodeJS environment), or fetched via XMLHttpRequest from internet.

Both are not webpack-way for projects bundling.

This loader workaround this behaviour by precompiling templates and dependant templates as separate bundle chunks. It also use custom wrapper for precompiled code to avoid creating window.nunjucksPrecompiled.

It also adds each found template as dependency for template that need it, so bundle get rebuild in watch mode only when required.

Asynchronous support

When loader found async filter in template dependencies, it returns Promise, instead of render result.

Options

Loader supports limited number of Nunjuncks options. It's doesn't support watch (we use webpack own dependencies watch), noCache, web settings and express.

All other options get passed to Nunjunks Environment during files loading.

NameTypeDefaultDescription
jinjaCompat{Boolean}falseInstall Jinja syntax support in bundle
searchPaths{String} or {Array.<string>}.One or more paths to resolve templates paths
assetsPaths{String} or {Array.<string>}.Paths to resolve static assets. Works like STATICFILES_DIRS.
globalsObject.<string, string>{}Map global function to corresponding module
extensionsObject.<string, string>{}Map extension to corresponding module
filtersObject.<string, string>{}Map filters to corresponding module
autoescape{Boolean}trueSee Nunjuncks options for description of options below
throwOnUndefined{Boolean}false
trimBlocks{Boolean}false
lstripBlocks{Boolean}false
tags{Object.<string, string>}Default Jinja tags configOverride tags syntax

tags default to:

{
    blockStart: '{%',
    blockEnd: '%}',
    variableStart: '{{',
    variableEnd: '}}',
    commentStart: '{#',
    commentEnd: '#}'
}

jinjaCompat

Installs Jinja syntax. This option install it for whole bundle.

searchPaths

Loader is searching for full template relative to given string(s) from searchPath option (or project root, if no paths given).

Path to file couldn't be outside of folders above.

webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: /\.njk$/,
                use: [{
                    loader: 'simple-nunjucks-loader',
                    options: {
                        searchPaths: [
                            'django_app_a/templates',
                            'django_app_b/templates'
                        ]
                    }
                }]
            }
        ]
    }
};

assetsPaths

List of paths where loader should search for assets.

module.exports = {
    module: {
        rules: [
            {
                test: /\.njk$/,
                use: [{
                    loader: 'simple-nunjucks-loader',
                    options: {
                        assetsPaths: [
                            'django_app_a/static',
                            'django_app_b/static'
                        ]
                    }
                }]
            }
        ]
    }
};

globals

Set global function and import path, that should return function to use. It the same function that env.addGlobal using.

webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: /\.njk$/,
                use: [{
                    loader: 'simple-nunjucks-loader',
                    options: {
                        globals: {
                            _: 'lodash',
                            globalEnv: path.join(__dirname, 'app/global-env.js')
                        }
                    }
                }]
            }
        ]
    }
};

app/global-env.js

export default function globalFn(foo, bar) {
    return `Do anything with ${foo} and ${bar}`;
}

extensions

Set map of extensions that would be imported before each template render. Extension should return instance, that would be added via env.addExtension.

webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: /\.njk$/,
                use: [{
                    loader: 'simple-nunjucks-loader',
                    options: {
                        extensions: {
                            CustomExtension: path.join(__dirname, 'lib/extensions/custom-extension.js')
                        }
                    }
                }]
            }
        ]
    }
};

lib/extensions/custom-extension.js

// You should use slim bundle to make it work in browser
import nunjucks from 'nunjucks/browser/nunjucks-slim';

// See example in docs
// https://mozilla.github.io/nunjucks/api.html#custom-tags
class CustomExtension {}

export default new CustomExtension();

Loader trying to guess which extensions are really used, and keep only required imports.

filters

Map of filters, that would be imported before each template render. Filter should return instance, that would be added via env.addFilter.

webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: /\.njk$/,
                use: [{
                    loader: 'simple-nunjucks-loader',
                    options: {
                        filters: {
                            foo: path.join(__dirname, 'foo.js')
                        }
                    }
                }]
            }
        ]
    }
};

foo.js

export default function filter(val, param) {
    return `${val + param}`;
}

template.njk

{{ foo_var | foo(3) }}

To mark filter as async, filter module should export async flag:

async-filter.js

export default function asyncFilter(val, param, callback) {
    setTimeout(function() {
        callback(null, val + param);
    }, 1000);
}

asyncFilter.async = true;

Keywords

FAQs

Package last updated on 01 Jul 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc