On Keeping Node Scripts Alive

I recently had a need to build a kind of one-off templating system at work. I waffled around a lot when it came to the templating language. I bounced between EJS, Handlebars, Edge, and Nunjucks. Because I'm super familiar with Laravel Blade, I initially decided on Edge, but Edge's documentation is pretty awful, and that just feels like a bad sign. Nunjucks, on the other hand, has fantastic documentation and pretty much all the features I want. I like Blade/Edge-style components more than Nunjucks' macros, but I'm willing to make the trade-off. My needs for this templating system are limited mostly to includes and layouts, with moderate usage of components/macros.

After that, I need a way to auto-render as I'm developing. I started off with nodemon, but I noticed a weird thing with using it as a module.

const nodemon = require("nodemon");

  script: "app.js",
  ext: "njk",

nodemon.on("restart", (files) => console.log(files));

Nodemon has a nice event system that gives you info about what files triggered the update, but you have to pass a script path into the config object. Since my project just needs to run a function once per file save, not an ongoing process, it felt weird passing a script it that didn't need to get run. It worked, but felt weird.

After nodemon, I landed on chokidar. Chokidar is a simpler file watcher. It lets you do this.

const path = require("path");
const builder = require("./app.js");

const watcher = require("chokidar")
  .on("ready", () => console.log("Watching for changes..."))
  .on("change", (filepath) => {
    console.log(`${filepath} updated`);
    const data = path.parse(filepath);

It's a bit more direct and requires a little bit more care in how you setup the output from scripts (because chokidar seems to eat the output from child processes).

Lastly, I just include a call out to BrowserSync to make hot reloading possible. All in all, not a terrible setup. I'd normally be using Nuxt for page generation, but sometimes you have to deal with other peoples' terrible code.

Update: like a hour after writing the original post

Turns out, there's a Nunjucks CLI project. It does pretty much everything I hand-coded already. Run it like this:

nunjucks '**/*.njk' -p templates -o dist data.json

Processes all .njk files, with templates as the src directory, outputing to dist, and all the data that needs to get passed to render() is in data.json. I really should've known better. I guess though, while I did waste a lot time figuring out some new things in Node.js, I learned a lot about Node and its ecosystem at the same time.