4

I'm having trouble finding a solution to this problem. I have a less file app.less that only consists of @import statements. Now I want to generate a single less file that includes all imported less files, because I want to send it to the client to compile it there (yes, I have my reasons to do that).

So the less file should not be compiled in the grunt build step, but only concatenated, so that the client doesn't have to load several less files. I feel that this is a usecase that should have appeared for others as well when compiling less on the client, but I couldn't find a single solution. I don't care if the concatenation happens with grunt-contrib-less or any other tool.

Peter
  • 621
  • 1
  • 6
  • 16
  • Use [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat). – Rene Korss Aug 04 '15 at 15:32
  • Ok, I suppose that's possible. But `grunt-contrib-concat` doesn't understand less' `@import`statements. Then I basically have to replace my `app.less` file with a `grunt-contrib-concat` configuration file, which I was looking to avoid. – Peter Aug 04 '15 at 15:42

2 Answers2

7

LESS docs says:

Use @import (inline) to include external files, but not process them.

See: Import At-Rules and @import (inline)

You could create new file, for example concatenate.less and import .less files with inline keyword. Then if you process it, it will work exactly like concatenation, no CSS is processed out of it.

concatenate.less

@import (inline) "file1.less"
@import (inline) "file2.less"
@import (inline) "file3.less"

And use your Grunt task like you used to, just rename output file extension to .less for clarity. Tested it, should give you exactly what you wanted.

Nested imports

As @seven-phases-max pointed out, that nested imports would be problem in this case.

Solution would be grunt-includes.

  • Use grunt-includes with includeRegexp option to create files listed in concatenate.less with already imported LESS files to some other folder.
  • Change concatenate.less files paths to that folder.
  • Run your LESS compiling Grunt task normally.
Rene Korss
  • 5,414
  • 3
  • 31
  • 38
  • Nice spot. I've never seen using of `(inline)` like this before (well, this has its problems of not supporting nested imports, but still very neat). – seven-phases-max Aug 04 '15 at 18:25
  • Thanks @seven-phases-max! Yes, nested imports would be problem with this. Hopefully @Peter dosen't have nested imports in this case. But I'll try to find any good solution for nesting. – Rene Korss Aug 04 '15 at 21:49
  • Thanks, that works indeed! And luckily I don't have any nested imports. – Peter Aug 05 '15 at 09:44
  • Actually I just realized what the downside of this is: Because the imported files are not being processed, all the comments remain in the concatenated less file, which makes it at least 20% longer than it needs to be. I'm now using [`grunt-stripcomments`](https://github.com/kkemple/grunt-stripcomments) to remove the comments. – Peter Aug 05 '15 at 11:49
  • Yes, it won't remove comments. It will just concatenate .less files, kust like you first asked. But nice solution. – Rene Korss Aug 05 '15 at 12:26
4

in case someone is working with gulp,

you can just create concatenate.less as @Rene Korss sugested, and use the same command as for compiling less.

Less outputs concatenate.css filename, which is misleading in our case, so I'm using gulp-rename to have filename named as I want.

var src = 'path-to-concatenate-less-file';
var destination = 'path-to-destination';
gulp.task('concatenate-styles', function () {
    var compile= gulp.src(src)
    .pipe(less())
    .pipe(rename('concatenate-all.less'))
    .pipe(gulp.dest(destination))
    .pipe(notify("Saved file: <%= file.relative %>!"));
    compile.on('error', console.error.bind(console));
    return compile;
});

Example of concatenate.less:

@import (inline) "general.less";
@import (inline) "typography.less";
Angel M.
  • 2,692
  • 2
  • 32
  • 43