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 xs 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.