将变量从 JSON 文件加载到 LESS CSS 预处理器中

Load variables into LESS CSS preprocessor from JSON file

本文关键字:CSS LESS 预处理 处理器 加载 变量 JSON 文件      更新时间:2023-09-26

是否可以像使用Stylus那样将变量从JSON文件加载到LESS CSS预处理器中?

包含文件myvars.json的内容

{
    "color1": "#112345",
    "color2": "#667890"
}

在手写笔中,我做...

json('myvars.json')
body{ background-color: color1; }

是否可以在 LESS 中做到这一点?

我想将文件保留为 JSON,这样我可以轻松地在 javascript 中重用它。

在更少.js你可以使用javascript插值(使用反引号(。并调用一个函数,该函数使用文件中的变量加载 json 对象......您可以从中提取变量的键 - 也许是这个方向:

@json_file: myvars.json;
@json: ~`json = function($key) { var request = new XMLHttpRequest(); request.open("GET", "@{json_file}", false); request.send(null); var my_json = JSON.parse(request.responseText); return my_json[$key]; }`;
body {
  background-color: ~`json('color1')`;
}

这可能看起来不是很优雅,但它有效。一个更优雅的选择可能是在调用脚本之前在全局 LESS 对象中定义您的自定义用户函数,但我从来没有真正费心玩过它,因为我总是在开发中使用 LESS 客户端。

您可以做的另一件事 - 是在 javascript 中加载 json 文件(在浏览器中调用 LESS 脚本之后(并使用 less.modifyVars() 函数使用 json 变量重新编译 LESS。你可以在你的html中做一些事情(这里我使用普通的JS,但如果你使用jQuery.getJSON,它会更简单(:

<link rel="stylesheet/less" href="style.less" type="text/css">
<script type="text/javascript">less = { env: "development" };</script>
<script src="http://rawgithub.com/less/less.js/master/dist/less-1.4.1.min.js" ></script>
<script type="text/javascript">
    var request = new XMLHttpRequest();
    request.open("GET", "myvars.json", false);
    request.send(null);
    var my_json = JSON.parse(request.responseText);
    less.modifyVars(my_json);
</script>

以及 LESS 样式文件中的类似内容:

@color1: darkblue; //default value - will get overwritten by .modifyVars()
body {
  background-color: @color1;
}

另一个注意事项:LESS 中的所有变量名都必须以 at 符号 ( @ ( 开头。但是,json 变量不需要这样做,因为如果缺少less.modifyVars(),会自动在变量前面加上@

希望这能给你一些想法。可能有更好的方法可以做到这一点...但这两种方法对我有用。

如果你不在浏览器中使用 LESS 而是编译 CSS,我只是发布一个 gulp 插件来完成这项工作。

它可以看起来像这样:

css/myvars.json

{
    "color1": "#112345",
    "color2": "#667890"
}

less/styles.less

@json-import "myvars.json";
body {
  background-color: @color1;
}

gulpfile.js

var gulp = require('gulp');
var less = require('gulp-less');
var lessJsonImport = require('gulp-less-json-import');
gulp.task('less', function(){ 
  gulp.src(['./less/**/*.less', '!./less/**/_*.less'])
      .pipe(lessJsonImport())
      .pipe(less())
      .pipe(gulp.dest('./css'));
});

在浏览器中使用 LESS 时,还有"globalVars"选项可用于在加载 LESS 文件之前设置变量: http://lesscss.org/usage/#using-less-in-the-browser-options

您可以使用

globalVars less选项来提供从json文件加载的对象。

例如,使用较少的加载器插件webpack.config.js如下所示:

function lessGlobalVars() {
    return require('flat')(require('./path/to/config.json'),
        {
            delimiter: '_'
        });
}
module.exports = {
  module: {
    rules: [
      {
        test: /'.less$/,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'less-loader',
            options: {
              globalVars: lessGlobalVars()
            }
          }
        ]
      }
    ]
  }
};

config.json

{
  "dimensions": {
    "width": 100,
    "height": 50
  }
}

globalVars只接受平面结构,因此我们需要扁平封装,将加载require('./path/to/config.json')的对象展平,以便:

{
  dimensions_width: 100,
  dimensions_height: 50
}

将此对象传递给globalVars选项将使全局变量@dimensions_width@dimensions_height可用于所有较少的样式表:

.some-class {
  width: @dimensions_width;
  height: @dimensions_height;
}

下面介绍了一种相对较新的方法:

myPluginFile.js

const axios = require('axios').default
module.exports = {
  install: function (less, pluginManager, functions) {
    functions.add("blue", function () {
      const headers = {
        'Access-Control-Allow-Origin': '*',
        'Content-Type': 'application/json',
        timestamp: +new Date(),
      }  
      
      try {
        const method = 'get'
        const url = 'https://myAPI.com/myFile.json'
        const options = { headers: { ...headers } }
        const { data } = await axios[method](url, {}, options)
        return data
      } catch (error) {
        console.info('Error', { msg: error.message })
      }
    });
  },
};

myStyleFile.less

@plugin "myPluginFile";
/* Style the body */
body {
  color: blue();
}