Sass @use does not work in CSS modules in React, while import does

Viewed 40

I have generated a React project with create-react-app using the TypeScript template. I've installed Sass via npm install sass, while CSS modules were already supported by the generated template.

I've created a common set of variables within the styles/common.scss file. I wanted to import and use the variables from the file in the stylesheet of my component. The recommended way to do this seems to be the @use directive, but I was unable to get to work.

Relevant files within my project structure:

components/
  custom/
    Custom.module.scss
    Custom.tsx
styles/
  common.scss

In this scenario components/custom/Custom.module.scss tries to import and use a variable from styles/common.scss with @use "styles/common.scss". While I don't get any specific errors related to the @use directive, attempting to reference any variables from the common stylesheet results in the following error: SassError: Undefined variable.

Things I've tried so far:

  • Proceeding the path with ~: @use "~styles/common.scss" yields the same error.
  • Different combinations of adding underscore to the common stylesheet, as well as removing extensions from the path in @use: same results.
  • Replacing @use with @import "styles/common.scss" works as expected: the variables are available in the CSS module.

However, since the @import is set to be deprecated, I'm wondering how to get @use to work and what is the root of the issue. Note that CSS modules themselves work as expected, and I'm able to import them correctly within the tsx files.

1 Answers

Given a default create-react-app setup, the correct way to import a module via @use is to omit the file extension (.scss) and the proceeding underscore. So, for example, styles/_colors.scss can be imported with @use "styles/colors".

However, by default each variable (etc.) from the imported file will require a prefix to be used. So, for example, to reference $pink from the imported _colors.scss file, you'd have to write colors.$pink. To change the prefix, you can choose an alias with as in the @use directive. For example, @use "styles/colors" as c; would allow the variables to be accessed with a c. prefix. To remove the prefix altogether, use the * alias.

Additionally, adding an _index.scss file allows using entire folders with specifying individual files. Use @forward directive in the _index.scss to choose which modules are available when importing the folder.

So, to sum it up, the file structure should look roughly like this:

  • styles/_colors.scss
$pink: #ff00ff;
  • styles/_index.scss: optional, allows importing multiple modules in 1 step.
@forward "styles/colors";
  • components/custom/Custom.module.css
@use "styles" as *;
// Or: @use "styles/colors" as *;

// Now $pink can be referenced without an alias.
Related