I have used LESS to implement theming in my application and using nodejs less module to compiling less files to CSS but its not working in one particular scenario.
I am also using Bootstrap for my application and using Bootstrap less source code I am compiling only that css which I want in my application.
I can also override Bootstrap variables and mixins in my various themes. So, while compiling Bootstrap I need to consider my theme variables and mixins as well.
So, differentiate Bootstrap variables/mixins and CSS rules I have created 2 different files,
Directory structure For the application
|
|--sample_application
|--resources
| |--libraries
| |--bootstrap
| |--css
| | |--application.less
| |--less
| | |--application_variables.less
|--themes
|--red
| |--mixins
| | |--mixins.less
| |--variables
| | |--variables.less
| |--red.less
|--blue
| |--mixins
| | |--mixins.less
| |--variables
| | |--variables.less
| |--blue.less
|--themes.less
Explanation of which file contains what?
1. /sample_application/themes/<-theme_name->/mixins/mixins.less :- This file contains all application specific mixins and overridden bootstrap mixins.
2. /sample_application/themes/<-theme_name->/variables/variables.less :- This file contains all application specific variables and overridden bootstrap variables.
3. /sample_application/themes/<-theme_name->/<-theme_name->.less :- This file contains file imports of mixins and variables for that particular theme.
@import "./variables/variables";
@import "./mixins/mixins";
4. /sample_application/themes/theme.less :- This file contains two file imports. First one for Bootstrap variables which is application_variables.less and second one for particular themes' base file imports for eg. red.less/blue.less
@import "application_variables.less";
@import "red/red.less";
5. /sample_application/resources/libraries/bootstrap/css/application.less :- This file contains one file import which is /themes/themes.less and all required Bootstrap CSS Rules.
@import "theme.less";
/*Bootstrap CSS rules*/
6. /sample_application/resources/libraries/bootstrap/less/application_variables.less :- This file contains all required Bootstrap variables and mixins.
Now I have one node script file which dose the bootstrap less compilation which is compile-bootstrap.js
var fs = require("fs");
var less = require('less');
(function() {
var bsLessContent = fs.readFileSync("sample_application/resources/libraries/bootstrap/css/application.less");
less.render(bsLessContent.toString(), {
paths : [ "sample_application/themes/", "sample_application/resources/libraries/bootstrap/less/"],
compress : true
}, function(e, output) {
fs.writeFileSync("sample_application/resources/libraries/bootstrap/css/application.css", output);
});
})();
But when I run this script I am getting following error
{ [Error: 'application_variables.less' wasn't found]
type: 'File',
message: '\'application_variables.less\' wasn\'t found',
filename: 'sample_application\\themes\\theme.less',
index: 18,
line: 2,
callLine: NaN,
callExtract: undefined,
column: 0,
extract:
[ '@import "application_variables.less";',
'@import "red/red.less";' ] }
Then I tried using relative paths as well but still its giving the same error
{ [Error: './../resources/libraries/bootstrap/less/application_variables.less' wasn't found]
type: 'File',
message: '\'./../resources/libraries/bootstrap/less/application_variables.less\' wasn\'t found',
filename: 'sample_application\\themes\\theme.less',
index: 18,
line: 2,
callLine: NaN,
callExtract: undefined,
column: 0,
extract:
[ '@import "./../resources/libraries/bootstrap/less/application_variables.less";',
'@import "red/red.less";' ] }
Note that since the source is supplied to the compiler as a string you need to explicitly set the original file path so the compiler can use it as the base one for imports and so, otherwise it just can't know what are all those paths you specify are relative to (most likely it will use just cwd
but it's pretty much "random" at the time it actually comes to imports and it does not necessary point to your project root anymore...). E.g.:
var fs = require('fs'),
path = require('path'),
less = require('less');
(function() {
var src = "foo/bar/baz.less";
less.render(fs.readFileSync(src).toString(), {
filename: path.resolve(src), // <- here we go
}, function(e, output) {
console.log(output.css);
});
})();
The same goes for the paths
option, if I'm not mistaken in this case they should be either absolute or relative to the filename
. In general it's a good idea to learn how lessc
itself handles these things.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With