68

I created an Angular project using the CLI. I'm using SCSS, and I included Angular Material with a custom theme iirc. I added a couple dummy components, and the app still built fine. Then I needed to style my components using Angular Material. In order to do so, I added @use '~@angular/material' as mat; to the first line of my style.scss file. Once I did this, the app will no longer build. It always throws the following error:

ERROR in ./src/styles.scss (./node_modules/css-loader/dist/cjs.js??ref--13-1!./node_modules/postcss-loader/src??embedded!./node_modules/resolve-url-loader??ref--13-3!./node_modules/sass-loader/dist/cjs.js??ref--13-4!./src/styles.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Can't find stylesheet to import.
  ╷
1 │ @use '~@angular/material' as mat;
  │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ╵
  src/styles.scss 1:1  root stylesheet

I have no idea what I'm doing wrong; I was under the impression that importing Angular Material this way would just work. Am I doing something wrong?

Here is my entire style.scss file if that's helpful:

@use '~@angular/material' as mat;

// Custom Theming for Angular Material
// For more information: https://material.angular.io/guide/theming
@import '~@angular/material/theming';
// Plus imports for other components in your app.

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();

// For each palette, you can optionally specify a default, lighter, and darker hue.
$aphrodite-primary: mat-palette($mat-indigo);
$aphrodite-accent: mat-palette($mat-pink, A200, A100, A400);

// The warn palette is optional (defaults to red).
$aphrodite-warn: mat-palette($mat-red);

// Create the theme object. A theme consists of configurations for individual
// theming systems such as "color" or "typography".
$aphrodite-theme: mat-light-theme((
  color: (
    primary: $aphrodite-primary,
    accent: $aphrodite-accent,
    warn: $aphrodite-warn,
  )
));

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($aphrodite-theme);

/* You can add global styles to this file, and also import other style files */

@import '~normalize.css';
@import 'sassVars.scss';

html, body { height: 100%; }

html{
  background: $nullGray;
  min-width: 400px;
}

body {
  font-family: Roboto, "Helvetica Neue", sans-serif;
  background: $canvas;
  max-width: $bodyWidth;
  margin: auto;
  height: 100%;
  @include elevation(16);
}

Here's my angular.json file:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "myapp": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "baseHref" : "/app/",
            "deployUrl": "/app/",
            "outputPath": "dist/myapp",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "myapp:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "myapp:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "myapp:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "tsconfig.app.json",
              "tsconfig.spec.json",
              "e2e/tsconfig.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        },
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "myapp:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "myapp:serve:production"
            }
          }
        }
      }
    }
  },
  "defaultProject": "myapp",
  "cli": {
    "analytics": "0ded4b78-d900-44ea-8ad2-b5cbba677e06"
  }
}
Mathew Alden
  • 1,458
  • 2
  • 15
  • 34

8 Answers8

111

For Angular 13 try to remove tilde symbol (~) from the path so import like:

@use '@angular/material' as mat;

It works like a charm.

Zze
  • 18,229
  • 13
  • 85
  • 118
Igor Kurkov
  • 4,318
  • 2
  • 30
  • 31
  • 3
    This is applicable to ng13 – McAden Nov 08 '21 at 22:10
  • 1
    Thanks! It worked for me too. – Sadiinso Nov 15 '21 at 16:49
  • 5
    I found https://github.com/angular/components/issues/23889 that gives some background. I also had success in running `ng update @angular/cdk --migrate-only --from 12.0.0 --to 13.0.0` which fixed my material scss imports. I guess I'm not the only one where the normal ng update broke – Schaki Nov 17 '21 at 12:52
  • 1
    I couldn't even use the ng update function, it kept erroring out with dependency conflicts (on the things it just updated itself), this was one of the things that broke while reinstalling one library at a time. Thanks for this tip. – coppereyecat Nov 19 '21 at 21:22
  • 12
    It worked but PhpStorm didn't like it, so I use `@use 'node_modules/@angular/material' as mat;` as per jetbrains issue WEB-41588 – darko99 Nov 20 '21 at 15:37
  • 1
    This is the way, thanks! – Jaime Still Nov 29 '21 at 21:32
  • 4
    @darko99: thank you! This has been bugging me for quite a while and JB didn't fix it yet (WebStorm doesn't recognize the path **without** the tilde and Angular does not recognize it **with** it being present - annoying af, using `WebStorm 2021.3, #WS-213.5744.224`). – Igor Dec 20 '21 at 00:50
  • 2
    @Igor The latest PhpStorm (PhpStorm 2021.3.1) release has solved this issue for me. "@angular" works without the tilde and the IDE is also fine with that, – Pateta Jan 05 '22 at 00:27
31

As usual with Google APIs, there is confusion between Angular Material version 11 and version 12.

[Short answer]

In SCSS, they seem to have deprecated use of @import favouring @use syntax. It seems Angular Material implemented this change somewhere around v11->12
(am also a newbie. This is my best guess).

Watch this YouTube video to get a general idea of the difference.

There is a reason why Google Angular is the most dreaded framework of 2020 on Stack Overflow :) So it depends on the Angular Material version you are using

[Long answer]
In Angular Material v11, they seem to use @import syntax, and in v12 they seem to favour @use syntax.

Therefore, you seem to be trying to use a tutorial or theme designed with Angular Material v11 in mind which uses @import syntax and you mix it with @use syntax of Angular Material v12. The biggest difference between the two is that @use syntax causes the SCSS to be prefixed, so the function names change slightly, for example

//angular material v11 which uses @import syntax 
@import '~@angular/material/theming';//notice that the file imported is also different
@include mat-core();

$candy-app-primary: mat-palette($mat-indigo); //notice that functions not Namespaced

$candy-app-accent:  mat-palette($mat-pink, A200, A100, A400);

While the same example using angular material v12 which uses @use syntax

@use '~@angular/material' as mat; 

$candy-app-primary: mat.define-palette(mat.$indigo-palette, 500); //notice that functions are prefixed with Namespace mat. This is a feature of the scss @use  directive
$candy-app-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);

[I have yet to find a way to find the correct function names across the 2 versions. It is not trivial to migrate a theme manually especially when you are a newbie]

So you can see, its easy to have a missing stylesheet depending on if you are using Material v11 or 12. Good luck selecting version

gotnull
  • 26,454
  • 22
  • 137
  • 203
Dr Deo
  • 4,650
  • 11
  • 43
  • 73
  • 9
    Even though I hate Angular as much as the next developer, the linked video about "dreaded" talks about Angular.js not Angular 2+, so you might want to edit that. – yuriy636 Oct 17 '21 at 11:30
  • Good answer. It was important to get the distinguished difference between Angular 11 and Angular 12, because the documentation does not make note of this. – Tyler Durden Feb 01 '22 at 14:39
  • 6
    this is a troll answer. This has nothing to do with Angular. It is sass breaking change and it affects all libraries which use it. – Vugar Abdullayev Feb 13 '22 at 16:33
12

I was having a similar issue and @darko99 helped me with his comment. If I change @use '@angular/material' as mat; to @use 'node_modules/@angular/material' as mat; I stop getting the SassError in the terminal. But instead of adding node_modules/ on each @use we can also add the following in angular.json under architect/build/options:

 "stylePreprocessorOptions": {
   "includePaths": [
     "node_modules/",
     ...
   ]
 }
11

Apparently, I had been reading the wrong documentation for my version. The above code has two things that needed to be changed for it to work for me.

  1. You don't do @use '~@angular/material' as mat;. The important line is @import '~@angular/material/theming';, which was already put in the file by the CLI.

  2. It's not @include elevation(16);, it's @include mat-elevation(16);.

Mathew Alden
  • 1,458
  • 2
  • 15
  • 34
  • Thank you! BTW it's also possible to roll with `@use '~@angular/material/theming' as mat;`. – DanielM May 26 '21 at 10:11
  • 3
    actually the latest version actually says to import `@use '~@angular/material' as mat;` [documentation](https://material.angular.io/guide/theming#customizing-strong-focus-indicators) – Edoardo May 28 '21 at 10:35
  • You might be using a lower version of angular material theme. https://v9.material.angular.io/guide/theming#defining-a-theme – Nirav Shah Sep 04 '21 at 08:21
  • [This post](https://stackoverflow.com/a/62757625/84424) suggests that `@use` is better. [Kurkov's answer](https://stackoverflow.com/a/69889728/84424) worked great for me. – Zachary Scott Nov 24 '21 at 17:44
6

Had similar issue. This helped me:

enter link description here

In Nx or Angular v15 - remove ' ~ ' stuff.

Vaidas D.
  • 193
  • 3
  • 8
5

try this way:

@use '@angular/material' as mat;

without the ~ symbol.

hope it works for you

Rob
  • 73
  • 1
  • 6
2

@use 'node_modules/@angular/material' as mat;

Above code worked for me. Node version was 14.16.0, angular 12.x and IDE was Visual Studio.

Zach Jensz
  • 3,650
  • 5
  • 15
  • 30
Hasib
  • 21
  • 1
1

If anyone gets this error again, the following helped me:

I had the same issue, I deleted my custom angular theme and forgot to remove the Path styles from angular.json file, then changed @use '~@angular/material' as mat; to @use '@angular/material' as mat;.

After I removed the styles path for customer I updated angular material. Then just reset your using VSCode because it sometimes does not refresh on its own.

ahuemmer
  • 1,653
  • 9
  • 22
  • 29