I've recently switched from grunt to gulp, and so far have successfully configured gulp to do what I want. The only problem I'm having is with livereload, I'm finding that I have to save twice in order to see the compiled sass in the browser. Sass seems delayed
Is there a way I can ensure that livereload doesn't execute until sass is compiled? Here's my config:
// Dependencies
var gulp = require('gulp');
var watch = require('watch');
var livereload = require('gulp-livereload');
var sass = require('gulp-sass');
var prefix = require('gulp-autoprefixer');
var cssmin = require('gulp-cssmin');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var plumber = require('gulp-plumber');
var notify = require('gulp-notify');
onError = function(error){
notify.onError({
title: "Gulp",
subtitle: "Failure!",
message: "<%= error.message %>",
sound: "Beep"
})(error);
this.emit('end');
};
// Watch
gulp.task('watch', function(){
gulp.watch('src/css/**/*.scss', ['sass']).on('change', livereload.changed);
gulp.watch('src/js/**/*.js', ['concat']).on('change', livereload.changed);
gulp.watch('*').on('change', livereload.changed);
});
// Sass
gulp.task('sass', function(){
gulp.src('src/css/style.scss')
.pipe(plumber({errorHandler: onError}))
.pipe(sass({style: 'expanded'}))
.pipe(prefix('last 4 versions', 'ie 8', 'ie 9'))
.pipe(gulp.dest('src/css/build'))
.pipe(cssmin())
.pipe(rename({suffix:'.min'}))
.pipe(gulp.dest('dist/css'))
});
// Concat
gulp.task('concat', function(){
gulp.src(['src/js/models/*.js', 'src/js/views/*.js', 'src/js/controllers/*.js'])
.pipe(plumber({errorHandler: onError}))
.pipe(concat('main.js'))
.pipe(gulp.dest('src/js/build'))
.pipe(uglify())
.pipe(rename({suffix:'.min'}))
.pipe(gulp.dest('dist/js'))
})
// Default
gulp.task('default', ['watch'], function(){
livereload.listen();
});
Your current watch task is telling gulp to run livereload as soon as one of your sass files changes, instead of waiting for the sass task to complete.
According to the gulp-livereload documentation:
Add .pipe(livereload()) as the last step in your sass task
Remove the livereload.change step from your sass file watch task.
That will ensure the livereload step will always happen last in your sass task, after your css has been compiled.
Related
Here is what I have:
var gulp = require('gulp');
var sass = require('gulp-sass');
var watch = require('gulp-watch');
var cleanCSS = require('gulp-clean-css');
var concat = require('gulp-concat');
// GULP WATCH
gulp.task('watch', function() {
gulp.watch('assets/sass/*.sass', ['sass']);
});
// GULP SASS CONVERTER
gulp.task('sass', function(){
return gulp.src('assets/sass/style.sass')
.pipe(sass()) // Converts Sass to CSS with gulp-sass
.pipe(gulp.dest('assets/css/'));
});
gulp.task('cleanCSS', function(){
return gulp.src('assets/*.css')
.pipe(cleanCSS())
.pipe(concat('style.css'))
.pipe(gulp.dest('assets/css/'));
});
gulp.task('minify-css', function() {
return gulp.src('assets/css/style.css')
.pipe(cleanCSS())
.pipe(concat('style.min.css'))
.pipe(gulp.dest('assets/css/'));
});
gulp.task('default', ['sass','watch','cleanCSS','minify-css']);
My problem:
When I initially run gulp it works perfectly. As I save my files, the only function that executes is sass, but my site files link to the minified CSS so I need each function to work otherwise I don't see my changes. This issue started once I added the task minify-css.
V2 Update
var gulp = require('gulp');
var sass = require('gulp-sass');
var watch = require('gulp-watch');
var cleanCSS = require('gulp-clean-css');
var concat = require('gulp-concat');
// GULP WATCH
gulp.task('watch', function() {
gulp.watch('assets/sass/*.sass', ['sass']);
});
// GULP SASS CONVERTER
gulp.task('sass', function(){
return gulp.src('assets/sass/style.sass')
.pipe(sass()) // Converts Sass to CSS with gulp-sass
.pipe(gulp.dest('assets/css/'));
});
gulp.task('cleanCSS', function(){
return gulp.src('assets/*.css')
.pipe(cleanCSS())
.pipe(concat('style.css'))
.pipe(gulp.dest('assets/css/'));
});
gulp.task('minify-css', ['cleanCSS'], function() {
return gulp.src('assets/css/style.css')
.pipe(cleanCSS())
.pipe(concat('style.min.css'))
.pipe(gulp.dest('assets/css/'));
});
gulp.task('default', ['sass','watch','minify-css']);
As far as I can tell you have three options.
Option 1 - least preferred but least amount of changes
var gulp = require('gulp');
var sass = require('gulp-sass');
var watch = require('gulp-watch');
var cleanCSS = require('gulp-clean-css');
var concat = require('gulp-concat');
// GULP WATCH
gulp.task('watch', function() {
gulp.watch('assets/sass/*.sass', ['sass', 'cleanCSS', 'minify-css']);
});
// GULP SASS CONVERTER
gulp.task('sass', function(){
return gulp.src('assets/sass/style.sass')
.pipe(sass()) // Converts Sass to CSS with gulp-sass
.pipe(gulp.dest('assets/css/'));
});
gulp.task('cleanCSS', function(){
return gulp.src('assets/*.css')
.pipe(cleanCSS())
.pipe(concat('style.css'))
.pipe(gulp.dest('assets/css/'));
});
gulp.task('minify-css', function() {
return gulp.src('assets/css/style.css')
.pipe(cleanCSS())
.pipe(concat('style.min.css'))
.pipe(gulp.dest('assets/css/'));
});
gulp.task('default', ['sass','watch','cleanCSS','minify-css']);
While your default task is running all four tasks(sass, watch, cleanCSS and minify-css), when the watch task notices changes in one of your .sass files, it only reruns the sass task(not the default task which would run all four again). This is not preferred as I believe gulp runs these tasks in parallel and they aren't guaranteed to run in order or wait for one to finish before the next run.
Option 2 - better, but still not optimal
var gulp = require('gulp');
var sass = require('gulp-sass');
var watch = require('gulp-watch');
var cleanCSS = require('gulp-clean-css');
var concat = require('gulp-concat');
// GULP WATCH
gulp.task('watch', function() {
gulp.watch('assets/sass/*.sass', ['minify-css']);
});
// GULP SASS CONVERTER
gulp.task('sass', function(){
return gulp.src('assets/sass/style.sass')
.pipe(sass()) // Converts Sass to CSS with gulp-sass
.pipe(gulp.dest('assets/css/'));
});
gulp.task('cleanCSS', ['sass'], function(){
return gulp.src('assets/*.css')
.pipe(cleanCSS())
.pipe(concat('style.css'))
.pipe(gulp.dest('assets/css/'));
});
gulp.task('minify-css', ['cleanCSS'], function() {
return gulp.src('assets/css/style.css')
.pipe(cleanCSS())
.pipe(concat('style.min.css'))
.pipe(gulp.dest('assets/css/'));
});
gulp.task('default', ['sass','watch',]);
This is much more declarative. Now running gulp will execute the default task which will fire off the sass and watch tasks. minify-css is dependent on cleanCSS, so gulp will try to run the cleanCSS task, but that is dependent on sass, so it will run that first, then cleanCSS, then minify-css. When watch notices a change it will rerun minify-css, but will see the dependency chain and run all of them again.
Option 3 - best
gulp is different from grunt in that it uses streams so that it doesn't have to write to disk in between each task. Keeping the files in memory while manipulating them makes it operate faster. If all of these tasks need to run all of time, the best would be to combine them into one with something like the following.
var gulp = require('gulp');
var sass = require('gulp-sass');
var watch = require('gulp-watch');
var cleanCSS = require('gulp-clean-css');
var concat = require('gulp-concat');
// GULP WATCH
gulp.task('watch', function() {
gulp.watch('assets/sass/*.sass', ['sass']);
});
// GULP SASS CONVERTER
gulp.task('sass', function(){
return gulp.src('assets/sass/style.sass')
.pipe(sass()) // Converts Sass to CSS with gulp-sass
.pipe(cleanCSS())
.pipe(concat('style.css'))
.pipe(concat('style.min.css'))
.pipe(gulp.dest('assets/css/'));
});
gulp.task('default', ['sass','watch']);
This will read the files in once and write them once. The default task will execute the sass task as will the watch task when it notices changes.
Hope this helps!
I want to have a watch task that reloads the browser. Below watch works fine for sass compilation but the browser doesn't reload - thoughts?
// Gulp Packages
var gulp = require('gulp'),
gutil = require('gulp-util'),
sass = require('gulp-sass'),
sourcemaps = require('gulp-sourcemaps'),
browserSync = require('browser-sync').create(),
reload = browserSync.reload;
// Default Task
gulp.task('default', ['copyFiles','styles']);
// Copy Files
gulp.task('copyFiles', function() {
gulp.src('./source/*.php').pipe(gulp.dest('./public'));
});
// Compile SASS
var sassOptions = {
errLogToConsole: true,
outputStyle: 'compressed'
};
gulp.task('styles', function() {
gulp.src('./scss/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./css/'));
});
// Watch Task
gulp.task('watch', function() {
gulp.watch('./scss/includes/**/*.scss', ['styles']);
gulp.watch('./scss/includes/**/*.scss').on('change', browserSync.reload);
});
I would suggest a configuration similar to:
// Static Server + watching scss/html files
gulp.task('serve', ['sass'], function() {
browserSync.init({
server: "./app"
});
gulp.watch("app/scss/*.scss", ['sass']);
gulp.watch("app/*.html").on('change', browserSync.reload);
});
// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', function() {
return gulp.src("app/scss/*.scss")
.pipe(sass())
.pipe(gulp.dest("app/css"))
.pipe(browserSync.stream());
});
gulp.task('default', ['serve']);
Source: https://www.browsersync.io/docs/gulp
You need to initialise a Server and watch changes to your SASS and HTML. Then in your sass compile task you need to add .pipe(browserSync.stream()); after the dest command so browserSync can pick up your newly compiled SASS and serve it.
Finally you need to call your serve task with your default task.
Also you can take a look here https://scotch.io/tutorials/how-to-use-browsersync-for-faster-development#using-browsersync-and-sass for another example of Browsersync + Gulp + SASS.
I am running the following in my gulpfile.js
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var csswring = require('csswring');
var sass = require('gulp-sass');
gulp.task('styles', function() {
var processors = [
csswring
];
return gulp.src('xampp/htdocs/wordpress/wp-content/themes/paws2play/sass/style.scss')
.pipe(sass())
.on('error', sass.logError)
.pipe(postcss(processors))
.pipe(gulp.dest('xampp/htdocs/wordpress/wp-content/themes/paws2play/style.css'));
});
gulp.task('watch:styles', function(){
gulp.watch('**/*.scss', ['styles']);
});
After running gulp styles I get this out put
[19:05:34] Using gulpfile c:\xampp\htdocs\wordpress\wp-content\themes\paws2play\gulpfile.js
[19:05:34] Starting 'styles'...
[19:05:34] Finished 'styles' after 17 ms
When I go and check my style.css file, it is empty. I am not sure what I am doing wrong. I have run sass -trace --watch style.scss:style.css and it worked just fine. I am at a loss for what to do here?
Thank You
I see a little error, but I don't think it's a problem in your case.
First make sure that your path is correct.
Check where is your gulpfile.js located
If it is in xampp/htdocs/wordpress/wp-content, then find PATH in gulpfile.js below and change with ./themes/paws2play
Then change your gulpfile.js with:
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var csswring = require('csswring');
var sass = require('gulp-sass');
gulp.task('styles', function() {
var processors = [
csswring
];
return gulp.src('PATH/sass/style.scss')
.pipe(sass().on('error', sass.logError))
.pipe(postcss(processors))
.pipe(gulp.dest('PATH'));
});
gulp.task('watch:styles', function(){
gulp.watch('PATH/sass/**/*.scss', ['styles']);
});
You can also add gulp-debug to see files that are in your stream.
I'm setup as outlined below. The good news: styles are being compiled, the bad news: gulp doesn't seem to watch the scss files for a change and compile automatically?
// Include gulp
var gulp = require('gulp');
// Plugins
var concat = require('gulp-concat');
var stripDebug = require('gulp-strip-debug');
var uglify = require('gulp-uglify');
var include = require('gulp-include');
var sass = require('gulp-sass');
var minifycss = require('gulp-minify-css');
// Styles
gulp.task('styles', function() {
gulp.src('./_themes/blanktheme/ui/scss/styles.scss')
.pipe(include())
.pipe(sass({
errLogToConsole: true
}))
.pipe(minifycss())
.pipe(gulp.dest('./_themes/blanktheme/ui/css/'))
});
// Watch
gulp.task('default', ['watch'], function() {
gulp.watch('./_themes/blanktheme/ui/scss/*.scss', ['styles']);
});
gulp.task('default', ['styles', 'watch']);
I think this come from the fact you have two tasks default. I guess gulp ignore the first one (with gulp.watch) to only trigger the second one. Then you have dependencies with watch but seems like watch does not exist ?
You can install gulp-watch locally, and include it in your file. Give a look at gulp-watch documentation it might help.
Try this :D
var watch = require('gulp-watch');
// Styles
gulp.task('styles', function() {
gulp.src('./_themes/blanktheme/ui/scss/styles.scss')
.pipe(include())
.pipe(sass({
errLogToConsole: true
}))
.pipe(minifycss())
.pipe(gulp.dest('./_themes/blanktheme/ui/css/'))
});
// Watch
gulp.task('watch', function() {
watch('./_themes/blanktheme/ui/scss/*.scss', function () {
gulp.start('styles');
});
});
gulp.task('default', ['styles', 'watch']);
I'm having a strange problem with Gulp. Here is my Gulp file:
var gulp = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var notify = require('gulp-notify');
var sass = require('gulp-ruby-sass');
gulp.task('default', function() {
gulp.run('main');
gulp.watch('sass/*.scss', function() {
gulp.run('main');
})
});
gulp.task('main', function() {
return gulp.src('sass/**/*.scss')
.pipe(sass())
.on('error', notify.onError(function(error) { return 'Error: ' + error.message; }))
// .pipe(autoprefixer('last 10 version'))
.pipe(gulp.dest('./css'))
.pipe(notify({ message: 'Your SASS has been auto-prefixed and minified.'}))
;
});
The script runs correctly the first time. But on second and subsequent runs of the same script (without Gulp having stopped running), it puts it in the SASS directory as a subitem of the .SCSS file. Any idea why this is happening. I'm not sure how to even debug.
Try the following code.
It uses the correct syntax for gulp, replacing gulp.run() with the supported function arguments.
var gulp = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var notify = require('gulp-notify');
var sass = require('gulp-ruby-sass');
gulp.task('main', function() {
return gulp.src('./sass/**/*.scss')
.pipe(sass())
.on('error', notify.onError(function(error) { return 'Error: ' + error.message; }))
.pipe(gulp.dest('./css'))
.pipe(notify({ message: 'Your SASS has been auto-prefixed and minified.'}));
});
gulp.watch('sass/*.scss', ['main']);
gulp.task('default', ['main']);
Found the answer, the gulp.dest keeps the folder structure of gulp.src, to override you can set the base property of the src, this will exclude whatever folder the base is set to
example gulp.src('./sass/' + '**/*.scss', {base: 'sass'}) this now excludes sass from the destination, no longer appending sass to your gulp.dest
See and this look at gulp.src