angular-cli: css warning "variable '--some-var' is undefined"

Bug Report or Feature Request (mark with an x)

- [X] bug report -> please search issues before submitting
- [ ] feature request

Versions.

Angular CLI: 1.5.0 Node: 8.9.0 OS: win32 x64 Angular: 5.0.0 … animations, common, compiler, compiler-cli, core, forms … http, language-service, platform-browser … platform-browser-dynamic, router

@angular/cdk: 2.0.0-beta.12 @angular/cli: 1.5.0 @angular/flex-layout: 2.0.0-beta.10 @angular/material: 2.0.0-beta.12 @angular-devkit/build-optimizer: 0.0.32 @angular-devkit/core: 0.0.20 @angular-devkit/schematics: 0.0.35 @ngtools/json-schema: 1.1.0 @ngtools/webpack: 1.8.0 @schematics/angular: 0.1.0 typescript: 2.4.2 webpack: 3.8.1

Repro steps.

add to global styles.scss:

:root {
  --some-var: blue;
}

add to some component scss:

.some-class {
  background: var(--some-var);
}

ng serve

The log given by the failure.

NonErrorEmittedError: (Emitted value instead of an instance of Error) postcss-custom-properties:
<my-component>.scss:2:3: variable '--some-var' is undefined and used without a fallback
    at Object.emitWarning (<path>\node_modules\webpack\lib\NormalModule.js:117:16)
    at <path>\node_modules\postcss-loader\index.js:131:24
    at Array.forEach (<anonymous>)
    at <path>\node_modules\postcss-loader\index.js:130:31
    at <anonymous>

Desired functionality.

no warning needed, the component is defined in the global styles.scss and everything works

Mention any other details that might be useful.

one workaround is the create a _variables.scss with all the global :root { --my-var ... } and include this files in components. This will make to warning go away but the declarations in _variables.scss will be included few times

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 8
  • Comments: 21 (10 by maintainers)

Commits related to this issue

Most upvoted comments

The problem is more serious than the issue title.

Here are details on what @varoot explained :

If you serve your app in AOT with ng serve --aot, there won’t be a warning anymore. But the feature won’t work at all.

Given this code in styles.scss :

:root {
  --my-color: red;
}

And this code in a component :

p {
  color: var(--my-color);
}

the final CSS produced will be :

p {
  color: var(--my-color);
  color: var(--my-color);
}

But if I use the CSS var in styles.scss it will be OK :

p {
  color: red;
  color: var(--my-color);
}

So it’s like the CSS variables declared in styles.scss are not taken into account when parsing components styles.

The issue should be renamed and silencing the warnings won’t solve the problem.

I also don’t understand @clydin proposition :

The most appropriate solution would be to only enable the plugin when the app needs to support browsers that do not have native css variable support.

The problem is here in all cases.

So currently this feature doesn’t have a lot of sense, as being limited to use CSS variables just inside styles.scss is not useful. CSS variables would be useful to use in components style, for theming.

@garoyeri

Let me see if I understand this accurately

  1. The plugin currently only works if the css variable is defined in the :root on the same file where it’s used (not even when it’s imported).
  2. Defining :root also doesn’t work properly on component stylesheet if the view is encapsulated (but the plugin won’t complain)

So basically this plugin is only useful for people who wants to support legacy browser and only have one big global stylesheet (or define variables in each of the global stylesheets where it’s use)

That really doesn’t seem very useful and it might be better to just remove it.

postcss-custom-properties has variables option (https://github.com/postcss/postcss-custom-properties#variables). Maybe we can leverage this and define all css variables in .angular-cli.json or something then only enable this plugin when the variables are defined? (We will also need to output those variables in a :root selector if we go that route)

Also, using native css only (no scss) and got the same problem. Eagerly awaiting a fix for this.

We depend on postcss custom properties and need it included in our build → What is the proposed workaround for adding own postcss plugins to an angular-cli project?

Currently postcss-custom-properties is unconditionally enabled even in the case where the app will only be used on browsers that natively support css variables. Among postcss-custom-properties limitations is that it needs full knowledge of the context. In this case that cannot be known at build time hence the warning.

The most appropriate solution would be to only enable the plugin when the app needs to support browsers that do not have native css variable support.

I don’t think we should just suppress the warning. Having postcss-custom-properties is useful for supporting older browsers since it doesn’t break supporting browsers. I think the problem is that component css files are compiled separately from global css file (and also before). If we can concat the global and component css files (put global styles first) then postcss should be able to read the variables and compile correctly.