gulp performing task multiple times - gulp

I have the following code fragment in my gulpfile.
gulp.task('static', function() {
return gulp.src(['./src/**', '!./src/js/**', '!./src/js/', '!./src/scss/', '!./src/scss/**'])
.pipe(gulp.dest(outputDir + '/'))
});
gulp.task('watch', function() {
gulp.watch(['./src/**', '!./src/js/**', '!./src/js/', '!./src/scss/', '!./src/scss/**'], ['static']);
});
gulp.task('dev', ['static']);
gulp.task('default', ['watch', 'dev']);
If I run gulp dev, gulp watch or gulp static, everything works fine. However, if I run just gulp (default), it does the static task 5 times. Can anyone help me out with why this is happening?
P.S. The paths passed to watch are such because if I don't disclude the directories as separate paths, it seems to be copying the empty directories js and scss for some reason.

Probably because you're not returning the tasks, and you need them to be asyc.
See this: Gulp.js task, return on src?
and the docs (also linked in SO post above) https://github.com/gulpjs/gulp/blob/master/docs/API.md#async-task-support
Also, the dev task looks redundant in its current form - you may as well use the task static directly, unless you plan to bundle in more tasks with dev

Related

gulp-watch in combination with gulp-less caching issue

I have the following setup:
// watch for changes
gulp.task('watch', function () {
gulp.watch('./assets/**/*.less', ['compile-less']);
});
gulp.task("compile-less", () => {
return gulp.src('./assets/build-packages/*.less')
.pipe($.less({
paths: [ $.path.join(__dirname, 'less', 'includes') ]
}))
.pipe(gulp.dest(OutputPath)); // ./dist/styles/
});
So basically every time a developer changes something in a less file it runs the task 'compile-less'. The task 'compile-less' builds our package less files (including all the #imports). The first change in a random less file works, all the less files are being build. The second time it runs the task but my generated dist folder isn't updated when I change something to a less file that is imported. I'm wondering if the combination of the watch task and the compiling task somehow caches files. Because if I run the compile-less task manually it works everytime.
Does anyone had the same experience?
gulp-less version 4.0.0 has a strange caching issue.
Install gulp-less#3.5.0 and will solve the issue.
This will be fixed. Check out https://github.com/stevelacy/gulp-less/issues/283#ref-issue-306992692

Script Concat / Minify Task Keeps Running

So I have a task like so:
gulp.task('scripts', function() {
return gulp.src(['app/scripts/app.js', 'app/scripts/controllers/**/*.js', 'app/scripts/services/**/*.js', 'app/scripts/directives/**/*.js', 'app/scripts/libs/**/*.js' ])
.pipe(concat('external.min.js'))
.pipe(ngAnnotate())
.pipe(uglify())
.pipe(gulp.dest('app/scripts'))
.pipe(gulp.dest('dist/scripts'))
});
and I have a watch task:
gulp.task('watch', ['sass-dev', 'scripts'], function() {
gulp.watch('app/style/sass/**/*.scss', ['sass-dev']);
gulp.watch('app/scripts/**/*.js', ['scripts']);
});
All works well, except whenever I save a JS file, "scripts" runs multiple times. I'm assuming the problem lies with the gulp.src and it looking at multiple files, but I'm not sure.
This is no big deal (to me), but sometimes I'll swap over to the command line and the task is running infinitely. It just keeps getting called over and over again.
If you haven't already guessed, I'm running Angular, which is why app.js is first and I have ngAnnotate.
Can someone shed some light on why the script runs continuously sometimes?
I guess the problem is .pipe(gulp.dest('app/scripts')). You're doing some stuff (uglify and angular stuff) with your scripts and then you place them in the same folder you're watching. So the scripts task will launch again and again and again.
You should remove this line and only place your distribution scripts in your distribution folder and leave your app files untouched.

GULP: Modify a watched file in place without causing an infinite loop

Im trying to use gulp and jscs to prevent code smell. I also want to use watch so that this happens when ever a change is made. The problem I'm running into is jscs is modify the source file that is being watched. This causes gulp to go into an infinite loop of jscs modifying the file and then watch seeing the change and firing off jscs again and again and again ...
const gulp = require('gulp');
gulp.task('lint', function() {
return gulp.src('/src/**/*.js')
.pipe(jscs({
fix: true
}))
.pipe(jscs.reporter())
.pipe(gulp.dest('/src'));
});
gulp.task('watch', function() {
gulp.watch('/src/**/*.js', ['lint']);
});
It's generally a bad idea to override source files from a gulp task. Any Editors/IDEs where those files are open might or might not handle that gracefully. It's generally better to write the files into a separate dist folder.
That being said here's two possible solutions:
Solution 1
You need to stop the gulp-jscs plugin from running a second time and writing the files again, thus preventing the infinite loop you're running into. To achieve this all you have to do is add gulp-cached to your lint task:
var cache = require('gulp-cached');
gulp.task('lint', function() {
return gulp.src('/src/**/*.js')
.pipe(cache('lint'))
.pipe(jscs({
fix: true
}))
.pipe(cache('lint'))
.pipe(jscs.reporter())
.pipe(gulp.dest('/src'));
});
The first cache() makes sure that only files on disk that have changed since the last invocation of lint are passed through. The second cache() makes sure that only files that have actually been fixed by jscs() are written to disk in the first place.
The downside of this solution is that the lint task is still being executed twice. This isn't a big deal since during the second run the files aren't actually being linted. gulp-cache prevents that from happening. But if you absolutely want to make sure that lint is run only once there's another way.
Solution 2
First you should use the gulp-watch plugin instead of the built-in gulp.watch() (that's because it uses the superior chokidar library instead of gaze).
Then you can write yourself a simple pausableWatch() function and use that in your watch task:
var watch = require('gulp-watch');
function pausableWatch(watchedFiles, tasks) {
var watcher = watch(watchedFiles, function() {
watcher.close();
gulp.start(tasks, function() {
pausableWatch(watchedFiles, tasks);
});
});
}
gulp.task('watch', function() {
pausableWatch('/src/**/*.js', ['lint']);
});
In the above the watcher is stopped before the lint task starts. Any .js files written during the lint task will therefore not trigger the watcher. After the lint task has finished, the watcher is started up again.
The downside of this solution is that if you save a .js file while the lint task is being executed that change will not be picked up by the watcher (since it has been stopped). You have to save the .js file after the lint task has finished (when the watcher has been started again).

Gulp watch doesn't recompile

I have a task :
gulp.task('styles', ['cleanup'], function () {
'use strict';
log('Compiling Less files to :' + config.temp);
return gulp
.src(config.less)
.pipe(less())
.pipe(autoprefixer({browsers: ['last 2 versions', '> 5%']}))
.pipe(gulp.dest(config.temp));
});
This tasks works like it should when I call it manually. It deletes the files in config.temp (not shown in code snippet) and recompiles the less to css and places it again in config.temp directory.
The problem is when I try to run this task inside gulp.watch :
gulp.task('watch', function() {
gulp.watch(config.less, ['styles']);
});
The task doens't work anymore. I can see gulp picking up changes I make in my less files, I see the log output, there are no errors, yet still the task hasn't really happend. My css output remains the same.
Another indication that the tasks aren't really executed, is the time that gulp spend; when I do it manually it takes longer :
then when the gulp watch runs the same task :
I have been following a tutorial that does the exact same thing, and I have some example files that also use gulp.watch and work.
I have seen some mentioning of gulp-watch but I'm not sure that's the same as gulp.watch?
Hope it's some obvious mistake someone can point out to me.
Some things to try:
Try the debugging i mentioned in the comments
Add this in the styles task, right after you pipe in the source code.
.pipe($.plumber()) // exit gracefully if something fails after this
also, make sure you check your version of the gulp.
I wish I could just delete this question because apparently there is nothing wrong: Webstorm was just too bloody slow in refreshing itself, so I always thought the .css file hadn't changed. I just needed to wait approx 45 seconds. Sorry for wasting internet space!

Gulp + gulp-compass compile, unchanged files being reinjected to BrowserSync

I've got a Gulp task setup to compile .scss files with compass, and also another task running which injects changed CSS into the browser via BrowserSync.
gulp.task('browser-sync', function () {
var options = {
files: './public/css/**/*.css',
proxy: ecs_domain,
port: 3000
};
browserSync(options);
});
gulp.task('compass', function () {
gulp.src('./scss/**/*.scss')
.pipe(compass({
css: cssOutput,
sass: 'scss'
}))
.pipe(gulp.dest(cssOutput))
.pipe(reload({stream: true}));
});
The problem I'm finding is that when compass is run, I get output like in the following snippet:
identical public/css/main.css
[BS] File changed: public/css/main.css
Even though the file main.css hasn't changed, compass somehow touches it, making BrowserSync think it has changed, meaning that even if only one file changes, the entire set of CSS files are re-injected to the browser.
Is there a way to leave the identical/unchanged *.css files un-touch-ed so BrowserSync can only load the files that actually changed?
We have quite a few files and makes the whole process quite slow.
I've found a partial solution. I installed gulp-changed and redirected output from compass to a temporary .out folder. Then created a watch to run gulp-changed when files differ from public/css and .out version using the following task:
gulp.task('copy-changed-css', function () {
gulp.src('.out/**/*.css')
.pipe(changed('public/css', {hasChanged: changed.compareSha1Digest}))
.pipe(gulp.dest('public/css'))
});