NOTE: I don't think this is a duplicate of Ignore parts of sass file for parsing because I'm looking for an alternative that doesn't require wrapping the native mixin in a string, which is the only solution presented in the other question.
// my-view1.scss
my-view1 {
--view1-card: {
border: solid 1px blue;
opacity: 0.5;
};
}
// my-view1.css
my-view1 {
--view1-card-border: solid 1px blue;
--view1-card-opacity: 0.5;
}
#{'...'}
// my-view1.scss
my-view1 {
--view1-card: #{'{
border: solid 1px blue;
opacity: 0.5;
}'};
}
TLDR: To me, the best solution was to switch to dart-sass
1.0.0-alpha.8, which correctly parses native CSS mixins.
I could update my Gulp task to preparse the file for native CSS mixins, and wrap them in Sass string interpolation before passing the output to Sass. For example, given this input:
$color: blue;
--view1-card: {
color: #{$color};
};
The preparser would produce this output:
$color: blue;
--view1-card: #{'{
color: #{$color};
}'};
This could be easily acheived with String#replace
(or gulp-replace
), using the right regular expression, like this:
sassInput.replace(/(--[-\w]+:\s*)(\{[\s\S]*\})/gm, "$1#{'$2'}");
sass
/libsass
This issue is fixed in the bleeding edge 3.5 or 4.0 builds of sass
or libsass
. In my case, I'm using gulp-sass
, which uses node-sass
, which wraps libsass
. To get this fix in my Gulp build, I would:
gulp-sass
and node-sass
.node-sass
dependency on libsass
so that it uses the commit/branch, containing the fix.node-sass
change on a branch.gulp-sass
dependency to point to that node-sass
branch.gulp-sass
change on a branch.gulp-sass
branch.A lot of extra work here, but it could be worth the trouble as several interesting features were added in the newest builds.
dart-sass
This issue is not present in dart-sass
1.0.0-alpha.8. I could update my build to use it instead of gulp-sass
. (I could also update gulp-sass
to use dart-sass
with the steps above for bleeding-edge libsass
, but I went with direct usage of dart-sass
.)
I had to wrap dart-sass
with through2
like this:
const dartSassPipe: Transform = through2.obj((file, _enc, cb) => {
dartSass.render({file: file.path}, (err: Error, result: Buffer) => {
if (err) {
console.error(chalk.red('[dart-sass] ') + err.message);
} else {
file.contents = result.buffer;
}
cb(err, file);
});
});
This pipe replaces the stream's contents with Sass output, but I also need the stream's file extension to change from .scss
to .css
, so I used gulp-ext-replace
.
This allowed me to replace gulp-sass
in my Gulp stream like this:
const stream = pump([
gulp.src('src/**/*.{css,sass,scss}'),
- $.sass().on('error', $.sass.logError),
+ dartSassPipe,
+ $.extReplace('.css'),
gulp.dest(distDir),
]);