12

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?

mindparse
  • 6,115
  • 27
  • 90
  • 191
  • I found the problem I was having: one file `scss` was prefixed with double underline `__` (because I use automatic css folder globbing elsewhere) and for a bizarre reasons files which starts with double `__` cannot be imported it would seem. – vsync Mar 16 '16 at 11:17
  • Are you using VS Code by any chance? – harvzor Sep 22 '18 at 10:04

4 Answers4

9

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'));
});
synkyo
  • 430
  • 5
  • 17
7

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.

Max S.
  • 1,383
  • 14
  • 25
0

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))
});
mistermist
  • 123
  • 1
  • 8
  • Thanks for you comments, I am working from a gulp file that was configured by someone else, and I wonder if this task needs further tweaking. See my latest comments, I am thinking the order of what is happening in the task needs attention?! – mindparse Jun 29 '15 at 10:51
  • Why do the imported SCSS files need to be compiled first when you are importing them into a single file? See edit to answer for possible better solution. – mistermist Jun 29 '15 at 11:09
  • I see what you are saying, see my latest edit. This task I am running requires another task to be run first, which compiles some bower css files used in my main.scss file. The person who originally wrote the gulp file has split our sass compilation into two tasks, one for the bower libs and one for our own. Im ending up with an error loading one of these bower sass files now, Im probably making this way more difficult than it needs to be! – mindparse Jun 29 '15 at 11:31
  • If all your SCSS files are going to wind up being in your main.scss file, then why bother compiling them beforehand? – mistermist Jun 29 '15 at 13:11
  • Simply by @importing them at the top of your main.scss file their content will be available for use. – mistermist Jun 29 '15 at 13:18
  • Did you get this sorted? – mistermist Jun 30 '15 at 12:26
  • 2
    Have you found a solution? – mistermist Jul 08 '15 at 20:49
  • @mindparse i think this is the right answer, first you have that task in Gulp with the ``` .pipe(gulp.dest(paths.dist))```duplicated, i think you should remove the first one, because you set the destination when the files are finally compiled. Second you have a lot of files without underscore _ in the name, Sass need to now what files are partials and what doesn't. If still failing probably is something in your main scss files with the @imports, can you paste that file ? and recreate the folder structure ? – Héctor León May 30 '16 at 10:40
0

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())

JoeCo
  • 695
  • 6
  • 13