Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

less.render is not working in nodejs with multiple import files which are in different directories

Tags:

node.js

less

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,

  • application_variables.less - It contains all required Bootstrap variables and mixins
  • application.less - It contains all required Bootstrap CSS Rules

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";' ] }
like image 214
Virbhadrasinh Avatar asked Mar 17 '23 14:03

Virbhadrasinh


1 Answers

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.

like image 110
seven-phases-max Avatar answered Apr 08 '23 15:04

seven-phases-max