postcss / postcss-simple-vars

PostCSS plugin for Sass-like variables
MIT License
415 stars 36 forks source link

Weird issue with version 6.0.3 and cssnano #94

Closed nemphys closed 3 years ago

nemphys commented 3 years ago

I just updated to the latest 6.0.3 version and I am facing the following problem:

In my plugins chain, I have postcss-simple-vars first, followed by some other plugins and then cssnano last. In my source, I declare a variable like this:

$variable: 15px;

And then use it like this:

.xxx { width: $variable; height: $variable; right: calc($variable / 2 * -1); }

If I omit cssnano, all is rendered as expected:

.xxx { width: 15px; height: 15px; right: -7.5px; }

After adding back cssnano, I get the following exception:

Lexical error on line 1: Unrecognized text. Erroneous area: 1: $variable / 2 * -1 ^..^

Needless to say that this all used to work fine until 6.0.2.

Any ideas?

ai commented 3 years ago

This error came from cssnano, you should open an issue there.

nemphys commented 3 years ago

I don't think that this has to do with cssnano, since it worked fine up until this latest release of postcss-simple-vars. As you can see in the error message, cssnano complains about $variable, which should not be there when cssnano runs (presuming that the plugins execute sequentially and so the $variable should have been replaced by postcss-simple-vars at the time cssnano is executed).

sampullman commented 3 years ago

@nemphys It looks like cssnano has updated to Postcss8 on the master branch, which may fix the problem, but hasn't made a release in quite a while. I think the real problem is that it shouldn't complain about $variable, since it's none of their business.

@ai I assume this is due to using the visitor callbacks. cssnano is on 7.x still, so it seems like it runs first no matter the plugin order. Previously you could hide the issue by making sure postcss-simple-vars was first, but that's no longer a workaround.

nemphys commented 3 years ago

OK, I get it now, thanks.

sampullman commented 3 years ago

@nemphys It looks like the issue is https://github.com/postcss/postcss-calc/issues/89

It's solved in the latest version of postcss-calc, so until cssnano updates you could work around this by doing something like:

postcss([
  ...,
  require('postcss-simple-vars')(),
  require('cssnano')({ preset: ['default', { calc: false }] }),
  require('postcss-calc')(),
  ...,
])
nemphys commented 3 years ago

@sampullman Tried this and it indeed stops throwing an exception, but the css is not processed properly. Since it is a postcss-calc issue, why does it not show up unless I use cssnano and, furthermore, since it is "fixed in the latest version of postcss-calc", why is it still showing up (you lost me there)?

sampullman commented 3 years ago

@nemphys I'm not sure what the details of your setup are, but the above fix worked for my simple reproduction:

Input

$x: 1;
a { left: calc($x / 2) }

Output:

a{left:0.5}

What I mean is that in the current cssnano release, they are using postcss-calc v7.0.1: https://github.com/cssnano/cssnano/blob/cdedda7f9d67873d872add044ad34c91616579f3/packages/cssnano-preset-default/package.json

The latest master of cssnano is using postcss-calc v8.0.0, so this issue should be fixed with cssnano's next release. In my workaround, if you manually install postcss-calc 8.0.0 and disable the old version from cssnano, it should work.

nemphys commented 3 years ago

OK, it now makes sense. I hadn't realized that cssnano was using postcss-calc internally; I already have postcss-calc 8.0 in my plugins array, between postcss-simple-vars and cssnano and that's why your comment made my scratch my head :-)