node.jsthrough2

NodeJS: Actual native substitute for "through2" for intervention to steams in 2021


From the through2 documentation:

Do you need this?

Since Node.js introduced Simplified Stream Construction, many uses of through2 have become redundant. Consider whether you really need to use through2 or just want to use the 'readable-stream' package, or the core 'stream' package (which is derived from 'readable-stream').

If I understand correctly, now (from 2021) we can intervene to the streams without third-party libraries. I did not found how to do same thing as through2 in Stream documentation.

// ...
  .pipe(through2(function (file, encoding, callback) {
    // Do something with file ...
    callback(null, file)
   }))

// ↑ Possible to reach the same effect natively (with core packages)?

I suppose, for 2021 there must be some method supporting async/await syntax:

// ...
  .pipe(newFeatureOfModernNodeJS(async function (file) {

    await doSomethingAsyncWithFile(file);
    // on fail - same effect as "callback(new Error('...'))" of trough2

    return file; // same effect as "callback(null, file)" of trough2

    // or
    return null; // same effect as `callback()` of trough2
   }))

// ↑ Possible to reach the same effect natively (with core packages)?

Solution

  • What you are looking for is likely a Transform stream, something implemented by the native 'stream' library included with Node.js. I don't know that there is an async compatible version yet, but there is most definitely a callback based one. You need to inherit from the native Transform stream and implement your function.

    Here's the boilerplate I like to use:

    const Transform = require('stream').Transform;
    const util      = require('util');
    
    function TransformStream(transformFunction) {
      // Set the objectMode flag here if you're planning to iterate through a set of objects rather than bytes
      Transform.call(this, { objectMode: true });
      this.transformFunction = transformFunction;
    }
    
    util.inherits(TransformStream, Transform);
    
    TransformStream.prototype._transform = function(obj, enc, done) {
      return this.transformFunction(this, obj, done);
    };
    
    module.exports = TransformStream;
    

    Now you can use this in places you would use through:

    const TransformStream = require('path/to/myTransformStream.js');
    //...
    .pipe(new TransformStream((function (file, encoding, callback) {
        // Do something with file ...
        callback(null, file)
     }))