With Grunt, how can I compile all *.less files, if I have global mixins and constants?

1.2k Views Asked by At

I want to organize my HTML, JS, and LESS by module. I'm already using Grunt to compile *.js and *.html from my source folders.

So I configured grunt as follows:

grunt.initConfig({
    less: {
        ALL: {
             files: { 'compiled.css': '**/*.less' }
        }
    }
}

But this runs into a major problem: constants and mixins from my /helper/*.less files are not accessible to other .less files.
It seems like grunt-contrib-less compiles each individual .less file, and then combines the output, but doesn't compile anything "globally".

The only solution I can think of is to create and maintain a master.less that @imports each individual .less file. But I'm trying to achieve an extremely modular build process, and I don't have to list any HTML or JS files, so I'm really hoping to find a *.less solution too!

2

There are 2 best solutions below

0
On BEST ANSWER

Thanks to @seven-phases-max for the following answer!

less-plugin-glob

Allows you to use wildcards in @import statements! Works perfectly!

// master.less
@import "helpers/**/*.less";
@import "modules/**/*.less";

And all you need to add to your Grunt configuration is the plugins option:

// Gruntfile.js
grunt.initConfig({
    less: {
        'MASTER': {
            src: 'master.less',
            dest: 'master.css',
            options: {
                plugins: [ require('less-plugin-glob') ]
            }
        }
    }
});

And, don't forget, npm install less-plugin-glob.

0
On

Here's one way to achieve an effortless development experience.
However, it requires a generated file and a custom task.

Auto-generate the master.less file

Create a task that generates master.less by writing an @import statement for each *.less file:

grunt.registerTask('generate-master-less', '', function() {
    generateFileList({
        srcCwd: 'modules',
        src: '**/*.less',
        dest: 'less/master.less',
        header: '// THIS FILE IS AUTOMATICALLY GENERATED BY grunt generate-master-less\n',
        footer: '// THIS FILE IS AUTOMATICALLY GENERATED BY grunt generate-master-less\n',
        template: '@import "<%= filename %>";\n',
        join: ''
    });
});

function generateFileList(options) {
    var _ = grunt.util._;
    var files = grunt.file.expand({ cwd: options.srcCwd }, options.src);

    var results = files.map(function (filename) {
        return _.template(options.template, { 'filename': filename });
    });
    var result = options.header + results.join(options.join) + options.footer;
    grunt.file.write(options.dest, result);
}

Then, use grunt-contrib-less to just build master.less.