问题
I'm using gulp to compile some .less files and inject the changes in the browser with live-reload.
This is the task I originally created:
var gulp = require('gulp');
var less = require('gulp-less');
var watch = require('gulp-watch');
var plumber = require('gulp-plumber');
var livereload = require('gulp-livereload');
var path = require('path');
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer-core');
var mqpacker = require('css-mqpacker');
var csswring = require('csswring');
gulp.task('less', function() {
var processors = [
autoprefixer({browsers: ["last 2 version", "> 1%", "ie 9", "ie 8", "ie 7", "ios 6"]}),
mqpacker,
csswring({
preserveHacks: true,
removeAllComments: true
})
];
gulp.src('./css/style.less') // only compile the entry file
.pipe(plumber())
.pipe(less({
paths: ['./css/'],
} ))
.pipe(postcss(processors))
.pipe(plumber.stop())
.pipe(gulp.dest('./css/'))
.pipe(livereload());
});
gulp.task('watch', function() {
gulp.watch('./**/*.less', ['less']); // Watch all the .less files, then run the less task
});
gulp.task('default', ['watch']); // Default will run the 'entry' watch task
I created an other gulp task to perform the same tasks but using browser-sync instead of live-reload for cross testing:
var gulp = require('gulp');
var less = require('gulp-less');
var watch = require('gulp-watch');
var plumber = require('gulp-plumber');
var path = require('path');
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer-core');
var csswring = require('csswring');
var browserSync = require('browser-sync').create();
var reload = browserSync.reload;
gulp.task('less', function() {
var processors = [
autoprefixer({browsers: ["last 2 version", "> 1%", "ie 9", "ie 8", "ie 7", "ios 6"]}),
csswring({
preserveHacks: true,
removeAllComments: true
})
];
gulp.src('./css/style.less') // only compile the entry file
.pipe(plumber())
.pipe(less({
paths: ['./css/']
} ))
.pipe(postcss(processors))
.pipe(plumber.stop())
.pipe(gulp.dest('./css/'))
.pipe(reload({stream: true}))
// .pipe(livereload());
});
gulp.task('serve', ['less'], function() {
browserSync.init({
proxy: "http://my-site.dev/"
});
gulp.watch("./css/*.less", ['less']);
});
I then tried to compile both files to be able to run either task depending on if i'm doing local development or if testing. I've created a "less" task to compile the css, a "lrl" live reload watch task and a "bs" browser-sync watch task. I created the "less" task to remove the duplication but now when i change the css the browser reload everything instead of just injecting the css.
var gulp = require('gulp');
var less = require('gulp-less');
var watch = require('gulp-watch');
var plumber = require('gulp-plumber');
var path = require('path');
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer-core');
var csswring = require('csswring');
var livereload = require('gulp-livereload');
var browserSync = require('browser-sync').create();
var reload = browserSync.reload;
gulp.task('less', function() {
var processors = [
autoprefixer({browsers: ["last 2 version", "> 1%", "ie 9", "ie 8", "ie 7", "ios 6"]}),
csswring({
preserveHacks: true,
removeAllComments: true
})
];
gulp.src('./css/style.less') // only compile the entry file
.pipe(plumber())
.pipe(less({
paths: ['./css/']
} ))
.pipe(postcss(processors))
.pipe(plumber.stop())
.pipe(gulp.dest('./css/'))
});
gulp.task('lrl',['less'], function(){
gulp.src('./css/style.less') // only compile the entry file
.pipe(livereload());
});
gulp.task('watch',['lrl'], function() {
livereload.listen();
gulp.watch('./**/*.less', ['lrl']); // Watch all the .less files, then run the less task
});
// browser-sync setup
gulp.task('bs',['less'], function(){
gulp.src('./css/style.less') // only compile the entry file
.pipe(reload({stream: true}))
});
gulp.task('serve', function() {
browserSync.init({
proxy: "http://my-site.dev/"
});
gulp.watch("./css/*.less", ['bs']);
gulp.watch("./js/script.js").on('change', reload);
gulp.watch("./templates/*.php").on('change', reload);
});
// run default task with live reload for local development
gulp.task('default', ['watch']); // Default will run the 'entry' watch task
I'm a bit confused with the way to call tasks within tasks. Is there a way to make sure that the css are injected, it's much faster to work on design this way.
Thanks a lot
=================== BIG EDIT ============================
I've been messing about with run-sequence but I still have the same problem.
In some way the task is working. With the default task i get live-reload on my local server only. With gulp serve
I get a server where i can debug my layout across browsers and devices. The problem is that i don't get css injection anymore. it looks like gulp keeps re-running all of the tasks and refresh the browser to reconnect it.
so I made a working version with duplicated code to make what i'm trying to achieve clearer
var gulp = require('gulp'),
less = require('gulp-less'),
watch = require('gulp-watch'),
plumber = require('gulp-plumber'),
path = require('path'),
postcss = require('gulp-postcss'),
autoprefixer = require('autoprefixer-core'),
mqpacker = require('css-mqpacker'),
csswring = require('csswring'),
livereload = require('gulp-livereload'),
browserSync = require('browser-sync').create(),
reload = browserSync.reload;
gulp.task('less-lrl', function() {
var processors = [
autoprefixer({browsers: ["last 2 version", "> 1%", "ie 9", "ie 8", "ie 7", "ios 6"]}),
mqpacker,
csswring({
preserveHacks: true,
removeAllComments: true
})
];
gulp.src('./css/style.less') // only compile the entry file
.pipe(plumber())
.pipe(less({
paths: ['./css/'],
} ))
.pipe(postcss(processors))
.pipe(plumber.stop())
.pipe(gulp.dest('./css/'))
.pipe(livereload());
});
gulp.task('watch', function() {
livereload.listen();
gulp.watch('./**/*.less', ['less-lrl']); // Watch all the .less files, then run the less task
});
gulp.task('less-bs', function() {
var processors = [
autoprefixer({browsers: ["last 2 version", "> 1%", "ie 9", "ie 8", "ie 7", "ios 6"]}),
mqpacker,
csswring({
preserveHacks: true,
removeAllComments: true
})
];
gulp.src('./css/style.less') // only compile the entry file
.pipe(plumber())
.pipe(less({
paths: ['./css/']
} ))
.pipe(postcss(processors))
.pipe(plumber.stop())
.pipe(gulp.dest('./css/'))
.pipe(reload({stream: true}))
});
gulp.task('serve', ['less-bs'], function() {
browserSync.init({
proxy: "http://myserver.dev"
});
gulp.watch("./css/*.less", ['less-bs']);
});
gulp.task('default', ['watch']); // Default will run the 'entry' watch task
When I do this it works smoothly. But I wanted to avoid the code duplication from the "less-lrl" and "less-bs" tasks. The only thing that differ is .pipe(livereload());
and .pipe(reload({stream: true}))
There's some stoopid going on in my brain, i don't haz understand :)
回答1:
If I understood your question correctly, the runSequence
would solve your problem. Take a look here: https://www.npmjs.com/package/run-sequence
You just need to add
var runSequence = require('run-sequence');
And create a task that runs your desired ones. For example:
gulp.task('build', function(callback) {
return runSequence(
'less',
['lrl'],
callback
);
});
then
gulp.task('watch',['build'], function() {
livereload.listen();
gulp.watch('./**/*.less', ['build']); // Watch all the .less files, then run the less task
});
回答2:
note - please do not use both less and postcss together, since postcss was invented to replace and enhance what less does. Google it..
Please make sure LESS files path is correct!
Try it like this:
var gulp = require('gulp'),
less = require('gulp-less'),
watch = require('gulp-watch'),
plumber = require('gulp-plumber'),
path = require('path'),
postcss = require('gulp-postcss'),
autoprefixer = require('autoprefixer-core'),
csswring = require('csswring'),
livereload = require('gulp-livereload'),
browserSync = require('browser-sync').create(),
reload = browserSync.reload;
gulp.task('less', function() {
var processors = [
autoprefixer({browsers: ["last 2 version", "> 1%", "ie 9", "ie 8", "ie 7", "ios 6"]}),
csswring({
preserveHacks: true,
removeAllComments: true
})
];
gulp.src('./**/*.less') // only compile the entry file
.pipe(plumber())
.pipe(less({
paths: ['./css/']
} ))
.pipe(postcss(processors))
.pipe(plumber.stop())
.pipe(gulp.dest('./css/'))
.pipe(livereload());
});
gulp.task('watch', function() {
livereload.listen();
gulp.watch('./**/*.less', ['less']); // Watch all the .less files, then run the less task
});
// browser-sync setup
gulp.task('bs',['less'], function(){
gulp.src('./css/style.less') // only compile the entry file
.pipe(reload({stream: true}))
});
gulp.task('serve', function() {
browserSync.init({
proxy: "http://my-site.dev/"
});
gulp.watch("./css/*.less", ['bs']);
gulp.watch("./js/script.js").on('change', reload);
gulp.watch("./templates/*.php").on('change', reload);
});
// run default task with live reload for local development
gulp.task('default', ['less', 'watch']); // Default will run the 'entry' watch task
回答3:
I tried both suggested answers above but to no avail. I can't manage to create a "less" subtask to be shared with the "live-relaod" and "browser-sync" tasks (It does re-run all tasks all the time and i loose the benefits of css injection).
The best I managed to do is to run them together like this:
var gulp = require('gulp'),
less = require('gulp-less'),
watch = require('gulp-watch'),
plumber = require('gulp-plumber'),
path = require('path'),
postcss = require('gulp-postcss'),
autoprefixer = require('autoprefixer-core'),
csswring = require('csswring'),
livereload = require('gulp-livereload'),
browserSync = require('browser-sync').create(),
reload = browserSync.reload;
gulp.task('less', function() {
var processors = [
autoprefixer({browsers: ["last 2 version", "> 1%", "ie 9", "ie 8", "ie 7", "ios 6"]}),
csswring({
preserveHacks: true,
removeAllComments: true
})
];
gulp.src('./css/style.less') // only compile the entry file
.pipe(plumber())
.pipe(less({
paths: ['./css/']
} ))
.pipe(postcss(processors))
.pipe(plumber.stop())
.pipe(gulp.dest('./css/'))
.pipe(livereload());
});
gulp.task('watch', function() {
livereload.listen();
gulp.watch('./**/*.less', ['less']); // Watch all the .less files, then run the less task
});
gulp.task('serve', function() {
browserSync.init({
//files: "**/*.css",
files: ['**/*.js', '**/*.php','**/*.css'], // is this better than gulp watch?
proxy: "http://leadgen.dev/node/1272"
});
//gulp.watch("./js/script.js").on('change', reload);
//gulp.watch("./templates/*.php").on('change', reload);
});
// run default task with live reload for local development
gulp.task('default', ['less', 'watch', 'serve']); // Default will run the 'entry' watch task
So now I have both tasks running together. I would still prefer to be able to switch between one or the other though.
回答4:
I've got same issue with stylus. You can try two dest
, it may help
gulp.src('./css/style.less') // only compile the entry file
.pipe(less({
paths: ['./css/']
} ))
.pipe(gulp.dest('./css/'))
.pipe(postcss(processors))
.pipe(gulp.dest('./css/'))
.pipe(livereload());
});
来源:https://stackoverflow.com/questions/29946662/gulp-tasks-chaining