Automation with Deno: a tiny text template processor in JavaScript

noseratio

Andrew Nosenko

Posted on June 4, 2021

Automation with Deno: a tiny text template processor in JavaScript

Basically, a three-liner:

const templateText = await Deno.readTextFile(Deno.args[0]);
const render = new Function("return `" + templateText + "`").bind(templateParams);
console.log(render());
Enter fullscreen mode Exit fullscreen mode

It uses interpolated JavaScript template strings (aka template literals) to process a generic text template file. For example:

# example of a YAML template
request:
  ip: ${ this.dateTime.client_ip }
  ip_time_zone: ${ this.dateTime.abbreviation }
  server_utc_time: ${ this.dateTime.utc_datetime }
  local_time: ${ new Date() }
Enter fullscreen mode Exit fullscreen mode

Here, this refers to the templateParams object we passed from the above Deno script. This text file is in fact just a multi-line template strings, with all the corresponding syntax rules you'd follow inside a JavaScript "backtick" string. Hey, it's even possible to use await inside `${...}` :)

What is this useful for?

I believe it can be useful for build automation, including certain CI/CD-related tasks.

Deno itself is a very self-cointained JavaScript/TypeScript runtime engine. It comes as a single executable file which can be used without any external dependencies. Yet it offers an extensive built-in API to deal with files, networking etc.

More so, any specific Deno version can be easily installed into a local folder without admin rights. E.g., to install Deno v1.10.3 on Windows with PowerShell:

# install Deno v1.10.3 into ./bin
$env:DENO_INSTALL = "$pwd"
$v="1.10.3"
iwr https://deno.land/x/install/install.ps1 -useb | iex
Enter fullscreen mode Exit fullscreen mode

Personally, I've never been comfortably fluent with Bash, PowerShell etc., so I find Deno very handy for quick, shell-like scripting with JavaScript. With Deno, I can quickly run a one-liner like this:

$ deno eval -p "await fetch('https://example.com').then(r => r.text()).then(t => t.match('example'))"
Enter fullscreen mode Exit fullscreen mode

Of course, Deno is much more capable than that, but that's outside the scope of this article.

An example of templating

This example is a bit contrived, but it illustrates the purpose. Here we make a simple fetch request to https://worldtimeapi.org/api/ip and save the results, using the above YAML template:

// deno run --allow-read --allow-net nascentTextGen.js sample.yaml.template 

const templateParams = {
  dateTime: await fetch("https://worldtimeapi.org/api/ip").then(r => r.json()),
  args: Deno.args
};

const templateText = await Deno.readTextFile(Deno.args[0]);
const render = new Function("return `" + templateText + "`").bind(templateParams);
console.log(render());
Enter fullscreen mode Exit fullscreen mode

Output:

# example of a YAML template
request:
  ip: a.b.c.d
  ip_time_zone: AEST
  server_utc_time: 2021-06-04T01:32:56.595373+00:00
  local_time: Fri Jun 04 2021 11:32:55 GMT+1000 (Australian Eastern Standard Time)
Enter fullscreen mode Exit fullscreen mode

Code

Clone or fork this simpe demo project. Then:

  • to install Deno (PowerShell):
pwsh -f _installDeno.ps1
Enter fullscreen mode Exit fullscreen mode
  • to run the sample:
pwsh -f _demo.ps1
Enter fullscreen mode Exit fullscreen mode

Some more advanced general-purpose templating tools

This little project was inspired by a search for a JavaScript-based general-purpose text templating tool.

Of course, this approach may only be useful for simple, "logic-less" templates. If you need branching and looping constructs like if, for, while or function, there are a lot more powerful and actively maintained alternatives out there:

đź’– đź’Ş đź™… đźš©
noseratio
Andrew Nosenko

Posted on June 4, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related