Combining SCSS and SASS syntax with Gulp? - sass

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'));
});

Related

Node-Sass includes the #use directive when compiling

I'm new to sass in general and am using gulp to watch my directory. However I realized that when my CSS Compiles from SASS it includes the #use directive at the top. For instance where I use sass:map this is brought over in the final file. I'm aware that it may just be of nuisance value right now. But wondering how to have them excluded.
Here is the gulpfile that I use for watching/compiling
var gulp = require("gulp");
var sass = require("gulp-sass");
var sassGlobbing = require("gulp-sass-glob");
sass.compiler = require("node-sass");
var paths = {
styles:{
src:"src/scss/**/*.scss",
dest: "assets/css/",
index: "src/scss/styles.scss"
}
}
gulp.task("sass", function(){
return gulp
.src(paths.styles.index)
.pipe(sassGlobbing())
.pipe(sass().on("error", sass.logError))
.pipe(gulp.dest(paths.styles.dest))
})
gulp.task("watch", function(){
gulp.watch(paths.styles.src, gulp.series("sass"))
})
According to this and I am just copying some lines from there
https://sass-lang.com/documentation/at-rules/import#importing-css
"Note that only Dart Sass currently supports #use. Users of other implementations must use the #import rule instead.)"

How do I use post-css to autoprefix SCSS without compiling to CSS?

I have a static site that is generated using Jekyll.
Directory structure:
| _sass/
|---| subfolder/
|---|---| _component-1.scss
|---|---| _component-2.scss etc
| css/
|---| main.scss
| _site/
|---| css/
|---|---| main.css
main.scss imports all my SCSS components into one file, and Jekyll compiles the SCSS into the 'source' directory (where the static site is generated) - _site.
I want to use an autoprefixer on my SCSS components. There are Jekyll plugins that do this, however I host the site on GitHub pages, which disables plugins for security reasons. I could use the plugin locally and then just push the _site directory to GitHub, but I don't want to use this option.
I want to use a Gulp task to autoprefix my SCSS components, without first compiling the SCSS to CSS. I want to simply autoprefix in my Gulp build step, and let the Jekyll build process take care of the SCSS compilation.
So I've changed the sass_dir in the Jekyll _config.yml file to be _gulped-sass (or whatever) instead of _sass, and tried the following gulp task:
var gulp = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var source = '_sass/**/*.scss';
var destination = '_gulped-sass';
gulp.task('autoprefixer', function() {
gulp.src(source)
.pipe(autoprefixer({
browsers: ['last 2 versions']
}))
.pipe(gulp.dest(destination));
});
..however this gives the error:
$ gulp autoprefixer
$ error: you tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser
Ok, so the docs for post-scss gives the useage as
var syntax = require('postcss-scss');
postcss(plugins).process(scss, { syntax: syntax }).then(function(result) {
result.content // SCSS with transformations
});
..and the docs for post-css give the useage as:
gulp.task('css', function () {
var postcss = require('gulp-postcss');
var sourcemaps = require('gulp-sourcemaps');
return gulp.src('src/**/*.css')
.pipe( sourcemaps.init() )
.pipe( postcss([ require('precss'), require('autoprefixer') ]) )
.pipe( sourcemaps.write('.') )
.pipe( gulp.dest('build/') );
});
I cannot work out from the docs how to use the postcss-scss parser in my Gulp task. I've tried many different combinations of the two examples from the docs, but none work.
So, how can I use post-css and/or post-scss in my Gulp task in order to autoprefix my SCSS without compiling it to CSS?
Figured it out. The post-scss parser (not plugin) can be assigned as the syntax property of an object passed as a second parameter to the postcss function. It starts to look really messy, but it works:
var gulp = require('gulp');
var source = '_sass/**/*.scss';
var destination = '_gulped-sass';
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
gulp.task('autoprefixer', function () {
return gulp.src(source)
.pipe(postcss([autoprefixer({
browsers: ['last 2 versions']
})], {
syntax: require('postcss-scss')
}))
.pipe(gulp.dest(destination));
});

Dealing with Gulp, Bundler, Ruby and Susy

According to this it's possible to compile susy install from Ruby with Gulp.
But is it possible to use gulp-sass instead of gulp-compass or gulp-ruby-sass because of performance and deprecation ?
Actually I use this in my gulpfile.js:
gulpfile
var gulp = require('gulp');
// Include plugins
var plugins = require('gulp-load-plugins')();
// Variables de chemins
var source = './sass/**/*.scss'; // dossier de travail
var destination = './css/'; // dossier à livrer
gulp.task('sasscompil', function () {
return gulp.src(source)
.pipe(plugins.sass({
outputStyle: 'compressed',
includePaths: ['/home/webmaster/vendor/bundle/gems/susy-2.2.2/sass']
}).on('error', sasscompil.logError))
.pipe(plugins.csscomb())
.pipe(plugins.cssbeautify({indent: ' '}))
.pipe(plugins.autoprefixer())
.pipe(gulp.dest(destination + ''));
});
But the error log doesn't work because sasscompil isn't define.
Then I need to give the path for all ex-compass includes like susy, sassy-button,etc..
is it possible to give a global path for gems ?
other thing, do I install gulp plugins despite of using gulp-load-plugins ? because gulp doesn't find plugins if I don't do that.
Thanks
You need to change sasscompil.logError to plugins.sass.logError
such that
gulpfile.js
gulp.task('sasscompil', function () {
return gulp.src(source)
.pipe(plugins.sass({
outputStyle: 'compressed',
includePaths: ['/home/webmaster/vendor/bundle/gems/susy-2.2.2/sass']
}).on('error', plugins.sass.logError))
...
});
gulp-sass doc:
Pass in options just like you would for node-sass; they will be passed along just as if you were using node-sass. Except for the data option which is used by gulp-sass internally. Using the file option is also unsupported and results in undefined behaviour that may change without notice.
example
gulp.task('sass', function () {
return gulp.src('./sass/**/*.scss')
.pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
.pipe(gulp.dest('./css'));
});

sass sourcemaps gulp task setup

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!

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