Gulp: Passing through to a stream depending on the contents of a stream - node.js

I have the following simplified gulp task:
gulp.src(...)
.pipe(stuff())
.pipe(moreStuff())
.pipe(imagemin())
.pipe(yetMoreStuff());
I only want the imagemin stream to be called when the file path contains "xyz", but I want the other three streams to always be called.
Called gulp.src() in another place is not appropriate—this example is massively simplified, and duplicating everything would be messy as hell.
So far, I've got this far:
var through = require('through2');
gulp.src(...)
.pipe(stuff())
.pipe(moreStuff())
.pipe(through.obj(function (file, enc, cb) {
console.log(file.path.indexOf('hero') !== -1);
// file has a pipe method but what do I do?!
}))
.pipe(yetMoreStuff());
Doesn't do anything. I don't know vinyl / streams well enough to be able to do this by myself :(
How do I do this?

It sounds like gulp-filter might be what you're looking for.
var Filter = require('gulp-filter');
var filter = Filter(['**xyz**']);
gulp.src(...)
.pipe(stuff())
.pipe(moreStuff())
.pipe(filter)
.pipe(imagemin())
.pipe(filter.restore())
.pipe(yetMoreStuff());

Related

Redirect Readable object stdout process to file in node

I use an NPM library to parse markdown to HTML like this:
var Markdown = require('markdown-to-html').Markdown;
var md = new Markdown();
...
md.render('./test', opts, function(err) {
md.pipe(process.stdout)
});
This outputs the result to my terminal as intended.
However, I need the result inside the execution of my node program. I thought about writing the output stream to file and then reading it in at a later time but I can't figure out a way to write the output to a file instead.
I tried to play around var file = fs.createWriteStream('./test.html'); but the node.js streams rather give me headaches than results.
I've also looked into the library's repo and Markdown inherits from Readable via util like this:
var util = require('util');
var Readable = require('stream').Readable;
util.inherits(Markdown, Readable);
Any resources or advice would be highly appreciated. (I would also take another library for parsing the markdown, but this gave me the best results so far)
Actually creating a writable file-stream and piping the markdown to this stream should work just fine. Try it with:
const writeStream = fs.createWriteStream('./output.html');
md.render('./test', opts, function(err) {
md.pipe(writeStream)
});
// in case of errors you should handle them
writeStream.on('error', function (err) {
console.log(err);
});

What does calling a function inside pipe, return in gulp?

I know the pipe function in NodeJs. A readable stream calls the pipe function with the first argument being the writable stream. Something like:
readable.pipe(fs.createWriteStream('file.txt'));
This will pipe all the output to file.txt. But I have not understood this in context of gulp.
What does a call to a pipe function like:
gulp.src('./assets/styles/**/*.scss')
.pipe(sass());
mean? Here is the full snippet:
var gulp = require('gulp');
var gutil = require('gulp-util');
// require sass
var sass = require('gulp-ruby-sass');
gulp.task('sass', function () {
gulp.src('./assets/styles/**/*.scss')
.pipe(sass())
.pipe(gulp.dest('./assets/styles'));
});
gulp.task('default', ['sass']);
I understand the dest part. But do not understand the pipe(sass()) part. What does it do? What stream does each of these functions return?
Note: I have taken the sample example from a blog
The pipe in gulp is the exact same as the pipe in Node.
This flow streams the sources files from .src() and creates a new stream a pipes it through the sass plugin - the sass plugin will then process all sass files into css and concat them to the destination path as a new stream.

Creating multiple files from Vinyl stream with Through2

I've been trying to figure this out by myself, but had no success yet. I don't even know how to start researching for this (though I've tried some Google searchs already, to no avail), so I decided to ask this question here.
Is it possible to return multiple Vinyl files from a Through2 Object Stream?
My use case is this: I receive an HTML file via stream. I want to isolate two different sections of the files (using jQuery) and return them in two separate HTML files. I can do it with a single section (and a single resulting HTML file), but I have absolutely no idea on how I would do generate two different files.
Can anyone give me a hand here?
Thanks in advance.
The basic approach is something like this:
Create as many output files from your input file as you need using the clone() function.
Modify the .contents property of each file depending on what you want to do. Don't forget that this is a Buffer, not a String.
Modify the .path property of each file so your files don't overwrite each other. This is an absolute path so use something like path.parse() and path.join() to make things easier.
Call this.push() from within the through2 transform function for every file you have created.
Here's a quick example that splits a file test.txt into two equally large files test1.txt and test2.txt:
var gulp = require('gulp');
var through = require('through2').obj;
var path = require('path');
gulp.task('default', function () {
return gulp.src('test.txt')
.pipe(through(function(file, enc, cb) {
var c = file.contents.toString();
var f = path.parse(file.path);
var file1 = file.clone();
var file2 = file.clone();
file1.contents = new Buffer(c.substring(0, c.length / 2));
file2.contents = new Buffer(c.substring(c.length / 2));
file1.path = path.join(f.dir, f.name + '1' + f.ext);
file2.path = path.join(f.dir, f.name + '2' + f.ext);
this.push(file1);
this.push(file2);
cb();
}))
.pipe(gulp.dest('out'));
});

Nodejs fs.FSWatcher

I am using fs.watch() to watch changes in a directory. My code looks like this:
watchDirectory(){
var watcher = fs.watch(this.directory, (event, filename) => {});
return watcher;
}
From Nodejs documentation: fs.FSWatcher Objects returned from fs.watch() are of this type. However when I try to do something like this:
console.log(watcher instanceof fs.FSWatcher) //output fs.FSWatcher - undefined
Then I tried this:
console.log(watcher.constructor.name); //output FSWatcher
The question is where I can find the class of FSWatcher if it does not exist in fs.FSWatcher?
Any help will be appreciated!
FSWatcher is a simple event emitter with convenient start()/close() methods. You can read the code here. As you can see, it's not exposed via fs. Are you trying to do something like this?
var fs = require('fs');
// instantiate the watcher
var watcher = fs.watch(__dirname);
// track changes later
watcher.on('change', function name(event, filename) {
console.log(event);
console.log(filename);
});

How to replace in stream using Gulp?

I try to switch from Grunt to Gulp and I have an issue:
I read two streams from two files
var fileStream = gulp.src(file);
var injectionStream = gulp.src(injection)
.pipe(replace('#class-name#', argv.cname));
If my console argument "--remove" is absent I have no problem to concatenate these streams
.pipe(concat('animation.styl'))
.pipe(gulp.dest('./dist'))
However when '--remove' is true I want to delete injection, in other words, subtract injectionStream from fileStream.
I tried:
var es = require('event-stream');
es.replace()
var replace = require('gulp-replace');
It works with strings, but I cannot succeed with streams read from files. Can anybody give me a small hint?
And maybe it is an incorrect tool for generation task and I should stay with Grunt and\or other tools like yo,etc?
Thank you for your time!
Nice work :) Looks like gulp-replace might be an easier way for folk coming here from google..
var replace = require('gulp-replace');
gulp.task('templates', function(){
gulp.src(['file.txt'])
.pipe(replace(/foo(.{3})/g, '$1foo'))
.pipe(gulp.dest('build/file.txt'));
});
I finally found the solution!
fs.readFile(injectionFile, 'utf8', function (err, injStr) {
injStr = injStr.replace(/svv/g, cname);
fileStream
.pipe(gulpif(rm!=true,injectString.append(injStr),replace(injStr,'')))
.pipe(concat(initialFile))
.pipe(gulp.dest(animation))
...
It took a while, but I AM HAPPY it's over.
Thank you

Resources