Setup gulp-sass to work like sass --watch - css

I am trying to migrate a project to gulp-sass workflow. After reading some tutorials online, I have setup a very basic gulpfile:
var gulp = require('gulp'),
sass = require('gulp-sass'),
concat = require('gulp-concat');
gulp.task('styles', function() {
return gulp.src('scss/*.scss')
.pipe(sass({
'sourcemap=none': true
}))
.pipe(gulp.dest('css/'))
});
gulp.task('watch', function() {
gulp.watch('scss/**/*.scss', ['styles']);
});
I want to generate a *.css file from every *.scss file that doesn't begin with underscore.
My problem: with current gulpfile, gulp will detect changes on .scss files and rebuild ALL libraries, instead of building only the ones which have been affected by the change.
For example, I have 2 libs on my project:
lib1, which #imports partials p1 and p2
lib2, which #imports partials p2 and p3
If I edit partial p1, I want only lib1 to be updated.
If I edit partial p3, I want only lib2 to be updated.
If I edit partial p2, I want both lib1 and lib2 to be updated.
Current setup updates both libs on every edit that I make in any of the *.scss sources.
In other words, I would like gulp-sass to behave the same way as sass --watch does. Is this possible? How?
thanks!

Currently you're targeting all scss files in your watch task:
gulp.watch('scss/**/*.scss', ['styles']);
You can narrow it down to a subfolder or to specific files. You can breakdown your watch task into 2 parts, for example:
gulp.watch('scss/p1/**/*.scss', ['stylesP1', 'stylesP2']);
gulp.watch('scss/p2/**/*.scss', ['stylesP2', 'stylesP3']);
And then create 2 style tasks to match:
gulp.task('stylesP1', function() { /* Your task actions */ });
gulp.task('stylesP2', function() { /* Your task actions */ });
gulp.task('stylesP3', function() { /* Your task actions */ });

Related

Gulpfile to turn sass to css starting but not finishing

I am very new to gulp and sass, but trying to create a gulpfile that will take and scss file and turn it into a css file (this seems like it is a very common thing that lots of people do). I am following along this tutorial - https://youtu.be/nusgoj74a3Y?t=1301 - but it seems to be a bit outdated.
My directory looks like this
-xxx
--gulpfile
--src
---Assets
----scss
-----default.scss
----css
My gulpfile looks like this:
'use strict';
//dependencies
var gulp = require('gulp');
var sass = require('gulp-sass');
var minifyCSS = require('gulp-clean-css');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var changed = require('gulp-changed');
//////////////////
// - SCSS/CSS - //
//////////////////
var SCSS_SRC = './src/Assets/scss/**/*.scss';
var SCSS_DEST = './src/Assets/css';
//compile css
gulp.task('compile_scss', function(){
gulp.src(SCSS_SRC)
.pipe(sass().on('error', sass.logError))
.pipe(minifyCSS())
.pipe(rename({ suffix: '.min' }))
.pipe(changed(SCSS_DEST))
.pipe(gulp.dest(SCSS_DEST));
});
//detect changes in SCSS
gulp.task('watch_scss', function() {
return gulp.watch(SCSS_SRC, gulp.series('compile_scss'));
});
//run tasks
gulp.task('default', gulp.series('watch_scss'));
and when I run it I get this:
[20:39:12] Using gulpfile ~/xxx/xxx/xxx/xxx/gulpfile.js
[20:39:12] Starting 'default'...
[20:39:12] Starting 'watch_scss'...
I believe it is supposed to finish these tasks not just start them.
Also I believe it is supposed to take the scss file from the scss directory and then put a css file in the css directory which it does not do.
Any help would be great. Thanks.
you are triggering a watch there, try modifying any of your scss files, and watch the terminal transpile to CSS ;)
you could add alternatively something like
gulp.task('getCSS', gulp.series('compile_scss'));
and then run gulp getCSS to get the CSS

Injecting SCSS variables with Node and Gulp

I want compile different css files based on different sass variables.
Im trying to use Gulp to achieve this
gulp.task('var 1', function() {
gulp.src(['styles/vars/var1.scss','styles/client.scss'])
.pipe(sass().on('error', sass.logError))
.pipe(concat('clientWithVar1.css'))
.pipe(gulp.dest('./public/'))
});
It doesnt seem to work and im getting a Sass error that a variable doesnt exist.
How can i achieve this? Any help is appreciated
You can try this way:
You have this dir structure:
- tmp (folder)
- _var1.scss
- _var2.scss
- client.scss
In client.scss add: #import "./tmp/var.scss
and add gulp task below, so you just copy and rename scss file with variables that you need and then you can compile your main scss file
var rename = require('gulp-rename');
gulp.task('copy', function() {
return gulp.src('./styles/_var1.scss')
.pipe(rename('var.scss'))
.pipe(gulp.dest('./styles/tmp'));
})
Assuming you've got a directory structure something like this:
vars/var1.scss
vars/var2.scss
vars/var3.scss
vars/var4.scss
styles/1/client.scss
styles/2/client.scss
styles/3/client.scss
styles/4/client.scss
And in each client.scss file you have a corresponding #import statement (e.g. #import "../../vars/var1/.scss";), you should be able to generate all stylesheets with a single task:
gulp.task('sass', function() {
gulp.src('styles/**/client.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./public/'))
});
I think this should end up with public/1/client.css, public/2/client.css etc, but you may have to tweak the gulp.dest line to suit.

Gulp CSS task not overwriting existing CSS

var paths = {
css: './public/apps/user/**/*.css'
}
var dest = {
css: './public/apps/user/css/'
}
// Minify and concat all css files
gulp.task('css', function(){
return gulp.src(paths.css)
.pipe(concatCSS('style.css'))
.pipe(minifyCSS({keepSpecialComments: 1}))
.pipe(rename({
suffix: '.min'
}))
.pipe(gulp.dest(dest.css))
});
When I first run the task it compiles alright and all changes are there.
After I change something and run it again it doesn't overwrite the existing minified css file. If I were to delete the minified css and run task again everything works perfect. Any insights?
Try and set the exact path, not a variable. Not that its not a good practice, just try without it.
Also , add a 'use strict'; to your task, so that you can be sure there are no serious errors with your settings. It will give you the right type of errors if there are any.
And, may I ask why are you concatenating your CSS before the production build?
Every file concatenation, minification and etc. should be performed in the 'build' task.
You have to delete your minified version of css before doing minify css.
To achieve this you can use gulp-clean
install gulp-clean as npm install gulp-clean
var gulp = require('gulp'),
concat = require('gulp-concat'),
cleanCSS = require('gulp-clean-css'), // this is to minify css
clean = require('gulp-clean'), //this is to delete files
gulp.task('del-custom-css', function(){
return gulp.src('./static/custom/css/custom.min.css',{force: true})
.pipe(clean())
});
gulp.task('minify-custom-css', ['del-custom-css'], function(){
return gulp.src(['./static/custom/css/*.css'])
.pipe(concat('custom.min.css'))
.pipe(cleanCSS())
.pipe(gulp.dest('./static/custom/css'))
});
Hope it helps.

Compile each SASS file with Gulp, creating multiple CSS files

I have the need to compile a SASS file to a CSS file when saved, without having to compile every SASS file to a single CSS file.
I need the ability to:
- Run a 'watch' on a directory
- If a file is saved, a CSS of it's name is created. Example: 'main.scss' compiles to 'main.css'.
- It should not compile every single SASS if it doesn't need to.
The goal is to optimize the development process to avoid compiling every single SASS file in a directory when 'watching'.
My current SASS task looks a bit like this and results in a single CSS file:
//Compile Sass
gulp.task('styles', function() {
return gulp.src('app/scss/styles.scss')
.pipe(plugins.sass({ includePaths : [paths.sass], style: 'compressed'})
.pipe(plugins.autoprefixer('last 2 version'))
.pipe(plugins.rename({suffix: '.min'}))
.pipe(plugins.minifyCss())
.pipe(gulp.dest('build/css'));
});
Looks like gulp-changed is what you're looking for:
https://github.com/sindresorhus/gulp-changed
You add it as a dependency with npm install --save-dev gulp-changed and plug it into your gulpfile. From the gulp-changed ReadMe:
var gulp = require('gulp');
var changed = require('gulp-changed');
var ngAnnotate = require('gulp-ng-annotate'); // just as an example
var SRC = 'src/*.js';
var DEST = 'dist';
gulp.task('default', function () {
return gulp.src(SRC)
.pipe(changed(DEST))
// ngAnnotate will only get the files that
// changed since the last time it was run
.pipe(ngAnnotate())
.pipe(gulp.dest(DEST));
});

Gulp minify-css only for distribution

How can I minify CSS generated from LESS only to 'dist' folder? Of course all gulp plugins are corretly installed. Everything goes OK except minifying CSS.
Here is my code:
gulp.task('styles', function () {
return gulp.src('app/less/*.less')
.pipe($.less())
.pipe(gulp.dest('.tmp/styles'));
.pipe(minifyCSS({keepBreaks:false}))
.pipe(gulp.dest('dist/styles'));
});
If I move .pipe(minifyCSS({keepBreaks:false})) one line above it works. But I need to have compressed CSS only in dist forlder.
Thanks for advice.
It might not be the best way, but I use two different gulp tasks. One task that compiles the CSS into my build directory and then another task takes that output and minifies it into my dist directory. Use a task dependency to ensure that the file gets built before the minify task runs.
gulp.task('styles', function() {
return gulp.src(styles)
.pipe(concat('app.less'))
.pipe(gulp.dest('./build/styles'))
.pipe(less())
.on('error', console.log)
.pipe(concat('app.css'))
.pipe(gulp.dest('./build/styles'));
});
gulp.task('styles-dist', ['styles'], function() {
return gulp.src('build/styles/app.css')
.pipe(minifycss())
.pipe(gulp.dest('./dist/styles'));
});

Resources