最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Get less variables list using less.js - Stack Overflow

programmeradmin3浏览0评论

I'm using client-side less.js. Is there a way to get all variables from my less file. I know how to modify variables:

less.modifyVars({
  "@var": "#fff"
});

But I want to get all of them, like (don't work):

var variables = less.getVars();

I'm using client-side less.js. Is there a way to get all variables from my less file. I know how to modify variables:

less.modifyVars({
  "@var": "#fff"
});

But I want to get all of them, like (don't work):

var variables = less.getVars();
Share Improve this question edited Dec 9, 2015 at 11:03 Dan Prince 30k14 gold badges93 silver badges122 bronze badges asked Dec 8, 2015 at 10:39 GenaGena 1,7972 gold badges15 silver badges19 bronze badges 4
  • 1 well all variables start with @ don't know if less offers something, but you can pretty much execute a regular expression and find all variables – Gntem Commented Dec 8, 2015 at 11:16
  • 1 Find where? I need to load them to variable for example – Gena Commented Dec 8, 2015 at 11:48
  • 7 Hmm, I don't understand why this maybe not ideal but still perfectly valid question was put on hold. Does at least one of close-voters have an idea of what Less is? I'm voting for re-opening. – seven-phases-max Commented Dec 8, 2015 at 12:49
  • 22 @seven-phases-max Possibly something to do with this meta post. – IKavanagh Commented Dec 8, 2015 at 13:58
Add a comment  | 

1 Answer 1

Reset to default 22

This is going to be an unconventional answer as it seems that this data isn't publicly exposed as part of the browser facing API.


tl;dr

  • Save a local copy of the less.js file.
  • Add this function definition somewhere

    function exposeVars(root) {
         var r=root._variables,n=Object.keys(r),m={}
         for(var k of n){m[k]=r[k].value}
             less.variables = m;
    }
    
  • Add the following call exposeVars(evaldRoot) just before return result on line ~2556.

  • Now less.variables contains all the variables from your file.

Disclaimer: Doing this is not a good idea! It's fine if you're just playing around, debugging or testing something, but don't depend on this hack for anything serious!


The basic aim here was to find the point in the source where the .less files are turned into abstract syntax trees (or some other formal structure).

Jumping straight into the source, I found a ParseTree class. It's a reasonable assumption to guess that it will contain the result of parsing the less file.

I wrote a quick test file and added it to the browser with the appropriate tag. It looks like this:

@myvar: red;
@othervar: 12px;

body {
  padding: @othervar;
  background: @myvar;
}

I've downloaded a local copy of less.js and added a breakpoint added to line 2556.

I had a poke around in the local scope to see what was available and found the variables in an object called evaldRoot.

evaldRoot = {
  _variables: {
    @myvar: {
      name: '@myvar',
      value: Color
    },
    @othervar: {
      name: '@othervar',
      value: Dimension
    }
  }
}

Next job was to work out where this data goes. It seems like the evaldRoot variable is used to generate the resulting CSS (which would make sense, as it contains information such as variables).

if (options.sourceMap) {
  sourceMapBuilder = new SourceMapBuilder(options.sourceMap);
  result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);
} else {
  result.css = evaldRoot.toCSS(toCSSOptions);
}

Whatever happens, the variables goes out of scope after it is used to generate a string of CSS as result.css.

To expose of these variables, the script needs a small modification. You'll have to expose the variables publicly somehow. Here's an example of doing that.

function exposeVars(root) {
  var varNames = Object.keys(root._variables);

  var variables = varNames.reduce(function(varMap, varName) {
    varMap[varName] = root._variables[varName].value;
  }, {});

  less.variables = variables;
}

This can be added just before the return statement with the breakpoint.

exposeVars(evaldRoot);
return result;

Now the variables will be available in a name: value object on the global less object.

You could even modify the expose function to return the variables from a call to less.getVars(). Just like your initial suggestion.

function exposeVars(root) {
  // ...
  less.getVars = function() {
    return variables;
  };
}
发布评论

评论列表(0)

  1. 暂无评论