why `gulp.src` in `gulp.watch` won't work? - gulp

I want to just build 'the only one file' I changed,not a bunch of files,
so I tried something like this
gulp.task('watch_html', function () {
return gulp.watch('source/**/*.html', function (event) {
gulp.src(event.path)
.pipe(prettify({indent_size: 4}))
.pipe(gulp.dest('dist'));
});
});
But why this won't work?
Is there a workaround?

I think a gulp package like gulp-changed may be able to help you out.
It provides a way to only operate on changed files in a stream. Check it out here.
Hope that helps!

You should separate the tasks :
gulp.task('html', function() {
return gulp.src('source/**/*.html')
.pipe(prettify({indent_size: 4}))
.pipe(gulp.dest('dist'));
});
gulp.task('watch', function() {
// when modification is detected, html task is launched
gulp.watch(['source/**/*.html'], ['html']);
});

Related

Gulp watch task, multiple folders with chained onchange

Why does this work
gulp.task("watch", ["browser-sync"], function() {
gulp.watch(
["node_modules/bootstrap/scss/bootstrap.scss", "src/scss/*.scss"],
["sass"],
);
gulp.watch("src/*.html").on("change", browserSync.reload);
});
But this does not work:
gulp.task("watch", ["browser-sync"], function() {
gulp.watch(
["node_modules/bootstrap/scss/bootstrap.scss", "src/scss/*.scss"],
["sass"],
["src/*.html"]
).on("change", browserSync.reload);
});
Hmmm, Thanks in advance !
Gulp.watch has this declaration:
gulp.watch(glob[, opts], tasks)
See gulp.watch documentation. You have
gulp.watch(
["node_modules/bootstrap/scss/bootstrap.scss", "src/scss/*.scss"],
["sass"],
["src/*.html"]
which is equivalent to
gulp.watch(glob, task, glob)
which just isn't allowed. You could fix it by doing something like:
gulp.task("watch", ["browser-sync"], function() {
gulp.watch(
["node_modules/bootstrap/scss/bootstrap.scss", "src/scss/*.scss"],
["sass"]);
gulp.watch(["src/*.html"]).on("change", browserSync.reload);
});
and then put a reload call at the end of your 'sass' task.

Gulp - start task with an argument

So I'm trying to create a gulp workflow and I'd like to implement options for some tasks, like gulp copy-images --changed. Now, I've created a watch task that obviously watches all image files and it should start the copy-images with the --changed flag.
Ideally, I want to do something like this:
gulp.task('copy-images', function(){
// some code
});
gulp.task('watch', function(){
gulp.watch(config.images, ['copy-images --changed']);
});
I'm also very aware that I could do:
gulp.task('copy-images', function(){
// some code
});
gulp.task('copy-images-changed', function(){
// some code
});
gulp.task('watch', function(){
gulp.watch(config.images, ['copy-images']);
});
but this means duplicate code.
Anyone with a solution or maybe some advice?
Thanks in advance!
Gulp does not provide a built-in way of specifying options for tasks. You have to use an external options parser module like yargs. See this question for more on that topic.
This also means that passing something like ['copy-images --changed'] to gulp.watch() will not work. The entire string will just be interpreted as a task name.
The best approach for you would be to factor out the code of your task into a function and then call this function from both your task and your watch:
var argv = require('yargs').argv;
function copyImages(opts) {
if (opts.changed) {
// some code
} else {
// some other code
}
}
gulp.task('copy-images', function() {
copyImages(argv);
});
gulp.task('watch', function(){
gulp.watch(config.images, function() {
copyImages({changed:true});
});
});
The above should cover all of your bases:
gulp copy-images will execute //some other code.
gulp copy-images --changed will execute //some code.
gulp watch will execute //some code any time a watched file is changed.

Watching for file changes does nothing when containing directory deleted

Consider this task:
gulp.task("WatchDirectoryForAllFileChanges", function () {
gulp.watch("Build/**/*",
function (event) {
console.log("event", event);
});
});
When I add or remove individual files in the Build directory I get events as expected. But when I delete a directory containing files I get no events at all for the removal of the files within that directory.
Is there an explanation for this behavior, and is it possible to handle it properly? I'd think directory deletion like this is a common enough scenario to motivate some befuddlement here.
While this is not an answer why gulp behaves like this, I found chokidar which handles this stuff correctly:
var chokidar = require("chokidar");
gulp.task("Watch", function () {
return chokidar.watch("Build/**", { ignoreInitial: true })
.on("all", function (event, path) {
console.log(event, path);
});
});

Gulp.js - `watch` not working on `typescript` changes, but works for `html,css` changes

I am using gulp to compile my ts files in to js file. when i change the ts file alone, the watch is not updating the browser. But when i change the html or css file it working fine.
I understand that, something i am missing in my watch property here. anyone help me to find the mistake here please?
here is my code :
var gulp = require('gulp'),
gulpTypescript = require('gulp-typescript')
browserSync = require('browser-sync');
var scripts = {
in : 'app/script/ts/*.*',
dest : 'app/script/js/'
}
gulp.task('typeScript', function () {
return gulp.src( scripts.in )
.pipe( gulpTypescript() )
.pipe( gulp.dest( scripts.dest ) );
});
gulp.task('browserSync', function () {
browserSync({
server: {
baseDir: 'app'
}
})
})
gulp.task('default', ['typeScript', 'browserSync'], function () {
gulp.watch([[scripts.in], ['typeScript']], browserSync.reload);
gulp.watch( ['app/*.html', 'app/styles/*.css'], browserSync.reload);
});
The possible method signatures for gulp.watch are:
gulp.watch(glob[, opts], tasks)
gulp.watch(glob[, opts, cb])
So what you're doing here makes no sense:
gulp.watch([[scripts.in], ['typeScript']], browserSync.reload);
That means you're passing 'typeScript' as part of the glob, when it is actually a task name.
Think about what you're trying to achieve:
Whenever you change a TypeScript file in scripts.in you want your typeScript task to run, so your *.ts files get compiled to scripts.dest.
Whenever a resulting *.js file in scripts.dest is changed you want the browserSync.reload callback to be executed.
So what you actually need is two different gulp.watch statements for those two steps of your TypeScript build process:
gulp.task('default', ['typeScript', 'browserSync'], function () {
gulp.watch(scripts.in, ['typeScript']); // 1st step
gulp.watch(scripts.dest + '*.*', browserSync.reload); // 2nd step
gulp.watch( ['app/*.html', 'app/styles/*.css'], browserSync.reload);
});

Is it possible to run gulp-notify in a watch task?

I'm putting together a gulpfile and I was wondering if you can combine gulp-notify (or some other solution) with a watch task so that a message pops up when the watch task has started running. I can't find anything from my searches on how I would go about doing this. Is it even possible?
Here's my watch task:
// Watch our files for changes
gulp.task('watch', function() {
// -- I wanna run a notify message here saying 'Watching for changes...' -- //
gulp.watch('assets/styles/**/*.scss', ['styles']);
gulp.watch('assets/scripts/**/*.js', ['scripts']);
gulp.watch('assets/images/**/*', ['images']);
});
This should do it:
gulp.task('watch', function() {
notify("Watching for changes...").write('');
gulp.watch('assets/styles/**/*.scss', ['styles']);
gulp.watch('assets/scripts/**/*.js', ['scripts']);
gulp.watch('assets/images/**/*', ['images']);
});
Also, if you meant to have a notification each time a file changes, you could do something like this:
gulp.task('watch', function () {
//...
gulp.watch([
'./src/**/*.html',
'./src/**/*.php',
]).on('change', function () {
browserSync.reload();
notify("File changed: browser synced").write('');
});
});
I managed to do it with gulp-notify and node-notifier.
After you gulp tasks pipe the notifier and in the callback use the node-notifier to show the popup.
var notify = require('gulp-notify');
var nodeNotifier = require('node-notifier');
gulp().src(options.src)
.pipe(gulp.dest(options.dest))
.pipe(notify(function () {
nodeNotifier.notify({
'title': 'App',
'message': 'Build'
});
}));
Can't you just use
gulp.task('watch', function() {
console.log('Watching for changes...');
gulp.watch('assets/styles/**/*.scss', ['styles']);
gulp.watch('assets/scripts/**/*.js', ['scripts']);
gulp.watch('assets/images/**/*', ['images']);
});