How can I input and output multiple files with gulp and browserify - gulp

I'm sure there's a way to do this, but I couldn't find it. What I want is to pass multiple files into browserify and output multiple files - this is useful for a case where a site has multiple SPA's, with each having its own requires.
Say I have app1.js, app2.js, etc, with each loading in different pages and having independent require('..') statements. I'm looking for a task that does something like this:
gulp.task('browserify', function() {
return
gulp.src('src/**/*.js')
.pipe(browserify) //
.pipe(gulp.dest('dist'));
});
Any idea what's a simple way to accomplish this? thanks.

I stumbled upon this problem actually earlier this week. The problem of "creating multiple bundles". This should work:
var gulp = require('gulp'),
source = require('vinyl-source-stream'),
browserify = require('browserify'),
es = require('event-stream');
gulp.task('default', function() {
// Your main files
var files = [
'./app/main-a.js',
'./app/main-b.js'
];
// Create a stream array
var tasks = files.map(function(entry) {
return browserify({ entries: [entry] })
.bundle()
.pipe(source(entry))
.pipe(gulp.dest('./dist'));
});
return es.merge.apply(null, tasks);
});
Please do not use the gulp-browserify plugin, as it's blacklisted by now. Use browserify itself instead.
Same with Globs:
gulp.task('withglob', function() {
return glob('./app/main-**.js', function(err, files) {
var tasks = files.map(function(entry) {
return browserify({ entries: [entry] })
.bundle()
.pipe(source(entry))
.pipe(rename({
extname: '.bundle.js'
}))
.pipe(gulp.dest('./dist'));
});
return es.merge.apply(null, tasks);
})
});
Btw.: That's the reason

Related

gulp task throwing error on second time run

I have two folders both of which contain some html template files. I need to minify these files to separate folders.
folder structure
|src
|--clientTemplates
|----abc.html
|----xyz.html
|--serverTemplates
|----abc.html
|----xyz.html
required destination folder
|dist
|--client
|----abc.html
|----xyz.html
|--server
|----abc.html
|----xyz.html
following is my gulpfile where I have my tasks defined for the
var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin');
var replace = require('gulp-replace');
var del = require('del');
var minOptions = {
collapseWhitespace: true,
minifyJS: { output: { quote_style: 1 } },
minifyCSS: true
};
gulp.task('clean', function(done) {
del(['dist'], done());
});
gulp.task('minify:serverTemplates', function() {
return gulp
.src('src/serverTemplates/*.html')
.pipe(htmlmin(minOptions))
.pipe(replace('\\', '\\\\'))
.pipe(replace('"', '\\"'))
.pipe(gulp.dest('dist/server'));
});
gulp.task('minify:clientTemplates', function() {
return gulp
.src('src/clientTemplates/*.html')
.pipe(htmlmin(minOptions))
.pipe(gulp.dest('dist/client'));
});
gulp.task(
'default',
gulp.series('clean', 'minify:serverTemplates', 'minify:clientTemplates', function inSeries(done) {
done();
})
);
when I run the gulp command it works fine for the first time, but throws errors on alternate runs.
running gulp command first time
running gulp command second time
can't figure out what exactly is wrong there.
Also is there a way to run the two minification task parallel once the clean task has finished?
thanks for the help.
The callback you pass to del is wrong. Just return the promise:
gulp.task('clean', function() {
return del(['dist']);
});
As for running the minification tasks in parallel, use gulp.parallel:
gulp.task(
'default',
gulp.series(
'clean',
gulp.parallel('minify:serverTemplates', 'minify:clientTemplates')
)
);

Gulp copies file but it is empty

I'm having a strange problem. I'm using gulp to compile a react app and am having it copy index.html to the appropriate web directory. When I first run gulp, all runs as expected, but when the file changes and the watch task is run, gulp copies an empty version of the file to the web directory. Does anyone know why this might be happening? Here is my gulpfile.js:
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
var livereload = require('gulp-livereload');
gulp.task('livereload', function() {
console.log('reloading');
livereload();
});
gulp.task('copyindextodist', function() {
gulp.src('app/index.html')
.pipe(gulp.dest('dist'));
});
gulp.task('compilejs', function() {
browserify({
entries: 'app/index.js',
extensions: ['.js'],
debug: true
})
.transform('babelify', {presets: ['es2015', 'react']})
.bundle()
.pipe(source('app.js'))
.pipe(gulp.dest('dist'));
});
gulp.task('publishapp', function() {
gulp.src('dist/*.*')
.pipe(gulp.dest('../public'));
});
gulp.task('copypaste', function() {
gulp.src('app/index.html')
.pipe(gulp.dest('../public'));
});
gulp.task('watch', function() {
livereload.listen();
gulp.watch('app/index.html', ['copyindextodist']);
gulp.watch('dist/index.html', ['publishapp']);
gulp.watch('app/index.js', ['compilejs']);
gulp.watch('dist/app.js', ['publishapp']);
});
gulp.task('default', ['copyindextodist', 'compilejs', 'publishapp', 'watch']);
I had the same problem until I defined the dependencies correctly. You can define which tasks should be completed, before the current task starts:
gulp.task('compress', ['copy'], function() {
//.... your job
});
This means that the compress task will wait for the copy task to be finished. If you don't do that, you might end up with empty/truncated files and other strange results.
Just take care that your copy tasks return a stream object.
gulp.task('copy', function() {
// "return" is the important part ;-)
return gulp.src(['filepath/**/*'])
.pipe(gulp.dest('lib/newpath'))
});
If you have multiple copy commands running in your task this is tricky, but there is an extension for this:
var gulp = require('gulp');
var merge = require('merge-stream');
gulp.task('copy', function() {
var allStreams = [
gulp.src(['node_modules/bootstrap/dist/**/*'])
.pipe(gulp.dest('lib/bootstrap')),
gulp.src(['node_modules/jquery/dist/**/*'])
.pipe(gulp.dest('lib/jquery')),
];
return merge.apply(this, allStreams);
});
gulp.task('nextTask', ['copy'], function() {
// this task formerly produced empty files, but now
// has a valid dependency on the copy stream and
// thus has all files available when processed.
});

How to set gulp.dest() in same directory as pipe inputs?

I need all the found images in each of the directories to be optimized and recorded into them without setting the path to the each folder separately. I don't understand how to make that.
var gulp = require('gulp');
var imageminJpegtran = require('imagemin-jpegtran');
gulp.task('optimizeJpg', function () {
return gulp.src('./images/**/**/*.jpg')
.pipe(imageminJpegtran({ progressive: true })())
.pipe(gulp.dest('./'));
});
Here are two answers.
First: It is longer, less flexible and needs additional modules, but it works 20% faster and gives you logs for every folder.
var merge = require('merge-stream');
var folders =
[
"./pictures/news/",
"./pictures/product/original/",
"./pictures/product/big/",
"./pictures/product/middle/",
"./pictures/product/xsmall/",
...
];
gulp.task('optimizeImgs', function () {
var tasks = folders.map(function (element) {
return gulp.src(element + '*')
.pipe(sometingToDo())
.pipe(gulp.dest(element));
});
return merge(tasks);
});
Second solution: It's flexible and elegant, but slower. I prefer it.
return gulp.src('./pictures/**/*')
.pipe(somethingToDo())
.pipe(gulp.dest(function (file) {
return file.base;
}));
Here you go:
gulp.task('optimizeJpg', function () {
return gulp.src('./images/**/**/*.jpg')
.pipe(imageminJpegtran({ progressive: true })())
.pipe(gulp.dest('./images/'));
});
Gulp takes everything that's a wildcard or a globstar into its virtual file name. So all the parts you know you want to select (like ./images/) have to be in the destination directory.
You can use the base parameter:
gulp.task('uglify', function () {
return gulp.src('./dist/**/*.js', { base: "." })
.pipe(uglify())
.pipe(gulp.dest('./'));
});

Gulp-rev-collector doesn't work properly

I don't understand what's wrong with this code. When I run it for the first time, rev_collector doesn't work. I mean: 'rev' and 'clean' works great, but css file name in index http didn't change ('rev_collector').
BUT it works properly when I start it again.
var gulp = require('gulp'),
less = require('gulp-less'),
rev_append = require('gulp-rev-append'),
rev = require('gulp-rev'),
revCollector = require('gulp-rev-collector'),
gutil = require('gulp-util'),
rimraf = require('rimraf'),
revOutdated = require('gulp-rev-outdated'),
path = require('path'),
through = require('through2');
gulp.task('rev', function(){
gulp.src('./src/less/*.less')
.pipe(less())
.pipe(rev())
.pipe(gulp.dest('./www/css/'))
.pipe(rev.manifest())
.pipe(gulp.dest('./src/manifest/'));
});
gulp.task('rev_collector', ['rev'], function(){
return gulp.src(['./src/manifest/**/*.json', './www/index.html'])
.pipe(revCollector({
replaceReved: true
}))
.pipe(gulp.dest('./www/'));
});
function cleaner() {
return through.obj(function(file, enc, cb){
rimraf( path.resolve( (file.cwd || process.cwd()), file.path), function (err) {
if (err) {
this.emit('error', new gutil.PluginError('Cleanup old files', err));
}
this.push(file);
cb();
}.bind(this));
});
}
gulp.task('clean', ['rev_collector'], function() {
gulp.src( ['./www/**/*.*'], {read: false})
.pipe( revOutdated(1) ) // leave 2 latest asset file for every file name prefix.
.pipe( cleaner() );
return;
});
gulp.task('rev_all', ['rev', 'rev_collector', 'clean']);
Today, I met the same problem.
After I got nothing from this page, I searched a lot.
I fount my problom came from the order the files loaded.
So I use a new plugin:
var runSequence = require('run-sequence');
then, I rewrite the load code:
gulp.task('default',['build']);
gulp.task('build', function (done) {
runSequence(
['clean'],
['images'],
['statcstyles', 'staticjs'],
['scripts'],
['styles'],
['html'],
done);
});
The code make sure that revCollector will always loaded after manifest create.
Then my problem solved.
I hope it helps you.

Sequencing tasks with gulp

I'm a bit stumped with gulp. Based on the docs, in order to get sequential execution, I should be returning the stream from my tasks, so i tried to do the below for my gulpfile. But as best I can tell, there's a race condition. Half the time I get ENOENT, lstat errors, the other half it succeeds, but my deployDir has weird folder names and missing files all over.. Am I missing something? Is there a trick to this?
var gulp = require('gulp'),
filter = require('gulp-filter'),
mainBowerFiles = require('main-bower-files'),
del = require('del'),
inject = require("gulp-inject"),
uglify = require('gulp-uglifyjs');
var config = {
bowerDir: 'src/main/html/bower_components',
cssDir: 'src/main/html/css/lib',
fontsDir: 'src/main/html/fonts/lib',
imgDir: 'src/main/html/img/lib',
jsDir: 'src/main/html/js/lib',
deployDir: 'src/main/resources/html'
};
gulp.task('default', ['clean', 'bowerdeps', 'dev']);
gulp.task('clean', function() {
return del([
config.cssDir,
config.fontsDir,
config.jsDir,
config.deployDir
]);
});
gulp.task('dev', function() {
return gulp
.src(['src/main/html/**', '!src/main/html/{bower_components,bower_components/**}'])
.pipe(gulp.dest(config.deployDir));
});
gulp.task('bowerdeps', function() {
var mainFiles = mainBowerFiles();
if(!mainFiles.length) return; // No files found
var jsFilter = filterByRegex('.js$');
var cssFilter = filterByRegex('.css$');
var fontFilter = filterByRegex('.eot$|.svg$|.ttf$|.woff$');
return gulp
.src(mainFiles)
.pipe(jsFilter)
.pipe(gulp.dest(config.jsDir))
.pipe(jsFilter.restore())
.pipe(cssFilter)
.pipe(gulp.dest(config.cssDir))
.pipe(cssFilter.restore())
.pipe(fontFilter)
.pipe(gulp.dest(config.fontsDir));
});
// Utility Functions
var filterByRegex = function(regex){
return filter(function(file){
return file.path.match(new RegExp(regex));
});
};
Dependencies run always parallel: ['clean', 'bowerdeps', 'dev'].
https://github.com/gulpjs/gulp/blob/master/docs/recipes/running-tasks-in-series.md
You can use run-sequence for sequencing tasks.
Other thing: del doesn't return a stream. Use callback instead:
gulp.task('clean', function(cb) {
del([
config.cssDir,
config.fontsDir,
config.jsDir,
config.deployDir
], cb);
});