In my office we are using gulp to build our less files. I wanted to improve the build task as it took over a second to build on a large project we recently worked on. The idea was to cache the files and only pass the one that changed. So I started with google and found incremental builds for javascript ang thought it would be easy to rewrite them for less. Here's the one I started with: https://github.com/gulpjs/gulp/blob/master/docs/recipes/incremental-builds-with-concatenate.md
After a few unsuccessful tries I ended up with following code (tested with the latest bootstrap distribution):
var gulp = require('gulp');
var less = require('gulp-less');
var concat = require('gulp-concat');
var remember = require('gulp-remember');
var cached = require('gulp-cached');
var fileGlob = [
'./bootstrap/**/*.less',
'!./bootstrap/bootstrap.less',
'!./bootstrap/mixins.less'
];
gulp.task('less', function () {
return gulp.src(fileGlob)
.pipe(cached('lessFiles'))
.pipe(remember('lessFiles'))
.pipe(less())
.pipe(gulp.dest('output'));
});
gulp.task('watch', function () {
var watcher = gulp.watch(fileGlob, ['less']);
watcher.on('change', function (e) {
if (e.type === 'deleted') {
delete cached.caches.scripts[e.path];
remember.forget('lessFiles', e.path);
}
});
});
But this passes only the changed file and the less compiler fails because of the variable definitions missing. If I pipe the concat plugin before the less task, gulp gets stuck in a (seemingly) endless loop.
gulp.task('less', function () {
return gulp.src(fileGlob)
.pipe(cached('lessFiles'))
.pipe(remember('lessFiles'))
.pipe(concat('main.less')
.pipe(less())
.pipe(gulp.dest('output'));
});
Has anyone experience with those plugins or managed to create an incremental less build in an other way. Here is a (messy) github repository for testing: https://github.com/tuelsch/perfect-less-build
PS: I'm planning on adding linting, sourcemaps, minification, evtl. cache busting and autoprefixer later on.
Like Ashwell, I've found it useful to use imports to ensure that all my LESS files have access to the variables and mixins that they need. I also use a LESS file with imports for bundling purposes. This has a few advantages:
Where you want to import variables, mixins, etc, but you don't want to actually output the entire contents of another file, you can use:
After a few days of effort, I was finally able to get an incremental build that correctly rebuilds all the objects that depend on the LESS file I changed. I documented the results here. This is the final gulpfile:
We can now simply run
gulp live
to build all our LESS files once, and then allow each subsequent change to just build those files that depend on the changed files.So when I want to do incremental builds in gulp I do it by abstracting out the inner process of the gulp task, this way I don't have to worry about keeping a cache.
This works great for me and I use this pattern all over my gulp tasks. However I have noticed that sometime gulp will squash paths during the watch "on change" if it gets a single file. In that case I do the path manipulation my self, something like
path.dirname(srcPath.replace( srcDir, outputDir ))
as the argumentdest
for therunCompile
function.Edit: Just realized this probably isn't going to solve your "lost variables" problem. I don't have anything off the top of my head to solve that one since I organize my LESS files with a heavy use of imports, so every file that would need a set of variables would have an import statement insuring they are there.