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?
Related
Edit: Solved below
Here is my gulpfile
var gulp = require('gulp');
var sass = require('gulp-sass');
var minify = require('gulp-minify');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var allSassFiles = 'scss/**/*.scss';
var sassFile = gulp.src('./scss/style.scss');
var cssDest = '../wp-content/themes/Jupiter-child/uwkc_assets/css');
var sassify = function() {
return sassFile.pipe(sourcemaps.init())
.pipe(sass({outputStyle: 'compressed', onError: sass.logError}))
.pipe(gulp.dest(cssDest + '/prod'))
.pipe(sourcemaps.write())
.pipe(gulp.dest(cssDest));
};
gulp.task('doSass', sassify);
gulp.task('watchSass', function(){
return gulp.watch(allSassFiles, ['doSass']);
});
The sass glob is the variable "allSassFiles".
s
When I run the task "doSass" everything compiles fine. My css changes are represented in the browser.
However when I run the "watchSass" task things only change once, and then further changes are not reflected in the browser. It is like running only one occurrence of "doSass".
What is weird is that in my console I see the start and complete logs for doSass as if everything is running fine. However I don't see any changes being made to my css destination files.
I've tried many things, mixing up what I am returning, changing the glob syntax. Lots of things. For some reason I just can't get the darned thing to work.
Anyone see anything I might be missing? I have a feeling it has to do with what is returned with gulp-sass or sourcemaps, but I don't know enough about those to figure out the answer.
Thanks everyone!
This is what I figured out:
I needed to create a new gulp.src() object every time I ran sassify in the watch runtime apparently. Also I hope I am using those terms right.
I re-wrote:
return sassFile.pipe(sourcemaps.init())
in the sassify function to:
return gulp.src('./scss/style.scss').pipe(sourcemaps.init())
This did the trick. It makes sense to me that watch would re-use the same src object referenced in the variable sassFile that didn't represent a changed scss file.
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've set up some simple Gulp tasks to process my CSS files.
The tasks are put together in one 'master' task:
gulp.task('process-css', ['concatCSS', 'minifyCSS', 'renameCSS']);
Just for reference, the definition of the concrete tasks follows:
gulp.task('minifyCSS', function() {
return gulp.src('themes/my_theme/css/dist/*.css')
.pipe(sourcemaps.init())
.pipe(minifyCSS())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('themes/my_theme/css/dist/'));
});
gulp.task('concatCSS', function() {
var files = [
'themes/rubbish_taxi/css/bootstrap.css',
'themes/rubbish_taxi/css/custom.css',
'themes/rubbish_taxi/css/responsive.css',
'themes/rubbish_taxi/css/jquery.fancybox.css'
];
return gulp.src(files)
.pipe(concat("bundle.css"))
.pipe(gulp.dest('themes/my_theme/css/dist/'));
});
gulp.task('renameCSS', function() {
gulp.src('themes/my_theme/css/dist/bundle.css')
.pipe(rename(function(path) {
path.basename += ".min";
}))
.pipe(gulp.dest("themes/my_theme/css/"));
});
The tasks complete without an error, but the problem is that minifyCSS does not minify the source file. An unminified version of the files is saved as bundle.min.css. I believe that the reason is that minifyCSS runs before concatCSS completed.
How can I make the tasks be executed synchronously?
Is my only option to specify which tasks should be executed before a give task like this:
gulp.task('minifyCSS', ['concatCSS'], function() {..} ?
It worked when I set it this way, but I wanted to avoid this to make code more readable.
gulp.task('minifyCSS', ['concatCSS'], function() {..} ?
It worked when I set it this way, but I wanted to avoid this to make code more readable.
More readable how? You're stating that minifyCSS is dependent on concatCSS. The line of code I quoted above is how you explain this dependency to gulp.
The alternative is to use something like run-sequence, but I think avoiding functionality built into the tool to solve the exact problem you're facing isn't justified by the desire for a subjective improvement in readability.
I have a scenario where a client of mine wants to drop LESS files into a src directory (via FTP), and for them to be automatically outputted as CSS to a build directory. For each LESS file, once its resultant CSS file is created, it should be removed from the src directory. How can I do this with Gulp?
My current gulpfile.js is:
var gulp = require("gulp");
var watch = require("gulp-watch");
var less = require("gulp-less");
watch({ glob: "./src/**/*.less" })
.pipe(less())
.pipe(gulp.dest("./build"));
This successfully detects new LESS files being dropped into the src directory and outputs CSS files into build. But it doesn't clean up the LESS files afterwards. :(
Use gulp-clean.
It will clean your src directory once you piped it. Of course, test it on a backup with different settings, and if you can't manage to make it work properly, don't hesitate to make a second task and use some task dependency to run the clean after your less task is completed.
If I'm right, when I tried to pipe gulp-clean after the gulp.dest, something went wrong, so I got another way to do this, here's an example with task dependency.
var gulp = require('gulp'),
less = require('gulp-less'),
clean = require('gulp-clean');
gulp.task('compile-less-cfg', function() {
return gulp.src('your/less/directory/*.less')
.pipe(less())
.pipe('your/build/directory'));
});
gulp.task('remove-less', ['less'], function(){
return gulp.src('your/less/directory)
.pipe(clean());
});
That's for the not-watching task. Then, you should use a watch on the *.less files, but you should get task remove-less running instead of less. Why ? Because of task dependency.
When you'll call the remove-less task, it will only start once the less task is complete. That way, the files will only be deleted once your less compilation is over, and not in the middle of it throwing errors.
It may not be the perfect method to get this working as I'm not an expert, but it's a safe and working solution for you to use. Also it's pretty clear to understand IMO.
gulp-clean is deprecated. Use the npm module del.
npm install --save-dev del
Here is how you should use it.
var gulp = require('gulp');
var del = require('del');
gulp.task('clean:mobile', function () {
return 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'
]);
});
gulp.task('default', ['clean:mobile']);