I wrote this to go in my simple static site generator. it takes any plaintext file (but meant for html) and injects the specified file contents and other data at matching tags. This is my first "big" JavaScript project, and most of my knowledge has come from several-year-old posts on StackExchange, YouTube, and Medium, so I cannot guarantee that I have followed modern conventions.

I have included test code, and It should run as-is however it does require a single index.html file in the same dir to test ```fileInject()```.

```
const fs = require('fs');

var test = `<!-- template:one -->
<!-- template:two -->
<!-- template:three -->
<!-- template:index.html -->
<!-- template:five -->`;

var data = [['one','apple'],['three','orange'],['five','banana']];

// Grab tags from template files. Does not return duplicates.
const getTags = (template) => {
    const regex = /\<\!\-\- template:(?<label>(?:(?!\<\!\-\-).)+) \-\-\>/g;
    var match, matches = [];
    while(match = regex.exec(template)) {
        if(!matches.includes(match)) {
            matches.push([match.groups.label, match[0]]);
        }
    }
    return matches;
}

// Inject data at matching tags. Tag object format: [['key','value'], ...]
// Silent on failure, but mostly because I do not know how to check if template.replace() succeeds or fails. 
const dataInject = (template, tags) => {
    for(let tag of tags) {
        const regex = new RegExp(`\<\!\-\- template:${tag[0]} \-\-\>`, 'g');
        template = template.replace(regex, tag[1]);
    }
    return template;
}

// Find and inject file contents at matching tags.
// Logs errors on failure.
const fileInject = (template) => {
    const tags = getTags(template);
    for(let tag of tags) {
        try{
            fs.accessSync(tag[0]);
            const partial = fs.readFileSync(tag[0]).toString();
            template = template.replace(tag[1], partial);
        } catch(e) { console.log(`error injecting file '${tag[0]}'`) }
    }
    return template;
}

// Individual tests
//console.log(dataInject(test, data));
//console.log(fileInject(test));

//combined tests. Both work, however (if combined) dataInject() should be called first as fileInject() will finish quicker encounter fewer failures.
//console.log(dataInject(fileInject(test), data));
console.log(fileInject(dataInject(test, data)));