0

Right now I'm trying to use Node readstreams and stream transforms to edit my HTML data before sending it to the client. Yes, I'm aware templating engines exist, this is the method I'm working with right now though. The code I'm using looks like this:

const express = require('express')
const app = express()
const port = 8080
const fs = require('fs')
const Transform = require("stream").Transform
const parser = new Transform()
const newLineStream = require("new-line")

parser._transform = function(data, encoding, done) {
    const str = data.toString().replace('</body>', `<script>var questions = ${JSON.stringify(require('./questions.json'))};</script></body>`)
    this.push(str)
    done()
}

app.get('/', (req, res) => {
    console.log('Homepage served')
    res.write('<!-- Begin stream -->\n');
    let stream = fs.createReadStream('./index.html')
    stream.pipe(newLineStream())
    .pipe(parser)
    .on('end', () => {
        res.write('\n<!-- End stream -->')
    }).pipe(res)
})

This is just a rough draft to try and get this method working. Right now, the issue I'm running into is that the first time I load my webpage everything works fine, but every time after that the html I'm given looks like this:

<!-- Begin stream -->
<html>
  <head></head>
  <body></body>
</html>

It seems like the stream is getting hung up in the middle, because most of the data is never transmitted and the stream is never ended. Another thing I notice in the console is a warning after 10 reloads that there are 11 event listeners on [Transform] and there's a possible memory leak. I've tried clearing all event listeners on both the readstream and the parser once the readstream ends, but that didn't solve anything. Is there a way to change my code to fix this issue?

Original StackOverflow post that this method came from

Colin Hanes
  • 106
  • 2
  • 12

1 Answers1

0

The issue here was using a single parser and ._transform() instead of creating a new transform every time the app received a request. Putting const parser = ... and parser._transform = ... inside the app.get() fixed everything.

Colin Hanes
  • 106
  • 2
  • 12