Grunt - scss is not compiled - gruntFile.js

804 Views Asked by At

(Beginner post)

I used Grunt for this tree :

Gruntfile.js :

module.exports = function(grunt) {
    grunt.initConfig({
        sass: {
            dist: {
                options: {
                    style: 'expanded'
                },
                files: {
                    'css/style.css': 'Component/**/*.scss',
                }
            }
        },
        watch: {
            css: {
                files: 'Component/**/*.scss',
                tasks: ['sass']
            },
        },
    });
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default',['watch']);
}

It runs without any errors, but it don't take any file. The style.css still empty.

When I replace this line :

files: {
    'css/style.css': 'Component/**/*.scss',
}

with :

files: {
    'css/style.css': 'Component/header/header.scss',
}

Its takes the .css file in header/ correctly.

I don't have any error with either of these two syntaxes.

Any idea ?

1

There are 1 best solutions below

16
muecas On BEST ANSWER

You need to use the grunt files pattern to get all the files recursively in the sources folder:

module.exports = function(grunt) {
    grunt.initConfig({
        sass: {
            dist: {
                options: {
                    style: 'expanded'
                },
                files: [{
                    expand: true,
                    cwd: 'Component/',
                    src: ['**/*.scss'],
                    dest: 'css/',
                    ext: '.css'
               }]
            }
        },
        watch: {
            css: {
                files: ['Component/**/*.scss'],
                tasks: ['sass']
            },
        },
    });
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default',['watch']);
}

To use Grunt file patterns you need to specify an object with options instead of the default setting in the form of 'destination': 'source'. The file pattern object has the following options:

{

    // source directory 
    cwd: String,

    // creates the subdirectories or flatten the content to the destination directory
    flatten: Boolean,

    // remove anything and after the file extension and replace with the ext String
    ext: String,

    // destination folder
    dest: String,

    // source file pattern using minimatch to match files
    src: String|Array

}

More about Grunt file patterns and minimatch file matching patterns.

Edit to achieve the desired result (have all the components compiled in to a single file), you will need to do the following:

  1. Change the filenames of all of your components, for example change Component/header/header.scss to Component/header/_header.scss. Files prefixed with _ will not create any output (Sass default behavior).
  2. Then create a bootstrap file (let's call is style.scss, containing only the reference to the files you want to merge in to your output css file. For each file add @import 'header/header'; for header/_header.scss. You don't need to add the extension or the _ prefix.
  3. Change the files definition of you sass:dist task to: { 'css/style.css' : ['Component/style.scss'] }

Gruntfile.js will now look like this:

module.exports = function(grunt) {
    grunt.initConfig({
        sass: {
            dist: {
                options: {
                    style: 'expanded'
                },
                files: { 'css/style.css' : ['Component/style.scss'] }
            }
        },
        watch: {
            css: {
                files: ['Component/**/*.scss'],
                tasks: ['sass']
            },
        },
    });
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default',['watch']);
}

That will compile Component/style.scss (containing the reference to all your components files) in to css/style.css.