sass sourcemaps gulp task setup - sass

I have my sass gulp task to compile my initial css:
var input = './sass/bootstrap/*.scss';
var output = './public/css';
var sassOptions = {
lineNumbers: true
};
gulp.task('sass', function () {
return gulp
// Find all `.scss` files from the `stylesheets/` folder
.src(input)
.pipe(sourcemaps.init())
.pipe(sass(sassOptions))
.pipe(sourcemaps.write())
.pipe(gulp.dest(output));
});
Then in a seperate project I have my watch task to minify the css:
gulp.task('debug-css', function () {
gulp.src([
'assets/css/style.test.css',
'assets/css/other.css'
])
.pipe(concat('app.css'))
.pipe(cssmin())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('./build/'));
livereload.listen();
gulp.watch('assets/**/*.css', function() {
gulp.src([
'assets/css/style.test.css',
'assets/css/other.css'
])
.pipe(concat('app.css'))
.pipe(cssmin())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('./build/'))
.pipe(livereload());
});
});
When I use chrome dev tools, I cannot see the sass partials anywhere, Is there a way I can setup sourcemaps so I can tell which css comes from which sass file?

Everything is good with your sourcemaps, you should try to separate a bit more the gulp.task and gulp.watch you've created so avoiding to confuse yourself.
I recreated your Gulpfile, adding some more useful plugins, here is the gist:
https://gist.github.com/carlosbensant/2a3a36633a06a50dda775b2a8bde3958
Working with Sourcemaps
Said that, if you want to see the sourcemaps while you're in development stage you just have to run gulp; when you just want to deploy you're app then you should run gulp css to remove the sourcemaps into the CSS compiled (and so saving file space).
Recommendation
Try to BrowserSync, after some years using LiveReload, when I used BrowserSync the first time, I didn't get back to LiveReload, because it does a lot more than just live reloading. One of the coolest thing it does is synchronizing between multiple browsers (and platforms).
Hope that helps!

Related

Gulpfile.js - how to get .min.css, .css, and .css.map files on gulp.watch?

Ok, I've done lots of research on this, but on a drupal site, I have a zurb foundation theme and am super happy with it. The only problem I'm having is when I customize the scss components. I'm using gulp to compile it and it is recreating the css file fine. However, I would like to get it to ALSO give me the min.css file and the css.map file, but I can't seem to figure it out. I've tried many different iterations on the gulpfile.js but here is my latest.
It only produces the css file.
var sassFiles = './themes/zurb_foundation/scss/**/*.scss',
cssDest = './themes/zurb_foundation/css';
gulp.task('styles', function(){
gulp.src(sassFiles)
.pipe(sourcemaps.init())
.pipe(autoprefixer())
.pipe(gulp.dest(cssDest))
.pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError))
.pipe(gulp.dest(cssDest))
.pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
.pipe(rename({ extname: 'min.css' }))
.pipe(sourcemaps.write('./themes/zurb_foundation/css'))
.pipe(gulp.dest(cssDest))
});
gulp.task('watch', function() {
livereload.listen();
gulp.watch(sassFiles, ['styles']);
})
I've finally gotten it to produce the following error:
CssSyntaxError: /Users/USERNAME/Desktop/SITEFOLDER/ROOTDIR/themes/zurb_foundation/scss/foundation.scss:1:1: Unknown word
You tried to parse SCSS with the standard CSS parser; try again with the
postcss-scss parser> 1 | // Foundation by ZURB
I guess at this point, my question would be how should I set-up my gulpfile to tackle the postcss-scss parsing?
So first of all we declare the necessary packages as const as these values shouldn't change their assignation.
const gulp = require('gulp');
const sass = require('gulp-sass');
const sourcemaps = require('gulp-sourcemaps');
const cssmin = require('gulp-cssmin');
Then we write a gulp task called sass, in which we search for all files in the styles folder in an .scss format.
We check and log any errors, we create sourcemaps which allow the browser to map CSS generated by SASS back to the original source file (if you want to use your .scss/.css that way).
We then write your new .css files to the public/styles folder.
gulp.task('sass', function () {
return gulp.src('./styles/*.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write('./maps'))
.pipe(gulp.dest('./public/styles'));
});
After which, we write a second gulp task called minify-css.
We look for all files in the .css format inside our styles folder.
First of all we auto prefix all our css properties. For example, if you have a css class where you have set:
user-select: none;
Autoprefixing will handle adding:
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
After which we minify, concatenate and then name our new minified css file as main.min.css and then save it in the public/styles folder.
gulp.task('minify-css', function(){
gulp.src(['./styles/*.css'])
.pipe(autoprefixer({
browsers: ['last 2 versions']
}))
.pipe(cssmin())
.pipe(concat('main.css'))
.pipe(rename("main.min.css"))
.pipe(gulp.dest('./public/styles'));
});
We then write a task called build, so to call both the sass and minify-css tasks in chronological order by simply running gulp build in the terminal.
gulp.task('build', [‘sass’, ‘minify-css’]);

Lint SASS in Gulp before compiling

I'm new at Gulp and I'm trying to lint scss files before compiling them in order to avoid gulp watcher breaking.
My gulpfile.js looks like this now:
gulp.task('default', ['watch']);
// Sass compilation to css
gulp.task('build-css', function() {
return gulp.src('source/scss/**/*.scss')
.pipe(sourcemaps.init()) // Process the original sources
.pipe(sass())
.pipe(sourcemaps.write()) // Add the map to modified source.
.pipe(gulp.dest('public/assets/css'));
});
// Configure which files to watch and what tasks to use on file changes
gulp.task('watch', function() {
gulp.watch('source/scss/**/*.scss', ['build-css']);
});
And when I enter a mistake in a scss file like:
body {
color: $non-existing-var;
}
The gulp watcher shows error info but stops watching cause gulp breaks its execution. How can I solve this?
I will assume you are using gulp-sass pluging, if you are not using, I suggest you to do it. It is a wrapper over node-sass, which is the C version: super fast :)
On gulp-sass documentation, they already have you covered with one example, so your task should look like this:
gulp.task('build-css', function() {
return gulp.src('source/scss/**/*.scss')
.pipe(sourcemaps.init()) // Process the original sources
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write()) // Add the map to modified source.
.pipe(gulp.dest('public/assets/css'));
});
Hope this helps you to accomplish what you are looking for :)

gulp-sass: ERROR - file to import not found or unreadable

I am having problems getting my SASS files to compile having now split them out and importing ones I require in my main scss file.
I have a styles folder that contains:
main.scss
top_menu.scss
I have added some imports to my main.scss:
#import 'font-awesome';
#import 'bootstrap';
#import 'custom_bootstrap';
#import 'top_menu';
and my gulp-sass task looks like this
gulp.task('compile_sass', ['compile_bower_sass'], function () {
return gulp.src(paths.scss_files, {base:'src'})
.pipe(gulp.dest(paths.dist))
.on('error', gutil.log)
.pipe(sass().on('error', sass.logError))
.pipe(minifycss({
keepSpecialComments: false,
removeEmpty: true
}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(paths.dist))
});
The paths.scss_files variable is set to:
scss_files: './src/assets/styles/**/*.scss'
When the task runs I receive an error:
file to import not found or unreadable: top_menu
I actually want to be able to split my scss out into separate related sub folders and then use #import: 'navigation\top_menu' kinda thing.
Why would this error be coming up?
Thanks
EDIT:
The compile_bower_sass task compiles some other scss files (font-awesome, bootstrap, custom_bootstrap) which are required as you can see from the #import lines on my main.scss.
When running the compile_sass task and watching the output (dist) folder, I see the css files get generated from the compile_bower_sass task (so font-awesome.css, bootstrap.css, custom_bootstrap.min.css). I notice that the top_menu.scss file gets copied across too, but does not get compiled, so I guess this is why the error occurs.
Do I need to specify an order in my task, so could I make sure it compiles main.scss last to ensure any required files such as my custom top_menu.scss get compiled first and are available for my main file to access?
EDIT 2
OK, so I think my thoughts this was down to the order of compilation is correct.
If I change my scss_files variable to explicitly set the order they get piped to the gulp-sass (this time I have further organised into folders)
scss_files: ['./src/assets/styles/custom_bootstrap.scss',
'./src/assets/styles/navigation/top_menu.scss',
'./src/assets/styles/navigation/user_toolbar.scss',
'./src/assets/styles/main.scss']
Now my original compile-sass task works as is.
So, my next question is how do I configure gulp-sass so that I can ensure my main.scss file is compiled last? Or am I going about this all the wrong way?
EDIT 3:
I should probably have added these extra task configs when first asking this question. So the compile_sass task requires compile_bower_sass to be run first.
/*-BOWER PACKAGEs INCLUSION --------------------------------------------*/
gulp.task('compile_bower_sass', ['compile_bower_css'], function(){
var sassFiles = mainBowerFiles('**/*.scss');
return gulp.src(sassFiles)
.pipe(rename(function(path){
path.basename = path.basename.replace(/^_/, '');
return path;
// required where the string begins with _ , meaning that sass won't compile it (bootstrap)
}))
.pipe(sass({onError: function(e) { console.log(e); } }))
.pipe(gulp.dest(paths.dist_styles));
});
gulp.task('compile_bower_css', function(){
var cssFiles = mainBowerFiles('**/*.css');
return gulp.src(cssFiles)
.pipe(gulp.dest(paths.dist_styles));
});
gulp.task('compile_sass', ['compile_bower_sass'], function () {
return gulp.src(paths.scss_files, {base:'src'})
.pipe(sass({outputStyle: 'compressed'})
.on('error', sass.logError))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(paths.dist))
});
Im now ending up with
file to import not found or unreadable: font-awesome
In my dist style folder I can see font-awesome.css has been generated. I am pretty new at gulp and sass compilation, so no doubt I have misunderstood something here.
When the #import statement is used, is the file looking for that named scss or css file?
I have been having the same issue (using a mac with Sierra) and it seemed to only happen when I was using the glob style of including.
It turns out it is due to a race condition, you can work around it by putting a short wait in like so...
var gulp = require('gulp');
var sass = require('gulp-sass');
var wait = require('gulp-wait');
gulp.task('scss', function () {
gulp.src('resources/scss/**/*.scss')
.pipe(wait(200))
.pipe(sass())
.pipe(gulp.dest('public/dist'));
});
Add line breaks between the #import lines.
I tried many other solutions, some suggested it's a SublimeText issue having to do with setting "atomic_save": true, that didn't work for me.
I even tried adding a .pipe(wait(500)). Didn't work either.
Then I just added a line break before the offending #import. So in your case if it's throwing an error regarding top_menu, put a line break so it becomes:
#import 'custom_bootstrap';
#import 'top_menu';
I have no idea why, but this is the only thing that worked for me.
As best-practice I would add line breaks between all the lines just in case.
I've tried to recreate the issue you're having, but for me it seems to run fine.
I'll attach my code, and a shot of the folder structure to compare.
The only omission is the ['compile_bower_sass'] part, as I'm not totally sure what you need here. Is it possible that's something that should be using a loadPath instead?
You'll also notice from the screenshot of the folders that your scss files are getting copied over to dist as well. This may not be desirable.
Here's the Gulp code:
var gulp = require('gulp');
var sass = require('gulp-sass');
var minifycss = require('gulp-minify-css');
var rename = require('gulp-rename');
var gutil = require('gulp-util');
var paths = {
scss_files: './src/assets/styles/**/*.scss',
dist: './dist'
};
gulp.task('compile_sass', function () {
return gulp.src(paths.scss_files, {base:'src'})
.pipe(gulp.dest(paths.dist))
.on('error', gutil.log)
.pipe(sass().on('error', sass.logError))
.pipe(minifycss({
keepSpecialComments: false,
removeEmpty: true
}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(paths.dist))
});
Here's the folders:
http://take.ms/AOFND
Perhaps all you need is:
var gulp = require('gulp');
var sass = require('gulp-sass');
var rename = require('gulp-rename');
var paths = {
scss_files: './src/assets/styles/**/*.scss',
dist: './dist'
};
gulp.task('compile_sass', function () {
return gulp.src(paths.scss_files, {base:'src'})
.pipe(sass({outputStyle: 'compressed'})
.on('error', sass.logError))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(paths.dist))
});
I was getting the error trying to migrate from Gulp 3.9.1 to 4.0.2, which requires a different way of setting up the gulpfile.js. I tried the line breaks in my file and also the wait just incase it was a race condition.
Utilizing gulp-plumber, it took away the error and my compiling of sass was successful.
function compile_sass() {
return gulp
.src('./wwwroot/css/**/*.scss')
.pipe(plumber())
.pipe(sass())
.pipe(gulp.dest("./wwwroot/css"));
}
The important part was the
.pipe(plumber())

Combining SCSS and SASS syntax with Gulp?

This is the first time I use a Taskrunner but I've used Sass a lot and I really like the Sass syntax rather than the SCSS syntax. However, I want to use the Bourbon library in my new project and it's written with SCSS, so it doesn't compile for me if I don't have all of my CSS written in SCSS, since I only compile the files with the .sass ending. Is there a way to compile both or to use some other gulp plugin that does this? I've never had this problem using Compass, Codekit or the Sass compiler that's built into Jekyll. I attached my code and remember that I'm new to this, so feel free to point out if I've done some stupid decisions or if there's something that looks weird, I'd love to improve.
var gulp = require('gulp'),
browserify = require('gulp-browserify'),
sass = require('gulp-sass'),
browserSync = require('browser-sync'),
reload = browserSync.reload;
//Tasks regarding scripts--------------------------------------------------|
gulp.task('scripts', function(){
// Single entry point to browserify
gulp.src('vendor/scripts/main.js')
.pipe(browserify({
insertGlobals : true,
debug : !gulp.env.production
}))
.pipe(gulp.dest('./dist/js'))
console.log("This is reloaded");
});
//Tasks regarding styles----------------------------------------------------|
gulp.task('sass', function(){
gulp.src('vendor/styles/**/*.scss')
.pipe(sass({
outputStyle: 'nested',
onError: console.error.bind(console, 'Sass error:')
}))
.pipe(gulp.dest('./dist/css'))
});
//Live reload--------------------------------------------------------------------|
gulp.task('serve', ['scripts','sass'], function () {
gulp.watch([
'dist/**/*'
]).on('change', reload);
gulp.watch('vendor/styles/**/*.scss', ['sass']);
gulp.watch('vendor/scripts/*.js', ['scripts']);
browserSync({
notify: false,
port: 9000,
server: {
baseDir: ['.tmp', 'dist'],
routes: {
'/bower_components': 'bower_components'
}
}
});
});
gulp-sass is based on libsass, the native C implementation of Sass, and libsass is well known to have issues with different syntaxes. I'd recommend using the plugin gulp-ruby-sass to fall back on the original Ruby implementation. The one you also use with Codekit, Compass, and so on. Be aware that gulp-ruby-sass has a different interface:
var sass = require('gulp-ruby-sass');
gulp.task('sass', function(){
return sass('vendor/styles/**/*.scss')
.pipe(gulp.dest('./dist/css'))
});
It's a lot slower that gulp-sass, but you won't come into such issues since there's still a huge difference between those implementations.
Btw: Good turn on your first Gulpfile! Just make sure to return streams in your subtasks so Gulp knows how to orchestrate them (just place a return statement before gulp.src)
According to
https://css-tricks.com/gulp-for-beginners/
You just need to change
/*.scss to *.+(scss|sass)
The plus + and parentheses () allows Gulp to match multiple patterns, with different patterns separated by the pipe | character. In this case, Gulp will match any file ending with .scss or .sass in the root folder.
This are my plugins:
// Load plugins
var gulp = require('gulp'),
sass = require('gulp-ruby-sass'),
autoprefixer = require('gulp-autoprefixer'),
cssnano = require('gulp-cssnano'),
jshint = require('gulp-jshint'),
uglify = require('gulp-uglify'),
imagemin = require('gulp-imagemin'),
haml = require('gulp-ruby-haml'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
notify = require('gulp-notify'),
cache = require('gulp-cache'),
livereload = require('gulp-livereload'),
coffee = require('gulp-coffee'),
gutil = require('gulp-util'),
slim = require("gulp-slim"),
del = require('del');
This worked for me:
// Styles
gulp.task('styles', function() {
return sass('src/styles/**/*.+(scss|sass)', { style: 'expanded' })
.pipe(autoprefixer('last 2 version'))
.pipe(gulp.dest('dist/css'))
.pipe(rename({ suffix: '.min' }))
.pipe(cssnano())
.pipe(gulp.dest('dist/css'));
});

Gulp, Compass and LiveReload - no style injection, page always reloads

Everything is almost working, compass is compiling the CSS and a few other tasks are running to minify, rename, rev etc. The problem is that when a style change occurs LiveReload is reloading the page instead of injecting the style. If I switch back to compass watch then style injection occurs. Is it possible to have style injection with Gulp, Compass and LiveReload? I hope so because if not I will have to run compass watch in 1 terminal and gulp in another which seems a bit clunky. Here is the relevant code from the gulpfile.js
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat'),
compass = require('gulp-compass'),
minifyCSS = require('gulp-minify-css'),
rev = require('gulp-rev'),
rename = require('gulp-rename'),
clean = require('gulp-clean'),
lr = require('tiny-lr'),
server = lr(),
livereload = require('gulp-livereload');
gulp.task('compass', function() {
gulp.src('./static/scss/*.scss')
.pipe(compass({
css: 'static/css',
sass: 'static/scss',
image: 'static/images',
font: 'static/fonts',
javascript: 'static/js',
comments: false,
style: 'expanded',
bundle_exec: true,
require: ['wegowise_styles/compass']
}))
.on('error', function(err) {})
.pipe(gulp.dest('./static/css/'))
.pipe(livereload(server))
.pipe(minifyCSS())
.pipe(rename({suffix: '.min'}))
.pipe(rev())
.pipe(gulp.dest('./static/production/'))
.pipe(rev.manifest())
.pipe(rename('css-manifest.json'))
.pipe(gulp.dest('./static/production/'));
});
gulp.task('clean', function() {
return gulp.src(['static/production'], {read: false})
.pipe(clean());
});
gulp.task('watch', function() {
gulp.watch('static/scss/**/*.scss', ['compass']);
gulp.watch('static/js/**/*.js', ['scripts']);
});
gulp.task('default', ['clean', 'watch']);
ps. I am using the LiveReload chrome extension
Yes, it is possible. I haven't seem in your code (maybe because you removed the rest of the file) when you start tiny-lr, i.e.:
var gutil = require('gulp-util');
gulp.task('tiny', function(next) {
server.listen(35729, function() {
gutil.log('Server listening on port: ', gutil.colors.magenta(port));
next();
});
});
// add as a dependency in your watch task
gulp.task('watch', ['tiny'], function() {
gulp.watch('static/scss/**/*.scss', ['compass']);
gulp.watch('static/js/**/*.js', ['scripts']);
});
The error might be related to the scripts task as well, so maybe include it in the question so we can take a look. Maybe, finally, there is some other task causing the issue.
In order to be sure, I just created a test here, and created a index.html file inside the static folder, pointing to css/file.css.
Created a simple static/scss/file.scss with a body background-color. I've used the same code snippet you provided for the rest of the gulpfile.
Also created a node-static server and served all files under static/ folder.
At the end, is there any other automated task involved in the building process?

Resources