5

This question would apply to any text file but as I want to use it for HTML replacements I will use HTML files for examples. I have looked at things like gulp inject and replace on npm but neither seamed to do quite what i needed.

I would like to have some placeholder text that references another file. when run through this replacement function the placeholdler text is replaced by the contents of the file.

main.html

<script><replace src="./other.js" /></script>

other.js

console.log("Hello, world!");

After the transformation the output file should be.

<script>console.log("Hello, world!")</script>

I have got to the following but don't know how to make it work with file streams in node.

var REGEX = /<replace src="(.+)" \/>/;

function replace(file){
  match = file.match(REGEX);
  var placeholder = match[0];
  if (placeholder) {
    return file.replace(placeholder, match[1].toUpperCase());
    // toUpperCase is just an example and instead should lookup a file for contents
  }
}

2 Answers 2

6

If your files are reasonable in size, you can avoid using streams and go with a custom replacer for string.replace():

var fs = require('fs');

function replace(path) {
    var REGEX = /<replace src="(.+)" \/>/g;
    // load the html file
    var fileContent = fs.readFileSync(path, 'utf8');

    // replacePath is your match[1]
    fileContent = fileContent.replace(REGEX, function replacer(match, replacePath) {
        // load and return the replacement file
        return fs.readFileSync(replacePath, 'utf8');
    });

    // this will overwrite the original html file, change the path for test
    fs.writeFileSync(path, fileContent);
}

replace('./main.html');

Using streams

var es = require('event-stream');

function replaceWithStreams(path) {
    var REGEX = /<replace src="(.+)" \/>/g;
    fs.createReadStream(path, 'utf8')
        .pipe(es.split()) // split the input file into lines
        .pipe(es.map(function (line, next) {
            line = line.replace(REGEX, function replacer(match, replacePath) {
                // better to keep a readFileSync here for clarity
                return fs.readFileSync(replacePath, 'utf8'); 
            });
            next(null, line);
        })).pipe(fs.createWriteStream(path)); // change path if needed
}

replaceWithStreams('./main.html');
Sign up to request clarification or add additional context in comments.

1 Comment

What if my included files are rather large... How can I change return fs.readFileSync(replacePath, 'utf8'); to take a stream instead? Is that even possible?
1

You can try this: https://gist.github.com/thebergamo/5ee9f589757ee904f882

Basically you will read your index.html, find the replace tag, read the content in the file and replace to the content in your other file.

And this snippet is promisified to help you to treat exceptions =D

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.