DEV Community

Andrew Nosenko
Andrew Nosenko

Posted on • Edited on

4 1

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:

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (3)

Collapse
 
ihack2712 profile image
James Bradlee

This will not work on Deno deploy btw

Collapse
 
noseratio profile image
Andrew Nosenko

That makes sense for security reasons, but it works locally or inside a docker container.

Collapse
 
ihack2712 profile image
James Bradlee

It indeed does, I do however like the idea a lot, and wish it was possible in Deploy (for other reasons than running untrusted code)

Image of Bright Data

Maintain Seamless Data Collection – No more rotating IPs or server bans.

Avoid detection with our dynamic IP solutions. Perfect for continuous data scraping without interruptions.

Avoid Detection

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay