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

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.

Related

How to run gulp tasks with different parameters depending on the argument on terminal

I have a shared SCSS source files which must be compiled and copied into different project folders.
I have a build task which calls 2 tasks, clean and styles(to compile/minify and copy to build folder).
My source SCSS files are shared between all websites however the destination folders are different.
I would like to be able to run: build websiteA and then clean build folder inside websiteA and compile files from a shared folder and copied to build folder inside Website A.
var assetsDir = '_Assets';
var buildStyleWebsiteA = 'WebsiteA/Assets/build';
var buildStyleWebsiteB = 'WebsiteB/Assets/build';
gulp.task('clean-websiteA', function (cb) {
return del([buildStyleWebsiteA ], cb);
});
gulp.task('styles-websiteA', ['clean-websiteA'], function () {
return gulp.src(assetsDir + '/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer())
.pipe(gulp.dest(buildStyleWebsiteA + '/css'))
.pipe(concat('styles.css'))
.pipe(cleanCss())
.pipe(sourcemaps.write())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest(buildStyleWebsiteA + '/min/'))
.pipe(liveReload());
});
gulp.task('build-websiteA', ['styles']);
PS: I also have same tasks for websiteB (build-websiteB, clean-websiteB, and style-websiteB).
So I ended up with repetitive code and I know there must be a better way.
What I would like to have is provide website name as a parameter for gulp command and then it runs clean and style using correct folder related to that website.
How can I refactor my code to achieve that?
Thanks
I would use environment variables to accomplish this rather than arguments.
var buildDir = process.env.BUILD_DIR + '/Assets/build';
Then you would call it as:
BUILD_DIR=websiteA gulp build

Gulp imagemin - optimize only one image

This code is working perfectly, it will optimize all images in folder and that is ok if I need to call the task manually using gulp images.
But usually I just do gulp watch and for that all images previously added don't need to be reoptimised.
So, how can gulp optimize only the image that was just added to folder, and not all of them?
gulp.task('images', function() {
gulp.src('images/src/*.{png,jpg,gif}')
.pipe(plumber(plumberErrorHandler))
.pipe(imagemin({
optimizationLevel: 7,
progressive: true
}))
.pipe(gulp.dest('images'))
.pipe(notify("Images optimized."));
});
gulp.task('watch', function() {
gulp.watch('images/src/*.{png,jpg,gif}', ['images']);
});
gulp-changed should serve this purpose.
Basically it compares the files' last-modified property if the source is newer than the destination he passes it down the stream, otherwise it's removed from it.

Gulp watch less and error?

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.

gulp notify two tasks when watch invoked task completes

I have a gulpfile in which is a watch task, below
gulp.task('watch', function() {
gulp.watch('template/slick/assets/less/*.less', ['less']); // Watch all the .less files, then run the less task
});
This then invokes a less compile to css of that directory and moves it to a /css/ folder.
I then have 2 other tasks already scripted up to min, concat and move these .css files to a dist folder.
What I need to know is that when my watch invoked less task completes can I notify/run the stylesmin, cssconcats tasks? I do need to add more code to do it. I can't see to find a decent notify/end style way of doing things.
Here's the less task which is invoked by watch
gulp.task('less', function () {
return gulp.src('game/http/template/slick/assets/less/*.less')
.pipe(less())
.pipe(gulp.dest('game/http/template/slick/assets/css/'))
.pipe(notify({message: 'Less compiled'}));
});
You can define your tasks as dependencies of each other with [] syntax like below. (I'm assuming you are using something like connect to start up a server before you start watching the files)
gulp.task('less', function() {
console.log('less');
})
gulp.task('stylesmin', ['less'], function() {
console.log('stylesmin');
})
gulp.task('cssconcats', ['stylesmin'], function() {
console.log('cssconcats');
})
gulp.task('test', ['connect', 'watch']);
Modify your watch to kick off the last task, cssconcats and gulp will run the dependencies first
gulp.task('watch', function() {
gulp.watch('template/slick/assets/less/*.less', ['cssconcats']); // Watch all the .less files, then run the less task
});
Change any .less file and the output shows that the tasks are run correctly in this order;
less, stylesmin, cssconcats

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.