我发现自己处于非常相似的境地。我们有很多现有的 SASS,现在需要接受要在整个过程中使用的动态值/变量(作为变量)。我最初走的是编写临时目录/文件的路线,本质上是创建一个“代理入口点”,它将创建一个proxy_entry.scss
并variables.scss
引导实际entry.scss
声明的预期 SASS 变量。这工作正常并达到了预期的结果,但感觉有点过于复杂......
事实证明,由于node-sass 的options.data
选项,有一个更简单的解决方案可用。这接受“要评估的 SASS 字符串”。
类型:字符串 默认值:null 特殊:必须指定文件或数据
传递给 libsass 进行渲染的字符串。建议您将 includePaths 与此结合使用,以便 libsass 在使用 @import 指令时可以找到文件。
这完全消除了编写/管理所有临时目录和文件的需要。
视觉 TL;DR
解决方案归结为这样
1.) 像往常一样定义 sassOptions
var sassOptionsDefaults = {
includePaths: [
'some/include/path'
],
outputStyle: 'compressed'
};
2.) 为options.data
var dataString =
sassGenerator.sassVariables(variables) +
sassGenerator.sassImport(scssEntry);
var sassOptions = _.assign({}, sassOptionsDefaults, {
data: dataString
});
3.) 像往常一样评估 SASS
var sass = require('node-sass');
sass.render(sassOptions, function (err, result) {
return (err)
? handleError(err);
: handleSuccess(result.css.toString());
});
注意: 这是假设您的entry.scss
导入一些variables.scss
将变量定义为“默认值”。
// variables.scss
$someColor: blue !default;
$someFontSize: 13px !default;
// entry.scss
@import 'variables';
.some-selector {
color: $someColor;
font-size: $someFontSize;
}
将它们拼凑在一起作为示例
var sass = require('node-sass');
// 1.) Define sassOptions as usual
var sassOptionsDefaults = {
includePaths: [
'some/include/path'
],
outputStyle: 'compressed'
};
function dynamicSass(scssEntry, variables, handleSuccess, handleError) {
// 2.) Dynamically create "SASS variable declarations"
// then import the "actual entry.scss file".
// dataString is just "SASS" to be evaluated before
// the actual entry.scss is imported.
var dataString =
sassGenerator.sassVariables(variables) +
sassGenerator.sassImport(scssEntry);
var sassOptions = _.assign({}, sassOptionsDefaults, {
data: dataString
});
// 3.) render sass as usual
sass.render(sassOptions, function (err, result) {
return (err)
? handleError(err);
: handleSuccess(result.css.toString());
});
}
// Example usage.
dynamicSass('some/path/entry.scss', {
'someColor': 'red',
'someFontSize': '18px'
}, someSuccessFn, someErrorFn);
“sassGenerator”函数看起来像
function sassVariable(name, value) {
return "$" + name + ": " + value + ";";
}
function sassVariables(variablesObj) {
return Object.keys(variablesObj).map(function (name) {
return sassVariable(name, variablesObj[name]);
}).join('\n')
}
function sassImport(path) {
return "@import '" + path + "';";
}
这使您可以像以前一样编写 SASS,在需要的任何地方使用 SASS 变量。它也不会将您束缚于任何“特殊的动态 sass 实现”(即这避免了在整个.scss
文件中使用“下划线/lodash 模板”)。这也意味着您可以利用 IDE 功能、linting 等......只是相同,因为您现在刚刚回到编写常规 SASS。
此外,它可以很好地转换为非节点/http/compile-on-the-fly 用法,例如entry.scss
通过 Gulp 预编译给定多个值集的多个变体等...
我希望这可以帮助您@ChrisWright(和其他人)!我知道我很难找到有关该主题的信息,我想这是一个相当常见的用例(希望将动态值从数据库、配置、HTTP 参数等传递到 SASS 中……)。