Here is a very minimalistic example gulpfile.js:
var gulp = require('gulp');
function foo(done) {
console.log('change');
done();
}
function watchFiles() {
console.log('starting watching...');
gulp.watch('./gulpfile.js', gulp.series(foo));
};
gulp.task('watch-files', gulp.series(watchFiles));
A message "change" should be displayed on the console every time, when the gulpfile.js itself gets edited. But it doesn't work. I get the initial message "starting watching..." and the Gulp info about starting the task displayed.
$ gulp watch-files
[[[00:07:48] Using gulpfile /var/www/.../my-app/gulpfile.js
[00:07:48] Starting 'watch-files'...
[00:07:48] Starting 'watchFiles'...
starting watching...
But changes on the defined file to be observed (the gulpfile.js) are ignored, so no further messages are being displayed.
What causes the issue and how to fix it and get the watching working?
Related
Consider the following gulp file:
var gulp = require('gulp');
var eslint = require('gulp-eslint');
var debug = require('gulp-debug');
gulp.task('lint', function (done) {
gulp
.src([
'src/**/*.js',
'!src/public/javascripts/external/*'
])
.pipe(eslint())
.pipe(eslint.format())
//.pipe(debug({title: 'Linting:'}));
done();
});
If my src folder contains too many files (I am not talking about an excessive number. It's less than 20), then gulp lint will only output
Using gulpfile [my/path/to/gulpfile]
Starting 'lint'...
Finished 'lint' after 55ms
There won't be any warnings from ESLint, even though I made sure there are problems in my code of course. This problem can be reproduced by manually adding javascript files from my src folder without using wildcards. After a certain number of files (I sadly forgot to count), errors won't be displayed any more. This does depend not on which files I add, just the number.
For some reason this behavior can be 'fixed' by adding the commented line that outputs debug information, so I am assuming my mistake has something to do with me misunderstanding how the gulp works internally. ESLint also works fine when called externally. Any ideas what the problems could be or steps to narrow it down?
I was able to fix my problem although I am not 100% sure what the problem was. According to the gulp-eslint package description you are supposed to return the result of the pipes. So the correct gulpfile would look like this:
var gulp = require('gulp');
var eslint = require('gulp-eslint');
var debug = require('gulp-debug');
gulp.task('lint', function () {
return gulp // note the return here
.src([
'src/**/*.js',
'!src/public/javascripts/external/*'
])
.pipe(eslint())
.pipe(eslint.format());
// no call to 'done()' is needed
});
My guess is that the plugin runs asynchronously and I ended the task by calling done() before it was actually done. Printing the debug information either happened after the asynchronous task was done or it bought enough time to finish. Now gulp will properly receives a promise (or something like that) and waits until it is finished.
Can anyone confirm this guess?
I was hoping to eventually set up a Gulp workflow with uncss as I have a lot of unused Bootstrap styles in my sites. I am trying to test some files first though and when I run it, it starts but just hangs and never stops. I got the code directly from the plugin page so I'm not sure what is going on. I haven't added anything more complicated yet. Does anyone see errors?
var gulp = require('gulp');
var uncss = require('gulp-uncss');
gulp.task('default', function () {
return gulp.src('css/landing.css')
.pipe(uncss({
html: ['index.html']
}))
.pipe(gulp.dest('out'));
});
I don't understand why this simple script behaves differently depending on the del plugin setup.
When I launch gulp sass I just want to clean the public/css dir and "compile" the css from sass. So far so good:
gulp.task('clean-css', del.bind(null,['./public/css']));
gulp.task('sass', ['clean-css'], function () {
return gulp.src('./resources/sass/**/*.scss')
.pipe(plugins.sass({outputStyle: 'compressed'}))
.pipe(gulp.dest('./public/css'));
});
However if if change the clean-css task to:
gulp.task('clean-css', del(['./public/css']));
Then it only works every other time. The first it cleans and generates the css, the next one it removes the directory but doesn't generate anything.
So, what's the difference between del(['./public/css']) and del.bind(null,['./public/css'])? Why does it affect the script in that way?
UPDATE:
The times when it doesn't generate anything I am seeing this error:
events.js:141
throw er; // Unhandled 'error' event
^
Error: ENOENT: no such file or directory, open 'C:\Users\XXXX\gulp-project\public\css\style.css'
at Error (native)
tl;dr
Gulp doesn't know when del is finished if no callback is provided. with or without bind, del works every other time if your sass task is run before del and files to be deleted actually exist.
According to the gulp documentation you should also provide the callback method to del. This is how gulp knows when a task is finished:
var gulp = require('gulp');
var del = require('del');
gulp.task('clean:mobile', function (cb) {
del([
'dist/report.csv',
// here we use a globbing pattern to match everything inside the `mobile` folder
'dist/mobile/**/*',
// we don't want to clean this file though so we negate the pattern
'!dist/mobile/deploy.json'
], cb);
});
gulp.task('default', ['clean:mobile']);
I suppose that the order in which your tasks are run is different each time, since gulp doesn't know when del is finished when no callback is provided. According to the documentation:
If you want to create a series where tasks run in a particular order, you need to do two things:
give it a hint to tell it when the task is done,
and give it a hint that a task depends on completion of another.
I am trying eslint with gulp. I have set up a task like this:
gulp.task('lint', function () {
return gulp.src([
'components/myjs.js'
])
// eslint() attaches the lint output to the eslint property
// of the file object so it can be used by other modules.
.pipe(eslint())
// eslint.format() outputs the lint results to the console.
// Alternatively use eslint.formatEach() (see Docs).
.pipe(eslint.format())
// To have the process exit with an error code (1) on
// lint error, return the stream and pipe to failOnError last.
.pipe(eslint.failOnError());
});
when I run gulp lint
It tells me a lot of errors. Now I am trying to fix them one by one. But I have to re-run gulp lint manually for it to give me an updated report. How do I set it up so that it will automatically re-run every time I update 'components/myjs.js'?
Just add a watch task:
gulp.task('watch', function() {
gulp.watch('components/myjs.js', ['lint']);
});
This way Gulp will track any changes on your 'components/myjs.js' and execute your 'lint' task on any change
If you want further reading:
https://scotch.io/tutorials/automate-your-tasks-easily-with-gulp-js
I have the following code in my gulpfile.js:
gulp.task('test-watch', function () {
console.log('running test-watch...');
return gulp.src('./views/layout.tmpl')
.pipe(rename('layout.html'))
.pipe(gulp.dest('./views/'));
});
gulp.task('watch', function () {
var watcher = gulp.watch('./views/layout.tmpl', ['test-watch']);
watcher.on('change', function (event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
});
It results in the following output (the last line occurs after I edit/save "layout.tmpl"):
[15:53:12] Using gulpfile C:\project1\gulpfile.js
[15:53:12] Starting 'watch'...
[15:53:12] Finished 'watch' after 6.72 ms
File C:\project1\views\layout.tmpl was changed, running tasks...
The file "layout.html" (which is supposed to be a copy of "layout.tmpl") does not get created. Note that in the above output while the "console.log" within the "watcher.on" invocation is shown in output, the "console.log" within the "test-watch" task is not shown. If I run the test-watch task directly, the file does get created.
Here is the output if I run the test-watch task directly:
[15:53:56] Using gulpfile C:\project1\gulpfile.js
[15:53:56] Starting 'test-watch'...
running test-watch...
[15:53:56] Finished 'test-watch' after 12 ms
Note that the "console.log" within the "test-watch" task is shown.
This is on a Windows 7 machine, running gulp tasks from cmd.exe.
Support for passing in watch tasks to the gulp.watch API as an array requires gulp version 3.5 at minimum. The gulp.watch API accepts an array of tasks only in gulp version 3.5 and up.
My local gulp was version 3.4.
I updated gulp to latest 3.8 version and my watch task worked correctly.