Using @use With Sass and Webpack
This is a post that will, I hope, be obsolete real soon. Even so, maybe this well help you. Please learn from my pain.
tldr;
If you want to use Sass's @use
instead of their @include
(which is deprecated) and you're using Webpack with sass-loader
you need to use Dart Sass via npm install sass
NOT npm install dart-sass
and not node-sass
or any other sass
package.
Really, Webpack is irrelevant. You need npm install sass
if you want @use
, period.
The Dirty Details
Let's illustrate this in a hypothetical situation. This definitely didn't happen in real life... definitely.
Say you're building an app that uses, among other things, Webpack and Sass. The tech is unfamiliar so it's a bit of a shitshow but you're figuring it out.
You've probably npm install
'ed some versions of the following...
"css-loader": "^3.2.0",
"style-loader": "^1.0.0",
"node-sass": "^4.13.0",
"sass-loader": "^8.0.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.2"
Let's assume you get to a point where you'd like to refactor your styling. Partials seem like a good idea. Maybe having a _variables.scss
would be nice. You think you remember something about being able to include .scss
files in other .scss
files, but how?
You google and this is what you find:
https://sass-lang.com/documentation/at-rules/import
"Sass extends CSS's @import
rule with the ability to import Sass and CSS stylesheets, providing access to mixins, functions, and variables and combining multiple stylesheets' CSS together."
Yes! This is what you want.
But wait a minute, what's this?
Interesting, so the folks at Sass are deprecating @include
... Guess we oughta go with @use
.
The documentation at https://sass-lang.com/documentation/at-rules/use makes it seem pretty straightforward. Essentially the same as @include
.
You create a _variables.scss
with some colors like so:
$dark-blue: rgb(30, 30, 46);
$hot-pink: rgb(224, 78, 202);
$teal-green: rgb(0, 214, 180);
$peach: rgb(255, 109, 138);
$grey: #555;
$pink-purple: rgb(186,83, 244);
You've got a simple custom boostrap theme stylesheet that you want to test it out on, so you follow the docs and end up with something like this:
@use 'variables';
$body-bg: variables.$dark-blue;
$modal-content-bg: variables.$dark-blue;
@import "../../node_modules/bootstrap/scss/bootstrap";
...
OK! Let's give it a shot.
SassError: Invalid CSS after "...y-bg: variables": expected expression (e.g. 1px, bold), was ".$dark-blue;"
Huh, there must be some sort of syntax error, or maybe your path to _variables.scss
is wrong, or maybe it should be more explicit like @use _variables.scss
instead of @use 'variables'
?
None of these things are the problem.
Let's say (hypothetically) you've spent hours on this stupid problem. You're about to thrust your fist full force into your face when you notice something in the @use
documentation:
Compatibility, interesting. What do those x
s mean next to LibSass and Ruby Sass?? Ooo an arrow!
"Only Dart Sass currently supports @use
."
You gotta be fuckin' kidding me.
If you went through any of the Webpack/Sass tutorials out there currently, they will likely have suggested you use node-sass
. Dart Sass seems less popular.
It gets better (worse). There are two Dart Sass packages.
https://www.npmjs.com/package/dart-sass
https://www.npmjs.com/package/sass
dart-sass
does not work. sass
does. I don't know why. The NPM pages make them seem identical but, for @use
, sass
works and dart-sass
doesn't. I just tested it again to make sure I'm not crazy.
Dear lord, what a pain in the ass.