Keeping Node Scripts Alive

Published 27 January, 2019

2 minute read

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.

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.

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.