Подтвердить что ты не робот

Получите меньше переменных, используя less.js

Я использую client-side less.js. Есть ли способ получить все переменные из моего меньшего файла. Я знаю, как изменять переменные:

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

Но я хочу получить все из них, например (не работает):

var variables = less.getVars();
4b9b3361

Ответ 1

Это будет нетрадиционный ответ, так как кажется, что эти данные публично не отображаются как часть API-интерфейса, обращенного к браузеру.


TL;DR

  • Сохраните локальную копию файла less.js.
  • Добавить определение этой функции где-нибудь

    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;
    }
    
  • Добавьте следующий вызов exposeVars(evaldRoot) непосредственно перед return result в строке ~ 2556.

  • Теперь less.variables содержит все переменные из вашего файла.

Отказ от ответственности: делать это не рекомендуется! Это нормально, если вы просто играете, отлаживаете или проверяете что-то, но не зависите от этого взлома для чего-то серьезного!


Основная цель здесь заключалась в том, чтобы найти точку в источнике, где файлы .less превращаются в абстрактные деревья синтаксиса (или какую-то другую формальную структуру).

Прыгая прямо в источник, я нашел класс ParseTree. Разумно предположить, что он будет содержать результат разбора меньшего файла.

Я написал быстрый тестовый файл и добавил его в браузер с соответствующим тегом. Это выглядит так:

@myvar: red;
@othervar: 12px;

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

Я загрузил локальную копию less.js и добавил точку останова, добавленную в строку 2556.

В локальной области я обнаружил, что доступно, и нашел переменные в объекте с именем evaldRoot.

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

Следующее задание заключалось в том, чтобы выяснить, куда идут эти данные. Кажется, что переменная evaldRoot используется для генерации полученного CSS (что будет иметь смысл, поскольку оно содержит информацию, такую ​​как переменные).

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

Независимо от того, что происходит, переменные выходят за рамки после того, как они используются для создания строки CSS как result.css.

Чтобы выставить эти переменные, script требуется небольшая модификация. Вам придется публично публиковать переменные. Вот пример этого.

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;
}

Это может быть добавлено непосредственно перед оператором return с точкой останова.

exposeVars(evaldRoot);
return result;

Теперь переменные будут доступны в объекте name: value на глобальном объекте less.

введите описание изображения здесь

Вы можете даже изменить функцию экспонирования, чтобы вернуть переменные из вызова в less.getVars(). Как и ваше первоначальное предложение.

function exposeVars(root) {
  // ...
  less.getVars = function() {
    return variables;
  };
}