ОБНОВЛЕНИЕ 3
еще одно усыновление на замену
let newSelector = selector.replace(/\s?\:\:flavor\-([^\s]+)/g, "").trim();
ОБНОВЛЕНИЕ 2
замена в селекторе правила css должна быть принята
let newSelector = selector.replace(/\s?\:\:flavor\-([a-zA-Z0-9\-\_\s]+)/g, "").trim();
ОБНОВЛЕНИЕ
используя модифицированный селектор, а не свойства, вы можете продолжать использовать вложенные правила внутри блока «for-flavor».
Итак, настройте миксин, чтобы он выглядел так:
@mixin for-flavor($name) {
::flavor-#{$name} & {
@content;
}
}
и задача глотка:
const path = require("path");
const gulp = require("gulp");
const sourcemaps = require("gulp-sourcemaps");
const sass = require("gulp-sass");
const autoprefixer = require("gulp-autoprefixer");
const through = require("through2");
const postcss = require("gulp-postcss");
/**
* compile/concat scss
*/
gulp.task('css', function () {
const sassOptions = {
outputStyle: "compressed",
errorLogToConsole: true
};
const autoprefixerOptions = {
browsersList: [
"last 2 versions",
"ie >= 11"
]
};
function addFlavorFiles() {
return through.obj(function(file, encoding, callback) {
/* @var file File */
let content = file.contents.toString();
let names = [];
let matches = content.match(/\:\:flavor\-([^\s\{]+)/g);
if (matches) {
names = matches.map(match => match.replace(/\:\:flavor\-/, '').trim());
// unique
names = names.filter((el, index, arr) => {
return index === arr.indexOf(el);
});
}
names.forEach(name => {
let newFile = file.clone();
newFile.contents = Buffer.concat([Buffer.from(`/*!flavor:${name}*/\n`, encoding), file.contents]);
let filePath = path.parse(file.path);
newFile.path = path.join(filePath.dir, `flavor-${name + filePath.ext}`);
this.push(newFile);
});
callback(null, file);
})
}
function filterFlavors(css, opts) {
let flavor = null;
if (css.nodes[0].type === "comment" && css.nodes[0].text.indexOf('!flavor:') === 0) {
flavor = css.nodes[0].text.replace(/^\!flavor\:/, "").trim();
}
css.walkRules(rule => {
let selector = rule.selector;
if (/^\:\:flavor\-/.test(selector)) {
// flavor rule
if (flavor === null) {
// general file, all flavor rules must go...
rule.remove();
} else {
let matches = selector.match(/\:\:flavor\-([a-zA-Z0-9\-\_]+)/);
let currentFlavor = matches[1];
if (flavor !== currentFlavor) {
// wrong flavor
rule.remove();
} else {
// keep rule but adjust selector
let newSelector = selector.replace(/^\:\:flavor\-([a-zA-Z0-9\-\_]+)/, "").trim();
rule.selector = newSelector;
}
}
} else if(flavor !== null) {
// general rule but flavor file, so remove the rule
rule.remove();
}
});
css.walkRules(rule => {
if (!rule.nodes || rule.nodes.length === 0) {
rule.remove();
}
});
css.walkAtRules(atRule => {
if (!atRule.nodes || atRule.nodes.length === 0) {
atRule.remove();
}
});
// optional: delete all font-face definitions from flavor file
if (flavor !== null) {
css.walkAtRules(atRule => {
if (atRule.name === "font-face") {
atRule.remove();
}
});
}
}
return gulp
.src("src/scss/*.scss")
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', makeErrorLogger('css')))
.pipe(addFlavorFiles())
.pipe(autoprefixer(autoprefixerOptions))
.pipe(postcss([filterFlavors]))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest("public/static/css"))
});
ИСХОДНОЕ СООБЩЕНИЕ
Мне удалось решить это, как я собирался
Используйте миксин sass, который добавляет правила для синтаксического анализа:
@mixin for-flavor($name) {
-flavor-start: unquote($name);
@content;
-flavor-end: unquote($name);
}
используйте его для своих объявлений css
// you get the idea...
$flavors: (
"lightblue": (
background: lightblue,
),
"pink": (
background: pink,
),
"dark": (
background: black
),
);
#page-header {
background: black;
@each $name, $options in $flavors {
@if map_has_key($options, 'background') {
@include for-flavor($name) {
background: map_get($options, 'background');
}
}
}
@include for-flavor("lightblue") {
/* special rule for specific flavor */
color: black;
}
}
глоток
const path = require("path");
const gulp = require("gulp");
const sourcemaps = require("gulp-sourcemaps");
const sass = require("gulp-sass");
const autoprefixer = require("gulp-autoprefixer");
const through = require("through2");
const postcss = require("gulp-postcss");
/**
* compile/concat scss
*/
gulp.task('css', function () {
const sassOptions = {
outputStyle: "compressed",
errorLogToConsole: true
};
const autoprefixerOptions = {
browsersList: [
"last 2 versions",
"ie >= 11"
]
};
function addFlavorFiles() {
return through.obj(function(file, encoding, callback) {
/* @var file File */
let content = file.contents.toString();
let names = [];
let matches = content.match(/\-flavor\-start\:([^\;]+)/g);
if (matches) {
names = matches.map(match => match.replace(/\-flavor\-start\:/, '').trim());
}
names.forEach(name => {
let newFile = file.clone();
newFile.contents = Buffer.concat([Buffer.from(`/*!flavor:${name}*/\n`, encoding), file.contents]);
let filePath = path.parse(file.path);
newFile.path = path.join(filePath.dir, `flavor-${name + filePath.ext}`);
this.push(newFile);
});
callback(null, file);
})
}
function filterFlavors(css, opts) {
let flavor = null;
if (css.nodes[0].type === "comment" && css.nodes[0].text.indexOf('!flavor:') === 0) {
flavor = css.nodes[0].text.replace(/^\!flavor\:/, "").trim();
}
let inFlavorBlock = "";
css.walkDecls(decl => {
let prop = decl.prop;
let isControlProp = false;
let value = decl.value.trim();
if (prop === "-flavor-end") {
inFlavorBlock = "";
isControlProp = true;
} else if (prop === "-flavor-start") {
inFlavorBlock = value;
isControlProp = true;
}
let isValid = ((inFlavorBlock === "" && flavor === null) || inFlavorBlock === flavor);
if (isValid === false || isControlProp) {
decl.remove();
}
});
css.walkRules(rule => {
if (!rule.nodes || rule.nodes.length === 0) {
rule.remove();
}
});
css.walkAtRules(atRule => {
if (!atRule.nodes || atRule.nodes.length === 0) {
atRule.remove();
}
});
}
return gulp
.src("src/scss/*.scss")
.pipe(sourcemaps.init())
.pipe(sass(sassOptions))
.pipe(addFlavorFiles())
.pipe(autoprefixer(autoprefixerOptions))
.pipe(postcss([filterFlavors]))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest("public/static/css"))
});
Единственная оставшаяся проблема заключается в том, что исходные карты не фильтруются...
person
Philipp Wrann
schedule
24.10.2019
flavor-a.scss
иflavor-b.scss
должны были импортировать общий частичный_app.scss
, вы могли бы разделить вывод с помощью миксина. См. мой ответ на этот похожий вопрос: stackoverflow.com/questions/58284016/ - person Cody MacPixelface   schedule 17.10.2019