Stop gulp pipeline from executing when jshint fails - javascript

I am using gulp to run a developer web server and I want the following tasks to happen when a change occurs to a javascript file:
Lint javascript
if there are no errors, copy files to .tmp/
reload webpage
I've seen in other examples to use jshint.reporter('fail') as shown in the code below, to stop the rest of the pipeline.
var jshint = require('gulp-jshint'),
watch = require('gulp-watch');
watch('resources/js/src/**/*.js', function() {
util.log('Changes to js source files detected');
}).pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(jshint.reporter('fail'))
.pipe(gulp.dest('.tmp/js/src/'))
.pipe(connect.reload());
However when I do this it appears to always stop regardless of whether or not the lint was a success. So, how can I end the pipeline after a failed linting?

Not sure if this is the best solution, but it works:
var map = require('map-stream');
...
var copyAndReload = map(function (file, cb) {
if (file.jshint.success) {
gulp.src('resources/js/src/**/*.js')
.pipe(gulp.dest('.tmp/js/src/'))
.pipe(connect.reload());
}
});
watch('resources/js/src/**/*.js', function() {
util.log('Changes to js source files detected');
}).pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(copyAndReload);

what you can do is plugin plumber to exit in case of error
so pipe the plumber in the linting process
.pipe(plumber(_doExit))
here is how you defined _doExit
function _doExit() {
process.exit(1);
}

Related

I'm getting error in node using gulp and gulp-livereload

i downloaded livereload extension but it's not working, here's the error.
Error: watching ./src/*.css: watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)
var
gulp = require("gulp"),
livereload = require("gulp-livereload");
gulp.task("reload-css", function() {
gulp.src('./src/*.css')
.pipe(livereload());
});
gulp.task("default", function() {
livereload.listen();
gulp.watch('./src/*.css', ['reload-css']);
});
So what should i do now ?
it looks like you're using gulp 4, but write gulp 3 syntax. Try
gulp.watch('./src/*.css', gulp.series('reload-css'))
Check out the gulp 4 docs.
This post highlight the differences in the new gulp.

gulp.src from a separate file doesnt work

I am trying to write a gulpfile as follows :
var gulp = require('gulp');
// other dependencies go here ....
// source of files
var inputs = require('./asset_source.js');
// a simple task
gulp.task('css', function () {
gulp.src(inputs.css)
.pipe(debug())
.pipe(plumber())
.pipe(maps.init())
.pipe(concatCss('libs.css'))
.pipe(maps.write('../srcmaps'))
.pipe(plumber.stop())
.pipe(gulp.dest('assets/css'));
});
// the watcher
gulp.task('watch', function () {
gulp.watch('./asset_source.js', ['css']);
});
// default task
gulp.task('default', ['browser-sync', 'watch']);
And the source of assets (asset_source.js) file is something like this :
module.exports = {
css: [
'path/to/a/file.css',
'path/to/another/file.css',
.......
.......
],
js: [
'path/to/a/file.js',
'path/to/another/file.js',
.......
.......
]
};
Now I run the app with by just typing gulp in the console and it starts in a browser thanks to browsersync. I have all the css,scss,js assets listed in the asset_source.js file which is in the same directory as the gulpfile.js. What I want to achieve is if I append or remove a value to/from either of the arrays in asset_source.js, the concerned task should run while the gulp is already running. In this case css should be running on any change to asset_source.js with its updated content.
But instead it doesnt do so. Even if there is a change in the asset_source file, gulp uses the initial content and runs the task. However if run gulp css in a separate terminal, it works.
Please help me where I am going wrong or if it is even possible. Thanks.

Pipe vendor js files from Bower and own js files into unique stream in Gulp

I'd like to grab my vendor js files from bower dependencies, and, along with my own js files, pipe through some other tasks and concat them into one .js file. And then do the same for Sass files.
How could I achieve that? I tried this, but it doesn't work:
gulp.task('scripts', function () {
return gulp.src([
mainBowerFiles(gulpFilter('*.js')),
'app/js/*.js'
])
.pipe(uglify())
.pipe(concat('app.js'))
.pipe(gulp.dest('./dist/js'));
});
It throws this error:
TypeError: Arguments to path.resolve must be strings
But it works if I have this, for example:
gulp.src([
'app/js/etc.js',
'app/js/main.js'
])
..and in the following case, it throws a different error (but no error without uglify()):
gulp.src(mainBowerFiles(gulpFilter('*.js')))
error:
events.js:72
throw er; // Unhandled 'error' event
How do I better debug this? Should I separate vendor / own js files in different streams?
update
I'm working now with two streams, and merging them later on with event-stream, like this:
gulp.task('scripts', function () {
var jsFilter = gulpFilter('*.js');
var vendorFiles = gulp.src(mainBowerFiles()) // don't read
.pipe(jsFilter)
.pipe(concat('vendor.js'));
var appFiles = gulp.src('app/js/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(concat('app.js'));
return es.concat(vendorFiles, appFiles)
.pipe(uglify())
.pipe(concat('app.js'))
.pipe(gulp.dest('./dist/js'));
});
It works great, but I'm not able to handle the order of the files. Obviously I'd like that the vendor code come before my code at the destination's app.js, but that's doesn't happen. I created a thread about that here.
Solved it with gulp-event-stream and gulp-order. Intrigues me a little that gulp-order is trending downward at https://www.npmjs.org, though.
gulp.task('scripts', function () {
var jsFilter = gulpFilter('*.js');
var vendorFiles = gulp.src(mainBowerFiles())
.pipe(jsFilter)
.pipe(concat('vendor.js'));
var appFiles = gulp.src('app/js/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(concat('app.js'));
return eventStream.concat(vendorFiles, appFiles)
.pipe(order([
"vendor.js",
"app.js"
]))
.pipe(concat('app.js'))
.pipe(uglify())
.pipe(gulp.dest('./dist/js'));
});
mainBowerFiles() returns an array. gulp.src is expecting an array of strings, not nested arrays, which is likely the cause of the first problem. You could try the following instead:
gulp.src(mainBowerFiles(gulpFilter('*.js')).push('app/js/*.js'))
I'm not sure what's causing the unhandled error event, but you could try using gulp-debug to get more information.

gulp error handling for dependent task

Please find the content of the gulpfile.js as below.
The task uglify depends on the task jshint. Currently when I run gulp, both the tasks get executed, irrespective of the outcome of the jshint task. I don't want the uglify task to get executed when there are 'jshint' error(s).
In other words, when ever there are dependent tasks, I don't want the subsequent tasks to get executed, if there are error detected by the preceding task.
Is it possible in gulp?
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
gulp.task('jshint', function () {
return gulp.src(['assets/js/**/*.js'])
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter('jshint-stylish'));
});
gulp.task('uglify', ['jshint'], function() {
return gulp.src('assets/js/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('assets-min/js/'));
});
gulp.task('default', ['jshint', 'uglify']);
Please refer the below console output - not desired. Though there had been jshint error, the uglify task ran successfully.
I have also created a GitHub repository with the boilerplate code for the above mentioned.
Please find the same at #sarbbottam/gulp-workflow.
Console out of the undesired workflow
Console out of the expected workflow
For JSHint, there is a built-in reporter for this purpose, fail. If an error occurs, it will stop your gulp process.
You just have to redefine your task like :
gulp.task('jshint', function () {
return gulp.src(['assets/js/**/*.js'])
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter('jshint-stylish'))
.pipe(jshint.reporter('fail'))
})
With other tasks, you can add an error callback on it and exit the process to prevent subsequent tasks to run.
Here is an example with ngmin (cause uglify is hard to break, but it will be the same) :
function handleError (err) {
console.log(err.toString())
process.exit(-1)
}
gulp.task('min', function () {
return gulp.src(['assets/js/**/*.js'])
.pipe(ngmin())
.on('error', handleError)
})
To complement Aperçu's answer, if you don't want gulp to just exit (because you have watcher running) then you can do the following:
gulp.task('min', function(done) {
return gulp.src(['assets/js/**/*.js'])
.pipe(ngmin())
.on('error', done);
});
This will prevent the next task that depends on this one to run but your watchers will still be running.

Build script with Browserify creates an empty file

I have a simple build script that supposedly should pack all my js modules into a single file using browserify. I have the following code ( inspired from http://www.forbeslindesay.co.uk/post/46324645400/standalone-browserify-builds)
function _browserify(srcPath, distPath) {
var browserify = require('browserify');
var b = new browserify();
b.add(srcPath);
b.bundle().pipe(_fs.createWriteStream(distPath));
console.log(' '+ distPath +' built.');
}
But when I run it, I get a completely empty file. Any idea why?
okay, definitely spent waaaay too much of my evening on this, but this turns out to be an async issue. you're most likely getting an error in there somewhere, but grunt is killing off the process before the error callback has a chance to be called. grunt provides a nifty async method on each task's context that you have to use to let grunt know that this is an async task (and therefore needs to wait for everything to be finito). something like...
grunt.registerTask('build', function () {
var done = this.async();
browserify({ debug: true })
.add('./src/main.js')
.bundle()
.on('error', function (err) {
console.log(err);
})
.pipe(fs.createWriteStream('./target/bundle.js')
.on('end', done);
});

Categories