Gulp Sass not compiling partials

7k views Asked by At

So I am using Gulp Sass with gulp-changed (i've also tried gulp-newer with the updated syntax changes) and watching all the scss files in my folders.

When I change a base scss file it will compile without any problems.

However if I change a partial it won't compile the sass file that has a dependency on that partial.

Gulp

var SRC = './stylesheets/**/*.scss';
var DEST = './stylesheets';
gulp.task('sass', function() {
  return gulp.src(SRC)
    .pipe(changed(DEST, { extension: '.css' }))
    .pipe(plumber({
        errorHandler: handleErrors
    }))
    .pipe(sourcemaps.init())
    .pipe(sass({
            includePaths: [
                'C:/var/www/mobile 2/stylesheets'
    ]}))
    .pipe(sourcemaps.write('./'))
    .on('error', handleErrors)
    .pipe(gulp.dest(DEST))
});

Folders

├── scss
│    └── base.scss
│          ├── _partial1.scss
│          └── _partial2.scss
│          └── anotherBase.scss
│                 ├── _anotherBasePartial1.scss
│                 └── _anotherBasePartial2.scss

Making changes to base.scss || anotherBase.scss changes made, making changes to partial1.scss nothing.

As you can see in the log:

[15:14:02] Starting 'sass'... //here i changed _partial1.scss
[15:14:03] Finished 'sass' after 248 ms
[15:18:20] Starting 'sass'...
[15:18:20] Finished 'sass' after 289 ms
[BS] File changed: c:\var\www\mobile 2\stylesheets\sitescss\responsive\tools\base.css
[15:18:24] Starting 'sass'...
[15:18:24] Finished 'sass' after 289 ms
[BS] File changed: c:\var\www\mobile 2\stylesheets\sitescss\responsive\tools\anotherBase.css

I would like it to compile the scss whenever a partial is changed.

6

There are 6 answers

3
chrisdhanaraj On

This might have more to do with how you're including the partials than anything else - have your @imported the partials into your base sass file?

i.e., does base.scss have

@import 'partial1';
@import 'partial2';

Somewhere in there?

EDIT

Okay I just ran into a similar issue, I ended up just using gulp-newer + looping through an array to generate the gulp tasks. So it looked something like

var sassMain = ['base', 'anotherBase'];
sassMain.forEach(current, function() {
    var src = current + '.scss';        

    return gulp.src(src)
      .pipe(newer(destination)
      .pipe(plumber())
      .pipe(sass())
      .pipe(gulp.dest(destination))
});

Not really the most flexible thing in the world (especially with nested directories for the base url), but kind of gets where you want to be. gulp-cached also almost gets where you want to be without this trickery, but has the same won't-compile-partials issue.

1
marblewraith On

https://www.npmjs.com/package/gulp-changed

By default it's only able to detect whether files in the stream changed.

I'm guessing you probably want this: https://github.com/floatdrop/gulp-watch

0
Md. A. Barik On

This is an excellent question. I had faced this problem and get rid of that after a huge amount of time. Because there was no such things I found online at that time to get rid of that.

  • sass

    • abstracts
      • _base.scss
    • base
    • components
    • layout
    • pages
    • themes
    • vendors
  • main.scss

main.scss

@import 'sass/abstracts/base';

const gulp = require('gulp');
const sass = require('gulp-sass');
const rename = require('gulp-rename');
const browserSync = require('browser-sync');
const gulpSequence = require('gulp-sequence');
const sassInheritance = require('gulp-sass-inheritance');
const filter = require('gulp-filter');
var cached = require('gulp-cached');
var gulpif = require('gulp-if');


gulp.task('sass', function() {
    return gulp.src('sass/main.scss')

    
    //filter out unchanged scss files, only works when watching
    .pipe(gulpif(global.isWatching, cached('sass')))
 
    //find files that depend on the files that have changed
    .pipe(sassInheritance({dir: 'sass'}))
    
    .pipe(filter(function (file) {
        return !/\//.test(file.path) || !/^_/.test(file.relative);
      }))


    .pipe(sass())
    .pipe(rename('style.compile.css'))
    .pipe(gulp.dest('css/'))
    .pipe(browserSync.stream());
})

gulp.task('serve', ['sass'], function () {
    browserSync.init(
        {
            server: "./"
        }
    );

    gulp.watch('sass/abstracts/**/*.scss', ['sass']);;
    gulp.watch('index.html').on('change', browserSync.reload);
});

Run gulp serve.

0
AudioBubble On

A bit late for the show, but if I understand you right; you want to run your build when you change ANY scss file, whether that being a partial or not, right? (but not including the partials in the build itself – as that is handled by sass @import).

I normally use this approach:

var scss_source = [ 'path/to/scss' ],
    partials_source = [ 'path/to/partials' ];

gulp.task('scss', function () {
    gulp.src( scss_source )
    ...
});

var scss_watcher = gulp.watch([ scss_source, partials_source ], [ 'scss' ]);

I pass only the scss_source to the build, but BOTH sources to the watcher. That way I can seperate all partials from the rest of the scss sources, but have changes to any of the files trigger a build. And I don't have to include yet another module for handling this.

I usually keep my partials in separate directories (think shared, and not mixed with other scss files).

Hope this makes sense in your case – otherwise I do apologize.

0
Alex Shwarc On

I use https://github.com/vigetlabs/gulp-starter as a template with https://github.com/berstend/gulp-sass-inheritance

It works but only with 2 levels of deep

var gulp            = require('gulp');
var debug           = require('gulp-debug');
var browserSync     = require('browser-sync');
var sass            = require('gulp-sass');
var sourcemaps      = require('gulp-sourcemaps');
var handleErrors    = require('../lib/handleErrors');
var autoprefixer    = require('gulp-autoprefixer');
var path            = require('path');
var cached          = require('gulp-cached');
var sassInheritance = require('gulp-sass-inheritance');
var gulpif          = require('gulp-if');
var filter          = require('gulp-filter');
var duration        = require('gulp-duration');
var notify          = require('gulp-notify');

var paths = {
    src : 'app/styles',
    dest: 'grails-app/assets'
}


var isPartial = function (file) {
    return /_/.test(file.relative);
}

//set global.isWatching = true on gulp watch

gulp.task('css', function () {
    return gulp.src(paths.src)
        //.pipe(debug({title: 'before cache:'}))
        .pipe(gulpif(global.isWatching, cached('sass')))
        //.pipe(gulpif(global.isWatching, debug({title: 'after cache:'})))
        .pipe(gulpif(isPartial, sassInheritance({dir: path.join(config.root.src, config.tasks.css.src), debug: false}).on('error', handleErrors))) //,
        .pipe(debug({title: 'after sassInheritance:'}))         
        //.pipe(debug({title: 'after filter:'}))
        .pipe(sourcemaps.init())
        .pipe(sass()).on('error', handleErrors)
        .pipe(debug({title: 'after sass:'}))
        //.pipe(notify('Sass compiled <%= file.relative %>'))
        .pipe(autoprefixer(config.tasks.css.autoprefixer))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(paths.dest))
        //.pipe(duration('after sass'))
        .pipe(debug({title: 'before browserSync:'}))
        .pipe(browserSync.reload({stream: true}))
})
0
Elmar Höfinghoff On

try var SRC = './stylesheets/**/{*.scss,_*.scss}'; if partials lay in the same folder or a subfolder.