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

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

Related

Gulp task: pipe gulp-sass to postCSS doing nothing

I'm trying to:
Add vendor prefixes to SCSS
Compile to CSS
Minify it
With this gulp code:
const {src,dest} = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const autoprefixer = require('autoprefixer');
const sourcemaps= require('gulp-sourcemaps');
const postcss = require('gulp-postcss')
const postcssScss = require('postcss-scss')
function genCSS() {
return src(tpath.src.scss)
.pipe(sourcemaps.init()) //line in css, maps to source (file & line).
.pipe(postcss({plugins:[autoprefixer()], syntax:require('postcss-scss')}))
.pipe(sass.sync({outputStyle:'compressed'}).on('error', sass.logError))
.pipe(sourcemaps.write())
.pipe(dest(tpath.dest.scss)) //single index.css file
};
exports.genCSS=genCSS
But this is what postCSS logs, and indeed it is true:
You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.
On the linked page: https://www.postcss.parts/, there are Sass plugins but this is not a compiler so I'm confused.
What is the mistake and how could it be solved?
This
.pipe(postcss([autoprefixer()],{syntax:'postcss-scss'}))
should be:
.pipe(postcss([autoprefixer()],{syntax:'postcss-scss'}))
A few details:
If Config file is there, remove the options from postcss({...})
It runs faster without postcss-scss on the function argument (but it has to be imported), like so:
const postcssScss = require('postcss-scss') //keep this
.pipe(postcss([autoprefixer()])) //removed here
You can add cssnano and remove outputStyle:compressed but this will be slower (loading an extra package).

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.)"

Getting proper sourcemaps (gulp sass + cleanCss + prefixer + uncss)

What is best way to chain gulp for compiling sass into clean css (prefixed, un-CSSed and minified).
Following example creates sourcemaps, but they are pointing to wrong line numbers in source files when viewed in browser inspector.
var plugins = require('gulp-load-plugins')(),
bourbon = require('node-bourbon').includePaths,
neat = require('node-neat').includePaths;
gulp.task('default', function () {
return gulp.src('src/scss/**/*.scss')
.pipe(plugins.sourcemaps.init())
.pipe(plugins.sass({includePaths: bourbon, includePaths: neat}))
.on('error',plugins.util.log.bind(plugins.util, 'Sass Error'))
.pipe(plugins.concat('styles.css'))
.pipe(plugins.uncss({html: ['dist/**/*.html']}))
.pipe(plugins.autoprefixer())
.pipe(plugins.cleanCss())
.pipe(plugins.sourcemaps.write('.'))
.pipe(gulp.dest('dist/css/'));
});
In an attempt to fix this problem I tried to output sourcemaps before autoprefixer and cleanCss but it results in an error related to "Neat" and "Burbon" paths: Error: Broken #import declaration of "../neat" Broken #import declaration of "../colors" Broken #import declaration of "../variables" Broken #import declaration of "../grid" Broken #import declaration of "../tables"
i work with this task, using CSSO instead of your cleanCSS but use whatever you want, the tricky part is the sourcemaps, sometimes mess up the paths.
Declare a source path
Init SourceMaps
Compile SCSS into CSS
Add the right prefix support
Paste SourceMaps in the CSS file generated pointing to the SCSS files
Compress the CSS file ( this probably remove the sourcemaps unless you told package to save comments )
Declare a dest path
Gulpfile: SASS Task
const gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
csso = require('gulp-csso'),
sass = require('gulp-sass'),
sourcemaps = require('gulp-sourcemaps');
gulp.task('sass', ['sass'], () => {
return gulp
.src('src/scss/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({ browser: ['last 2 version', '> 5%'] }))
.pipe(sourcemaps.write())
.pipe(csso())
.pipe(gulp.dest('dist/css'));
});

How to configure gulp-sass properly?

Here is my gulpfile.
var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var babel = require("gulp-babel");
// Gulp Sass Task
gulp.task('sass', function () {
console.log('called');
// gulp.src locates the source files for the process.
// This globbing function tells gulp to use all files
// ending with .scss or .sass within the scss folder.
gulp.src("scss/*.scss")
// Converts Sass into CSS with Gulp Sass
.pipe(sass().on('error', sass.logError))
// Outputs CSS files in the css folder
.pipe(gulp.dest("css"));
});
// Watch scss folder for changes
gulp.task('watch', function() {
// Watches the scss folder for all .scss and .sass files
// If any file changes, run the sass task
gulp.watch('./scss/**/*.{scss,sass}', ['sass'])
});
gulp.task("transpile", function () {
return gulp.src("js/*.js")
.pipe(babel())
.pipe(gulp.dest("./compile"));
});
// Creating a default task
gulp.task('build', ['sass', 'transpile']);
gulp sass runs successfully but does not create any css folder which I am expecting. Also when I run the sass manually,
sass --trace _picker.scss:css/_picker.css
I see the css being compiled properly. Not sure what is going wrong with gulpfile. Any help would be really appreciated.

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

Resources