The Goal

Learn the basics of manually migrating your legacy Sass files to the new module system.

Author
Name:
Profession: Web Design & Development
Specialties: Front-end development, hand-drawing
Years’ Experience: 17
Tutorial Details
Experience Level: Intermediate
Noob: No coding skills required.
Beginner: Entry-level coding skills.
Intermediate: Code literate.
Advanced: Code fluent. Extensive technical skills.
Über Geek: Need I say more?
Skills: Sass, coding
Tools: sass, dart, compiler
Completion Time: 30-45 minutes
Related Article: Source
Tags: sass, preprocessor, dart, migration

This is a member-contributed tutorial. If possible, contact the author with questions or comments.

The Sass Migration

A few things before we get started:

  • Sass is/was not dead/abandoned, it was just feature-frozen but it’s been officially back in active development since 2019.
  • Sass now uses a module system and comes with new features and a minor syntax update.
  • There’s more to learn about the module system which is beyond the scope of this tutorial.
  • Migration is not a one-time only process. According to Miriam Suzanne the official Sass migration tool will receive regular updates as new features are added. So regardless of tool more migrations are inevitable.

Speaking of Migration...

As to the last point above there are various migration tools available from Node, Chocolatey, Homebrew, and of course the official Sass version written by Jennifer Thakar. But depending on your comfort-level and/or understanding of such tools they might not be for everyone.

For those of you that use a GUI compiler app some of them might already have a built-in migration feature. If so, great, but if not keep reading. I know that Bryan Jones, developer of the utterly fantastic Swiss Army knife of front-end development CodeKit (Mac) has it on his radar because I requested it, but I want to get this initial migration moving so...

What to Expect

I wrote this intentionally very simple (manual) migration tutorial for those who don’t want to install command-line tools and just want the basics and nothing more. The bare minimum of @use and @forward outlined below should be sufficient to get most people up and running until you can do a deeper dive into the new system.

Thanks to @dev_willis of the MODX Slack community for the heads-up about @use and @forward and helping sort out some configuration issues.

@use

Now that Sass has made the jump to a module-based structure the way it handles partials internally has changed so we need to make some small but necessary syntax changes as it applies to @import. While the Sass dev team have made sure @import will continue to work alongside the new module-based approach it will eventually (perhaps in two years or so) be dropped in favor of @use and @forward.

Sass refers to mixins, variables, and functios as “members” which is how they are sometimes referred to in this tutorial.

Previously, in order to use members in other partials we could simply include their respective file(s) at the top of our partials listing in the root file, e.g. global.scss like so:

// The old syntax

// global.scss project root file w/ partial listing

@charset "UTF-8";

@import "mixins"; // The members will be available to any files listed below that use mixins
@import "variables"; // The members will be available to any files listed below that use variables
@import "main";
@import "form";
@import "menu";

Looks familiar, right?

Except now we need to use @use which is functionally very similar to @import (we’re still importing files) but is also slightly different and better. So using the above example our root file would now look like this:

// global.scss project root file w/ partial listing

@charset "UTF-8";

@use "main";
@use "form";
@use "menu";

Notice the mixins and variables files are missing.

With the new system when a partial, e.g. _main.scss, needs access to the members of another file, e.g. _mixins.scss, we need to explicitly call said file(s) with @use from the partial, not the root global.scss file. It’s a simple matter of calling the required file at the very top of the partial, before anything else.

Only @charset and simple variable definitions can appear before the import commands.

// At the top of _main.scss

@use "mixins" as *;  // The members of this file will be available to _main.scss

/* !Begin Main Styles */

* {
	@include hyphens;
}
...

If you need to @use more files then simply add them one after another in the oreder you need to load them like so:

/* At the top of _main.scss */

@use "mixins" as *;
@use "variables" as *;

/* !Begin Main Styles */

* {
	@include hyphens;
}
...

You’ll notice that as * has been appended to the call. What this does is make available all members of the included partials for use in _main.scss. Without as * the Dart compiler would throw errors about any mixins, variables, or functions used in _main.scss.

For example, @include hyphens; as shown above would throw the following error if as * were missing.

Dart Sass failed with this error: Error: Undefined mixin.
  ?
7 ?     @include hyphens;
  ?     ^^^^^^^^^^^^^^^^
  ?
  _main.scss 7:2   @use
  global.scss 4:1  root stylesheet

So instead of the blanket coverage we enjoyed under the previous method we now need to explicitly add any required files on a partial-by-partial basis. Not a big deal but a bit more more work for more granular control.

It’s also possible to target a specific member for use in another file instead of loading all members.

@forward

This is pretty handy.

As always you are free to organize your partials however you like. What @forward does is allow you to group similar partials under one namespace e.g., ui, for use in another file. Or you can cherry pick only the partials you need with a separate call for each file. Either way works.

So, after grouping the partials under a folder, e.g., ui we need to create either a index.scss or _index.scss file (pick only one). This acts as the root file for the ui namespace so we can @forward all the partials (or individual ones) contained within the ui folder.

// ui/index.scss partial listing

@forward "menu";
@forward "slider";
@forward "tipped";

Then @use them as normal. This will load all 3 files as defined in ui/index.scss.

// main.scss

@use "mixins" as *;
@use "ui" as *;

/* !Begin Main Styles */

* {
	@include hyphens;
}
...

As mentioned, if you only want to use one file from the ui folder/namespace, e.g., _menu.scss, instead of all three then call it as normal but remember to adjust the path accordingly.

// main.scss

@use "ui/menu" as *; // Include the parent folder "ui" in the path

/* !Begin Main Styles */

* {
	@include hyphens;
}
...

Keep in mind that if _menu.scss requires any additional members like mixins (spoiler: it does) then be sure to call those files too or you’ll get errors.

// At the top of _menu.scss

@use "mixins" as *;
@use "ui/menu" as *;

/* !Begin Menu Styles */

...

Wrap Up

There’s still plenty of time to migrate, probably two years. Thankfully the Sass team has put the time and effort into ensuring @import continues to work in parallel with the new system right up to the day it gets dropped.


Tutorials Archive show by year/month