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
Related
Can I get some insight on why I'm getting this message in chrome console, it seems to prevent css code injection.
Browsersync reloading all stylesheets because path
'html\css\theme.css' did not match any specific one.
I suspect it's a path issue i have, but I can't seem to figure it out.
I tried to strip as much as I could.
Here's my folder structure:
/_base/gulpfile.js
/_base/html/index.html
/_base/html/css/theme.css
/_base/src/scss/theme.scss
And here's my code:
// Defining requirements
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var sass = require('gulp-sass');
var watch = require('gulp-watch');
var browserSync = require('browser-sync').create();
var sourcemaps = require('gulp-sourcemaps');
var notify = require('gulp-notify');
// var style lint
//general error handler with plumber
var pb_errorHandler = { errorHandler: notify.onError({
title: 'Gulp',
message: 'Error: <%= error.message %>'
})
};
// stage 1 - HTML CSS JS FILE CREATION
// A. scss to css
var s1_sassOptions = {
errLogToConsole: true,
outputStyle: 'expanded'
};
// compile stage1 scss files, use plumber and sorcemaps.
// to do : need to check what error handling to use - curently 2
gulp.task('create-css', function () {
gulp.src('src/scss/theme.scss')
.pipe(plumber(pb_errorHandler))
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sass(s1_sassOptions).on('error', sass.logError))
.pipe(sourcemaps.write(undefined, { sourceRoot: null }))
.pipe(gulp.dest('html/css/'))
});
// automatically reloads the page when files coressponding to this paths are changed:
var s1_broswserSync_files = [
'html/css/*.css'
];
// browsersync options
var s1_browserSync_options = {
server:"./html"
};
gulp.task('browser-sync', function() {
browserSync.init(s1_broswserSync_files, s1_browserSync_options );
});
// Starts watcher. Watcher runs gulp sass task on changes
gulp.task('stage1-watch', function () {
gulp.watch(['src/scss/*.scss'], ['create-css']);
});
// Starts watcher with browser-sync. Browser-sync reloads page automatically on your browser
gulp.task('stage1', ['browser-sync', 'stage1-watch'], function () { });
It looks like your options for browserSync.init() aren't correct. The init method takes two optional arguments of configuration options and a callback function. See https://browsersync.io/docs/api#api-init
You want to setup your options like this.
var s1_browserSync_options = {
server:"./html",
files: "html/css/*.css"
};
gulp.task('browser-sync', function() {
browserSync.init(s1_browserSync_options );
});
Take a look at the SASS and CSS injecting in the docs https://browsersync.io/docs/gulp#gulp-reload
Browsersync stream is not working for me.
I've copied example from official documentation and it won't working. Reloading for html and js files working fine. Only sass streaming wouldn't work. I've read all the issues on github and can't find an answer for my question.
var gulp = require('gulp');
var sass = require('gulp-sass');
var browserSync = require('browser-sync');
var useref = require('gulp-useref');
var uglify = require('gulp-uglify');
var gulpIf = require('gulp-if');
var cssnano = require('gulp-cssnano');
var imagemin = require('gulp-imagemin');
var cache = require('gulp-cache');
var del = require('del');
var runSequence = require('run-sequence');
// Development Tasks
// -----------------
gulp.task('serve', ['sass'], function() {
browserSync.init({
server: {
baseDir: "./app",
index: 'index.html'
}
});
gulp.watch('app/styles/*.scss', ['sass']);
gulp.watch("app/*.html").on('change', browserSync.reload);
gulp.watch('app/pages/*.html').on('change', browserSync.reload);
gulp.watch('app/js/**/*.js').on('change', browserSync.reload);
});
// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', function() {
return gulp.src('app/styles/*.scss'). // Gets all files ending with .scss in app/scss and children dirs
pipe(sass().on('error', sass.logError)). // Passes it through a gulp-sass, log errors to console
pipe(gulp.dest('app/css')). // Outputs it in the css folder
pipe(browserSync.stream());
})
// Build Sequences
// ---------------
gulp.task('default', function(callback) {
runSequence([
'sass', 'serve'
], callback)
})
gulp.task('build', function(callback) {
runSequence('clean:dist', 'sass', [
'useref', 'images', 'fonts'
], callback)
})
I would make three quick changes to see if they help. First
const browserSync = require("browser-sync").create();
Note the create() at the end, you need that. Second, simplify this:
gulp.task('default', function(callback) {
runSequence([
'sass', 'serve'
], callback)
})
to:
gulp.task('default', ['serve']);
Your 'serve' task calls the 'sass' task first anyway so you don't need the renSequence stuff. Finally, change:
pipe(browserSync.stream());
to:
pipe(browserSync.reload({stream:true}));
I would also make this change:
gulp.watch('app/js/**/*.js').on('change', browserSync.reload(stream:true}));
Normally Gulp-Sass compiles Sass to CSS perfectly until there is an error in a Sass file(for eg: h1{font-size:}).
I have used Gulp Plumber to prevent the pipes from breaking but I could not figure out the way to properly use it. In the above example, even if I fix the error and make it h1{font-size:32px;}, CSS is not generated.
ERROR
Plumber found unhandled error:
error in plugin 'gulp-sass'
Message:
app\scss\pages\_landing.scss
Error: style declaration must contain a value
...
gulpfile
// Requires Gulp
var gulp = require('gulp');
// Require Gulp Sass
var sass = require('gulp-sass');
// Require Browser Sync
var browserSync = require('browser-sync').create();
// For minificatin
var useref = require('gulp-useref');
var uglify = require('gulp-uglify');
var gulpIf = require('gulp-if');
var cssnano = require('gulp-cssnano');
// Require imagemin
var imagemin = require('gulp-imagemin');
var cache = require('gulp-cache');
// Require del
var del = require('del');
// Require runsequence
var runSequence = require('run-sequence');
// Require Sourcemaps
var sourcemaps = require('gulp-sourcemaps');
// Require Plumber
var plumber = require('gulp-plumber');
// Prepocessing Sass
gulp.task('sass', function(){
return gulp.src('app/scss/**/*.scss')
.pipe(sourcemaps.init())
.pipe(plumber({
handleError: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(sass()) // Using gulp-sass
.pipe(sourcemaps.write())
.pipe(gulp.dest('app/css'))
.pipe(browserSync.reload({
stream: true
}))
});
// Spinning up a Browser Sync Server
gulp.task('browserSync', function() {
browserSync.init({
server: {
baseDir: 'app'
},
})
})
// Watching for changes
gulp.task('watch', ['sass', 'browserSync'], function(){
gulp.watch('app/scss/**/*.scss', ['sass']);
gulp.watch('app/*.html', browserSync.reload);
})
// Gulp Default Function
gulp.task('default', function (callback) {
runSequence(['sass','browserSync', 'watch'],
callback
)
})
// Minification
gulp.task('useref', function(){
return gulp.src('app/*.html')
.pipe(useref())
// Minifies only if it's a JavaScript file
.pipe(gulpIf('*.js', uglify()))
// Minifies only if it's a CSS file
.pipe(gulpIf('*.css', cssnano()))
.pipe(gulp.dest('dist'))
});
// Image Optimization
gulp.task('images', function(){
return gulp.src('app/images/**/*.+(png|jpg|jpeg|gif|svg|JPG)')
// Caching images that ran through imagemin
.pipe(cache(imagemin({
interlaced: true
})))
.pipe(gulp.dest('dist/images'))
});
// Copy Fonts
gulp.task('fonts', function() {
return gulp.src('app/fonts/**/*')
.pipe(gulp.dest('dist/fonts'))
})
// Cleaning up generated files
gulp.task('clean:dist', function() {
return del.sync('dist');
})
// Build Production website
gulp.task('build', function(callback) {
runSequence(
'clean:dist',
'sass',
['useref', 'images', 'fonts'],
callback
)
})
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'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.