Search code examples
javascriptnode.jsjinja2nunjucks

Precompiling Nunjucks templates with jinja2 compatibility mode


Nunjucks has more and more powerful jinja compatibility mode. If I include full nunjucks I can use it calling nunjucks.installJinjaCompat() before rendering templates (see snippet below):

nunjucks.installJinjaCompat();
var res = nunjucks.renderString(
  '{% for i in list[0:2] %}' +
  '  count: {{ i }}' +
  '{% endfor %}',
  {list: [1, 2, 3, 4]}
);
document.write(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/3.0.1/nunjucks.min.js"></script>

I cannot figure out how to precompile the same code though. Having file list.njk:

{% for i in list[0:2] %}
    count: {{ i }}
{% endfor %}

I precompile using default nunjucks-precompile list.njk > list.js command, but it raises:

/usr/local/lib/node_modules/nunjucks/src/precompile.js:130
        throw lib.prettifyError(name, false, err);
        ^

Template render error: (list.njk) [Line 1, Column 15]
  parseAggregate: expected comma after expression
    at Object.exports.prettifyError (/usr/local/lib/node_modules/nunjucks/src/lib.js:34:15)
    at _precompile (/usr/local/lib/node_modules/nunjucks/src/precompile.js:130:19)
    at precompile (/usr/local/lib/node_modules/nunjucks/src/precompile.js:79:27)
    at Object.<anonymous> (/usr/local/lib/node_modules/nunjucks/bin/precompile:62:13)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)

error if I use array splicing which is jinja-compatibility specific construct. It compiles if I remove [0:2].

How can I precompile templates taking adventage of jinja compat mode?

I have already tried finding this in documentation, nunjucks issues and checking nunjucks-precompile node script for nunjucks variable so I could monkeypatch it including nunjucks.installJinjaCompat() call; sadly it is not there, it only uses Environment.


Solution

  • It looks like nunjucks-precompile doesn't have a switch available for nunjucks.installJinjaCompat() but you can add it very easily:

    Copy the existing CLI file and modify it to correct the require source and install the compat layer:

    cp node_modules/.bin/nunjucks-precompile .
    <edit nunjucks-precompile>
    ./nunjucks-precompile list.njk
    ...
    

    with nunjucks 3.0.1 ./nunjucks-precompile should look like

    #!/usr/bin/env node
    var path = require('path');
    var precompile = require('nunjucks/src/precompile').precompile;
    var Environment = require('nunjucks/src/environment').Environment;
    var lib = require('nunjucks/src/lib');
    var nunjucks = require('nunjucks');
    nunjucks.installJinjaCompat();
    ...
    

    Or you can download it from here.