Gulp watch less and error? - gulp

I am using gulp for creating some css from less and have watch function. Everything working ok when there is no errors in less files, watch is calling less function and compile css. But when i have errors in less files, watch just breaks say where is error stop. When i fix error in less file, watch does not work anymore. I have to start it again, is it possible to see if there is error and just continue watching for compiling, here is my gulp.js
// Less to CSS task
var parentPath = './content/css/';
var sourceLess = parentPath;
var targetCss = parentPath;
gulp.task('less', function () {
return gulp.src([sourceLess + 'styles.less'])
.pipe(less({ compress: true }).on('error', gutil.log))
.pipe(autoprefixer('last 10 versions', 'ie 9'))
.pipe(minifyCSS({ keepBreaks: false }))
.pipe(gulp.dest(targetCss))
.pipe(notify('Less Compiled, Prefixed and Minified'));
});
gulp.task('watch', function () {
gulp.watch([sourceLess + 'styles.less'], ['less']); // Watch all the .less files, then run the less task
});

In gulp-less plugin documentation says that it doesn't have a built-in way to fail the task and keep the watcher active. But it says that you can't do it with stream-combiner2.
You can see the example here taked from the official gulp github repo.

Related

gulp stops server on error even with jshint included in gulpfile.js

I don't know why the server still stops whenever there's an error in my js files even though I have jshint in my gulpfile. I installed jshint and included it in my project because it reports errors in js files, but it's still failing. How can I fix this?
gulp.task('scripts', () => {
return gulp.src('assets/js/src/*.js')
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish', {beep: true}))
.pipe(concat('main.js'))
.pipe(gulp.dest('assets/js/build/'))
.pipe(uglify())
.pipe(gulp.dest('assets/js/'))
.pipe(browserSync.stream({stream: true}));
});
gulp-jshint does what you says it does: it reports errors in JavaScript files. Nothing more, nothing less. It doesn't prevent defective JavaScript files from reaching later pipe stages like uglify() (which throws up and thus stops your server if there's any error in a JavaScript file).
If you want to prevent defective JavaScript files from wrecking your server, you need to put all the jshint stuff into it's own task and make sure that task fails when any JavaScript file has an error:
gulp.task('jshint', () => {
return gulp.src('assets/js/src/*.js')
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish', {beep: true}))
.pipe(jshint.reporter('fail'))
});
Then you need to make your scripts task depend on that jshint task:
gulp.task('scripts', ['jshint'], () => {
return gulp.src('assets/js/src/*.js')
.pipe(concat('main.js'))
.pipe(gulp.dest('assets/js/build/'))
.pipe(uglify())
.pipe(gulp.dest('assets/js/'))
.pipe(browserSync.stream({stream: true}));
});
Now your scripts task will only run when the jshint task was successful. If any JavaScript file was defective jshint will output the error to the console while your server continues to run using the last good version of your JavaScript.
The simplest fix would be to use gulp-plumber to handle the error a little more gracefully:
var plumber = require("gulp-plumber");
gulp.task('scripts', () => {
return gulp.src('assets/js/src/*.js')
.pipe(plumber())
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish', {beep: true}))
.pipe(concat('main.js'))
.pipe(gulp.dest('assets/js/build/'))
.pipe(uglify())
.pipe(gulp.dest('assets/js/'))
.pipe(browserSync.stream({stream: true}));
});
Personally, I don't like that solution because it will prevent your minified file from being updated. Here's what I would recommend:
var jshintSuccess = function (file) {
return file.jshint.success;
}
gulp.task('scripts', () => {
return gulp.src('assets/js/src/*.js')
.pipe(sourcemaps.init())
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish', {
beep: true
}))
.pipe(gulpif(jshintSuccess, uglify()))
.pipe(concat('main.js'))
.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('assets/js/'))
.pipe(browserSync.stream({
stream: true
}));
});
First, notice that I'm not writing to multiple destinations. Instead, I'm using sourcemaps so that you don't need unminified code. Second, I'm using gulp-if to conditionally pipe your code through uglify based on the results of jshint. Code with errors will bypass uglify so that it still makes it into to your destination file.
Now, you can inspect and debug it with the developer tools.
Note: I recommend this for local development only. I wouldn't connect this to a continuous integration pipeline because you'll only want good code to make it into production. Either set up a different task for that or add another gulp-if condition to prevent broken code from building based on environment variables.

Confused with combining gulp and webpack with watch

I'm trying to create a gulpfile that allows me to compile scss and js files.
Calling webpack from a gulp task seems to work as expected (simply followed the webpack-stream intro.
However, I'm failing setting up watching for files. It's working as expected for scss files, but not for webpack compilation. It occurs once at launch, block the console, but does not recompile files.
Here is my gulpfile:
'use strict';
var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var webpackConfig = require('./webpack.config.js');
var webpack = require('webpack-stream');
gulp.task('default', function () {
// place code for your default task here
});
gulp.task('watch', ['sass:watch','webpack:watch']);
gulp.task('sass', function () {
return gulp.src('./Styles/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write(".",{ ext: '.map' }))
.pipe(gulp.dest('./wwwroot/styles'));
});
gulp.task('sass:watch', function () {
gulp.watch('./Styles/**/*.scss', ['sass']);
});
gulp.task('webpack', function(){
return gulp.src('App/entry.js')
.pipe(webpack( webpackConfig ))
.pipe(gulp.dest('./'));
});
gulp.task('webpack:watch', function(){
var watch = Object.create(webpackConfig);
watch.watch = true;
return gulp.src('App/entry.js')
.pipe(webpack(webpackConfig))
.pipe(gulp.dest('./'));
});
When I run gulp watch, I get this output:
c:\Data\projets\someproject>gulp watch
[13:30:18] Using gulpfile c:\Data\projets\someproject\gulpfile.js
[13:30:18] Starting 'sass:watch'...
[13:30:18] Finished 'sass:watch' after 13 ms
[13:30:18] Starting 'webpack:watch'...
[13:30:22] Version: webpack 1.12.13
Asset Size Chunks Chunk Names
./wwwroot/dist/bundle.js 498 kB 0 [emitted] main
./wwwroot/dist/bundle.js.map 616 kB 0 [emitted] main
[13:30:22] Finished 'webpack:watch' after 3.92 s
[13:30:22] Starting 'watch'...
[13:30:22] Finished 'watch' after 11 µs
However, even if the console does not returns to the prompt, no bundle file is updated, if I update my sources.
I don't believe the issue is in my webpack.config.js file. If I run webpack --watch --color --progress in the prompt, I see the recompilation of bundle whenever a file is modified.
Thanks for clarification, I'm learning javascript ecosystem the hard way :)
In your console output, you should get 'webpack is watching for changes' if you do everything correctly. You have set watch.watch to true, but in the next step you have referenced to the old webpackConfig, for which the watch parameter is not true. You should use:
return gulp.src('App/entry.js')
.pipe(webpack(watch))
.pipe(gulp.dest('./'));
It worked after this change and the gulp watch polls for both the changes. You will also see in your console 'webpack is watching for changes'.
I hope this solves the issue.

Gulp not watching correctly

I'm new to using gulp and I think I have it setup correctly, but it does not seem to be doing what it should be doing.
My gulpfile.js has
gulp.task('compass', function() {
return gulp.src('sites/default/themes/lsl_theme/sass/**/*.scss')
.pipe(compass({
config_file: 'sites/default/themes/lsl_theme/config.rb',
css: 'css',
sass: 'scss'
}))
.pipe(gulp.dest('./sites/default/themes/lsl_theme/css'))
.pipe(notify({
message: 'Compass task complete.'
}))
.pipe(livereload());
});
with
gulp.task('scripts', function() {
return gulp.src([
'sites/default/themes/lsl_theme/js/**/*.js'
])
.pipe(plumber())
.pipe(concat('lsl.js'))
.pipe(gulp.dest('sites/default/themes/lsl_theme/js'))
// .pipe(stripDebug())
.pipe(uglify('lsl.js'))
.pipe(rename('lsl.min.js'))
.pipe(gulp.dest('sites/default/themes/lsl_theme/js'))
.pipe(sourcemaps.write())
.pipe(notify({
message: 'Scripts task complete.'
}))
.pipe(filesize())
.pipe(livereload());
});
and the watch function
gulp.task('watch', function() {
livereload.listen();
gulp.watch('./sites/default/themes/lsl_theme/js/**/*.js', ['scripts']);
gulp.watch('./sites/default/themes/lsl_theme/sass/**/*.scss', ['compass']);
});
when I run gulp, the result is
[16:14:36] Starting 'compass'...
[16:14:36] Starting 'scripts'...
[16:14:36] Starting 'watch'...
[16:14:37] Finished 'watch' after 89 ms
and no changes are registered.
for file structure, my gulpfile.js is in the root directory and the sass, css, and js are all in root/sites/default/themes/lsl_theme with the sass folder containing the folder 'components' full of partials.
My assumption is that you are on windows? Correct me if I'm wrong.
There is this problem that gulp-notify tends to break the gulp.watch functions. Try commenting out
// .pipe(notify({
// message: 'Scripts task complete.'
// }))
and see if the problem still exists.
If that does fix the issue, a solution from this thread may be helpful.
You can use the gulp-if
plugin in combination with
the os node module
to determine if you are on Windows, then exclude gulp-notify, like
so:
var _if = require('gulp-if');
//...
// From https://stackoverflow.com/questions/8683895/variable-to-detect-operating-system-in-node-scripts
var isWindows = /^win/.test(require('os').platform());
//...
// use like so:
.pipe(_if(!isWindows, notify('Coffeescript compile successful')))
It turns out that a large part of my issue was just simply being a rookie with Gulp. When I removed 'scripts' from my gulp watch it started working.
I then made the connection that it was watching the same directory that it was placing the new concatenated and minified js files in so it was putting the new file, checking that file, and looping over and over causing memory issues as well as not allowing 'compass' to run.
After creating a 'dest' folder to hold the new js everything started working just peachy.

Why don't newly added files trigger my gulp-watch task?

I have a gulp task which uses gulp-imagemin to compress images. When I add new files to this directory I'd like for this task to compress them as well. I read that gulp.watch doesn't trigger on new files and that I should try gulp-watch so I used it like so;
gulp.task('images', function() {
watch({glob: './source/images/*'}, function (files) {
return files
.pipe(plumber())
.pipe(imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./www'));
});
});
This works the same as gulp.watch on the first run, but when I add a new image to the directory nothing happens. If I overwrite an existing file however, it DOES run the task again, so it does behave differently.
The documentation on gulp-watch called this "Batch Mode" and said I could also run the task on a per-file basis, so I tried this way too;
gulp.task('images', function() {
gulp.src('./source/images/*')
.pipe(watch())
.pipe(plumber())
.pipe(imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./www'));
});
But nothing changed. Why isn't adding files to my image directory triggering the task?
Adding an extra argument {cwd:'./'} in gulp.watch worked for me:
gulp.watch('src/js/**/*.js',{cwd:'./'},['scripts']);
2 things to get this working:
1 Avoid ./ in the file/folder patterns
2 Ensure ./ in the value for cwd
Good Luck.
Ref:- https://stackoverflow.com/a/34346524/4742733
Most likely such kind of questions are redirected to gaze package and its internal processes, that runs complicated watching procedures on your OS. In this case you should pass images/**/* to glob option, so gaze will watch all (including new) files in images directory:
var gulp = require('gulp');
var watch = require('gulp-watch');
var imagemin = require('gulp-imagemin');
gulp.task('default', function() {
watch({glob: 'images/**/*'}, function (files) {
files.pipe(imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./www'));
});
});
But this fill not fix case, when you have empty images directory. If you want to watch them, pass ['images', 'images/**/*'] to glob, and it will watch directory, that initially empty.
P.s. also you dont need gulp-plumber in this case, because watch will rerun function, that uses imagemin every time, even when imagemin pops an error.

gulp watch terminates immediately

I have a very minimal gulpfile as follows, with a watch task registered:
var gulp = require("gulp");
var jshint = require("gulp-jshint");
gulp.task("lint", function() {
gulp.src("app/assets/**/*.js")
.pipe(jshint())
.pipe(jshint.reporter("default"));
});
gulp.task('watch', function() {
gulp.watch("app/assets/**/*.js", ["lint"]);
});
I cannot get the watch task to run continuously. As soon as I run gulp watch, it terminates immediately.
I've cleared my npm cache, reinstalled dependencies etc, but no dice.
$ gulp watch
[gulp] Using gulpfile gulpfile.js
[gulp] Starting 'watch'...
[gulp] Finished 'watch' after 23 ms
It's not exiting, per se, it's running the task synchronously.
You need to return the stream from the lint task, otherwise gulp doesn't know when that task has completed.
gulp.task("lint", function() {
return gulp.src("./src/*.js")
^^^^^^
.pipe(jshint())
.pipe(jshint.reporter("default"));
});
Also, you might not want to use gulp.watch and a task for this sort of watch. It probably makes more sense to use the gulp-watch plugin so you can only process changed files, sort of like this:
var watch = require('gulp-watch');
gulp.task('watch', function() {
watch({glob: "app/assets/**/*.js"})
.pipe(jshint())
.pipe(jshint.reporter("default"));
});
This task will not only lint when a file changes, but also any new files that are added will be linted as well.
To add to OverZealous' answer which is correct.
gulp.watch now allows you to pass a string array as the callback so you can have two separate tasks. For example, hint:watch and 'hint'.
You can then do something like the following.
gulp.task('hint', function(event){
return gulp.src(sources.hint)
.pipe(plumber())
.pipe(hint())
.pipe(jshint.reporter("default"));
})
gulp.task('hint:watch', function(event) {
gulp.watch(sources.hint, ['hint']);
})
This is only an example though and ideally you'd define this to run on say a concatted dist file.