48

After updating from Angular 11 to 12, ng serve is now throwing an error:

Error: /Users/btaylor/work/angular-apps/mdsl-authoring/assets/scss/_colors.scss:1:4: Unknown word
You tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser

Error: /Users/btaylor/work/angular-apps/mdsl-authoring/assets/scss/custom-bootstrap.scss:1:1: Unknown word
You tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser

Error: /Users/btaylor/work/angular-apps/mdsl-authoring/assets/scss/global.scss:296:12: Unknown word
You tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser

Error: /Users/btaylor/work/angular-apps/mdsl-authoring/assets/scss/mdsl-composer/mdsl-composer-variables.scss:103:1: Unknown word
You tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser

None of the SCSS files in question is doing anything special. _colors.scss for example is simply:

// Bootstrap Overrides
$text-secondary: #2E93B1;
$text-muted: #ccc;
$link-color: #2E93B1;

.text-secondary {
  color: $text-secondary !important;
}

// LabCorp UI Overrides
$theme-colors: (
  'primary': #003A70,
  'secondary': #2E93B1,
  'success': #155724,
  'danger': #790E1D,
  'warning': #C59C38,
  'info': #007A6E,
  'light': #EDF1F4,
  'dark': #0B1519,
);

// UI design colors
$primary: #007FA3;
$highlighted: #D57800;
$accent: #5F456F;
$accent-secondary: #808080;
$related: #D1EAF1;

So I'm not sure what Unknown word the parser is complaining about.

I'm not finding very much information online regarding this error with Angular.

The rest of the project code will compile as expected, but now the application won't run. I'm not sure what other code to provide here, but am more than happy to post whatever would be helpful for debugging.

The error is specific to Angular CLI. Our project uses Angular Universal, and building the code and serving it via Node work as expected.

Brandon Taylor
  • 33,823
  • 15
  • 104
  • 144
  • 11
    I am experienced the same after upgrading ang 11 > ang 12 – user576700 May 21 '21 at 17:34
  • 2
    @user576700 set `buildOptimizer` and `optimization` to false in your `development` configuration in angular.json. That's what fixed it for me. – Brandon Taylor May 21 '21 at 18:08
  • that worked, updated buildOptimizer and optimization to false; Although compiler says these are deprecated and should be set in browser builder options - Thank you! – user576700 May 21 '21 at 19:43
  • 2
    Turning of the optimization is not a solution... – jmeinlschmidt May 28 '21 at 16:25
  • @jmeinlschmidt Keep in mind that disabling the buildOptimizer is only when running `ng serve` locally, not for production. – Brandon Taylor May 28 '21 at 16:30
  • I got this error when upgrading from 12.1.4 to 12.2. It is also complaining about a missing semicolon and lists a line. However that line, and all lines I can see contain an ending semicolon. Too bad the error message isn't more helpful. - update: the missing semicolon was due to an upgrade in bootstrap from 5.0.2 to 5.1.0. – Jeff Hiatt Aug 05 '21 at 15:14
  • For me, using the deprecated `/deep/` work in my `scss` file caused the same error. – Rami Alloush Jun 08 '22 at 16:17

12 Answers12

28

I have investigated this issue since I lately migrated a medium-size project from v11 to v12.

The issue is that you have your .scss files in the assets folder which is basically meant to be for assets to be copied as-is. Not to be processed by some kind of scss preprocessor.

Source https://angular.io/guide/workspace-config#asset-config

... folders you want to copy as-is when building your project.

However, files in the assets folder are being minifed and that's where the exception comes from. During the previous version, these files were probably preprocessed and that is the reason why this issue hasn't came up until now.

The solution is moving your global .scss files out of the assets folder. You can additionally list them in angular.json (styles property) if needed.

Itai Dagan
  • 285
  • 2
  • 11
jmeinlschmidt
  • 1,446
  • 2
  • 14
  • 33
21

For those of you finding this right after updating to Angular 12 be sure to carefully read the Angular 12 Update Guide.

The relevant section is :

Critical CSS inlining is now enabled by default. To turn this off, set inlineCritical to false. See PR #20096 and the Style preprocessor options section of Angular workspace configuration.

What it's doing is actually looking at your index.html file and inspecting stylesheet entries, then trying to include them in the source.

As some others have said setting optimization: false can solve the problem - but I'm guessing you didn't do your bundle size any favors with that one!

Instead you can change inlineCritical to false which you can do by setting something like this. See the full configuration for optimization.

"optimization": {
  "scripts": true,
  "styles": {
    "minify": true,
    "inlineCritical": false
  },
  "fonts": true
}

Another possibly relevant change in Angular 12 is the inlineStyleLanguage option.

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • Note: I'm still in the process of doing my own update, and I think maybe you need a production and development instance of these settings - or your ng serve will take several minutes (like mine is now!). – Simon_Weaver May 28 '21 at 02:59
  • I don't understand how this can fix anything, the optimization is part of the production configuration and the issue is in ng serve. This would mean that ng serve is actually doing optimizations that you don't want during your 'dev'. For me this fix doesn't seem to work BTW. – Samantha Adrichem Jun 02 '21 at 06:45
  • @SamanthaAdrichem honestly I'm a bit confused myself. After I wrote this I actually generated a new stub application, compared everything and copied things over. I ended up with just `optimization: false` in my development section and the defaults for `production`. I did not in the end have `inlineCritical` in my file, nor did I see this problem again (so that's the good news). You may need to run migrations manually if you did not run `ng update`, but DON'T run them twice by mistake due to this (https://github.com/angular/angular-cli/issues/20979). – Simon_Weaver Jun 02 '21 at 08:01
  • @SamanthaAdrichem if you haven't yet tried to generate a brand new `ng new` project and compare the `angular.json` and `tsconfig` files I'd recommend doing that for sure. Haven't seen this actual error and I've since pushed my app to production which succeeded. – Simon_Weaver Jun 02 '21 at 08:02
  • @Simon_Weaver yeah I did that already. I'm getting a ton of errors though when migrating. Since angular 12, it no longer supports the require statement, but we're still in hybrid, old code still uses require for svg. I also figured out that the error on my side is caused because it's loading scss files that are not imported or referenced anywhere but are just in the folder.. But apparently as you stated, optimization actually RUNS for development, so I turned it off and it helped with half of the errors. The other ones are files that should not even be loaded, thats why it didn't seem to work. – Samantha Adrichem Jun 02 '21 at 09:18
  • @SamanthaAdrichem I'm not sure what you mean about `require`. I also use it to import some svgs and it's still working fine! I'm using `declare let require: any;` then `this.registerIcon('open-question', require('!svg-inline-loader?classPrefix!' + 'src/assets/images/icons/next_14_18.svg'))` to register the icon with a helper. No change with 12 with that. 12.0.3 just got released today, just looking at that now. – Simon_Weaver Jun 02 '21 at 18:40
15

As you say, the problem is to have sass / scss files in the assets folder.

Instead of moving these files out of the assets folder, you can just ignore them.

In angular.json, change

"assets": [
    "src/favicon.ico",
    "src/assets",
    ...
]

to

"assets": [
    "src/favicon.ico",
    {
        "glob": "**/*",
        "input": "src/assets/",
        "ignore": ["**/*.scss"],
        "output": "/assets/"
    },
    ...
]
Pascal
  • 151
  • 2
  • Yep this makes sense especially when you want to maintain the folder organization of having styles located in `assets` folder. Then for preprocessing, it can be imported in the global stylesheet or added to the styles `array` in angular.json – BrunoElo Nov 14 '22 at 04:31
6

I faced the same error, and my solution was to change the file angular.json, specifically the section projects -> "angular_name" -> architect -> configurations -> production -> optimization. Initially the value of optimization was optimization:true so I changed optimization section to this:

         "optimization": {
            "scripts": true,
            "styles": {
              "minify": false,
              "inlineCritical": true
            },
            "fonts": true
          },

As you can see the option minify was set to false, After changing this everything started to work

Check this link for more details about optimization https://angular.io/guide/workspace-config#optimization-configuration

Andres Rincon
  • 379
  • 2
  • 6
  • for me it worked perfectly, in spite of not generating minified css files, but I will check a way to remove these comments before minifying the files – Elvis Reis May 31 '21 at 18:37
  • For me it didn't work right away but I got a better error message which helped me fix the problem – koljaTM Nov 01 '22 at 09:15
4

I created a new project using Angular CLI 12.0.0 and then copied over portions of angular.json that were missing or different from my project.

In this application, it was:

"projects": {
  "schematics": {
    "@schematics/angular:application": {
      "strict": true
    }
  },
  ...,
  "architect": {
    "build": {
      "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "200kb",
                  "maximumError": "1024kb"
                }
              ],
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            }
          },
          "defaultConfiguration": "production"
    }
  },
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
      "configurations": {
        "production": {
          "browserTarget": "mdsl-authoring:build:production"
        },
        "development": {
          "browserTarget": "mdsl-authoring:build:development"
        }
      },
    "defaultConfiguration": "development"
  }
}

now ng serve works as expected. So if you're updating, be sure to check the differences between angular.json files in a new project vs yours.

Brandon Taylor
  • 33,823
  • 15
  • 104
  • 144
  • 1
    buildOptimizer and optimization to false, that solved my problem. It happened only when I use build --watch with optimization. When I do ng build --prod with optimization everything works. – Lachezar Raychev May 23 '21 at 16:45
1

I was strugling with this same problem. I needed to first add this:

npm --save install postcss-scss

https://www.npmjs.com/package/postcss-scss

and create the

postcss.config.js

file on root of the project.

add

module.exports = {
    syntax: 'postcss-scss',
};

most importantly don't forget to do

npm audit fix --force

now you can ng build or ng serve

this should fix the current angular 12 bug.

syncastra
  • 102
  • 1
  • 9
  • 1
    Is there any explanation for your solution? Why do you consider necessary `--force` flag? How does `npm audit fix` solve the issue? – jmeinlschmidt May 28 '21 at 14:40
  • It forces fixes in the installation of the package. This may or may not be necessary depending on your npm installations, it worked for me. I'm not knowledgeable enough to explain in detail. – syncastra May 28 '21 at 14:48
1

Make sure you don't have sass files inside /assets

I have my primary styles.scss file which references other files ...

@use '~@angular/material' as mat;
@import 'assets/preload/preload';    // this is preload.scss

As you can see one of the files is in assets. This is because it was originally included directly by the index.html file (for speed). With this nifty new inlining feature that uses critters I wanted it to be inlined using the default optimization settings.

SASS officially supports both common styles of commenting including //. However regular css (and the standard css parser) does not.

My preload.scss file happens to contain a few // style comments. This is absolutely fine when it's imported in styles.scss with @import because everything is processed through the sass compiler and // comments are fine.

However (and I'm not sure exactly why) the postcss-scss parser is looking inside /assets for scss files. It finds an invalid comment style and blows up. I think only ng serve does this.

The solution for me was just to move the preload.scss file to the same location as my other files. Hopefully if you're getting this same issue the fix will be the same.


Other observations / speculation:

  • ng serve loads and processes every file in assets (you can see it doing this if you enable verbose mode). I'm not sure exactly *what it's doing tbh but it's at that phase when it fails. And it does this even if it isn't referenced by anything.
  • If I run a production it doesn't fail because it's just copying assets without processing them.
  • If I disable optimization/minify then it also succeeds with ng serve. It's only in the minification that post-css is run.
  • I think this is a bug but I'm not entirely sure. It doesn't make sense to be processing asset files like this and is probably taking time.
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
1

From my part it was because I had wrong scss code. For example, incorrect variable setting.

Vugar Abdullayev
  • 1,852
  • 3
  • 21
  • 46
1

If anyone is getting the same error but has nothing to do with angular 12 or scss files being in the assets folder, it might be because you have errors in your scss file.

Errors can be:

  • importing another file that does not exist
  • syntax errors
  • using undeclared variables or mixins
David
  • 33,444
  • 11
  • 80
  • 118
0

Moving the offending styles dir to the includePaths of stylePreprocessorOptions did the trick for me.

"stylePreprocessorOptions": {
    "includePaths": [
        "src/assets"
    ]
},
Rocky Assad
  • 365
  • 1
  • 3
  • 10
0

Had the same problem. How I managed to solve it was by fixing the syntax errors from old Scss to new Scss.

It takes some time but in the end, it was all worth it.

(I had code from 2017 that I needed to use in Angular 12)

Arvid B
  • 31
  • 5
  • Welcome to StackOverflow! This reads more like a comment than an answer. Please read [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer) – Todd Jul 23 '21 at 15:56
-2

Angular 12

Add these code above "fileReplacements" foreach environment configuration in angular.json

"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true,

example:

"configurations": {
    "staging": {
        "buildOptimizer": false,
        "optimization": false,
        "vendorChunk": true,
        "extractLicenses": false,
        "sourceMap": true,
        "namedChunks": true,
        "fileReplacements": [{
            "replace": "src/environments/environment.ts",
            "with": "src/environments/environment.testing.ts"
        }]
    },
    "testing": {},
    "local": {}
}
AK109
  • 9
  • 2