Search code examples
node.jsnpmnunjucks

How to reference a nunjucks template included in a node module?


If I want to package a nunjucks template file with a node module, how do I reference the packaged template file so it is universally available when the package is installed globally?

I have the following node file, index.js:

#!/usr/bin/env node

var nunjucks = require('nunjucks');

var env = nunjucks.configure('./');
var template = env.getTemplate('template.html');
var output = template.render({
  h1_copy: "Foo and Bar"
});

console.log(output);

Here's template.html:

<html>
  <body>
    <h1>{{ h1_copy }}</h1>
  </body>
</html>

I set it up to have a binary command in the package.json:

"bin": {
  "make_output": "./index.js"
}

Now, if I install it globally, I can run make_output to make the output:

node-nunjucks$ npm install -g .
/usr/local/bin/make_output -> /usr/local/lib/node_modules/node-nunjucks/index.js
+ [email protected]
added 1 package in 0.099s

node-nunjucks$ make_output
<html>
  <body>
    <h1>Foo and Bar</h1>
  </body>
</html>

But that only works if template.html is present in the directory where I run the command. If I try to run the global command from anywhere else, it can't find the template:

node-nunjucks$ cd ..
tmp$ make_output
/private/tmp/node-nunjucks/node_modules/nunjucks/src/environment.js:296
          throw err;
          ^

Error: template not found: template.html

How do I reference the packaged template file in index.js, so it uses the template in the package (the one at /usr/local/lib/node_modules/node-nunjucks/template.html) rather than looking for the template in my working directory?


Solution

  • The configure call is the one you're going to want to tweak. It tells getTemplate where to look for templates. It can take an array of values referring to multiple directories where it can find templates.

    Example:

    #!/usr/bin/env node
    var nunjucks = require('nunjucks');
    
    var env = nunjucks.configure(['./', './node_modules/node_nunjucks/']);
    var template = env.getTemplate('inner.html');
    var output = template.render({
      h1_copy: "Foo and Bar"
    });
    var template2 = env.getTemplate('outer.html');
    var output2 = template2.render({
      h1_copy: "Foo2 and Bar2"
    });
    
    
    console.log(output);
    console.log(output2);
    

    In this example inner.html resides in the root next to index.js, and outer.html resides in node_modules/node_nunjucks. It's just a relative path to the node_modules folder, but you can get more clever with aliases and whatnot depending on what tools you're using to build with.

    Hope that helps.