4

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!

Scott Rippey
  • 15,614
  • 5
  • 70
  • 85
  • Well, yes, If you want your partials to became compilable they *must* import required stuff. Things like `/**/*.less` are for compiling multiple *independed* stylesheets (and for that reason it just *can't* implicitly share anything between those files). – seven-phases-max May 27 '15 at 01:16
  • I updated my question with a sample config. Long story short, `*.less` does compile to a single output file, but it seems to simply combine the results from the individual compiled files. I'm looking for any sort of `*.less` solution, if you can think of any? – Scott Rippey May 27 '15 at 04:39
  • Does this help you? http://stackoverflow.com/questions/3538605/join-two-less-files-into-one-css-file – sobolevn May 27 '15 at 05:38
  • @sobolevn That's what I mentioned in my last paragraph. I was hoping that I wouldn't have to maintain a list of `@import` statements, because it'd be great for development to just go create some new files, and the build process would automatically pick them up. – Scott Rippey May 27 '15 at 05:44
  • 1
    [`less-plugin-glob`](https://github.com/just-boris/less-plugin-glob). – seven-phases-max May 27 '15 at 08:01
  • @seven-phases-max Hey, post your comment as an answer if you want me to upvote it! That looks like it might be the right answer! – Scott Rippey May 27 '15 at 16:42
  • Ah, feel free to append it to your own answer (an answer of 16 letters would be too strange). – seven-phases-max May 28 '15 at 01:11

2 Answers2

4

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.

Scott Rippey
  • 15,614
  • 5
  • 70
  • 85
2

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.

Scott Rippey
  • 15,614
  • 5
  • 70
  • 85