43081j / postcss-lit

PostCSS syntax for extracting CSS from template literals inside JS/TS files
84 stars 6 forks source link

Stylelint throws error #59

Closed evertmonk closed 2 months ago

evertmonk commented 3 months ago

I'm getting the following error when running stylelint.

7:33  ✖  Expected "POSTCSS_LIT_0" to be "postcss_lit_0"  value-keyword-case

This is my stylelint config.

{
  "plugins": [
    "stylelint-order"
  ],
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-prettier"
  ],
  "overrides": [
    {
      "files": ["**/*.styles.ts"],
      "customSyntax": "postcss-lit"
    }
  ],
  "rules": {
    "order/properties-alphabetical-order": true,
    "order/order": [
      {
        "type": "at-rule",
        "name": "include",
        "hasBlock": false
      },
      "custom-properties",
      "declarations"
    ]
  }
}

And this is the style file (I've created a minimal reproduction case).

import {css, unsafeCSS} from 'lit';

export default css`
  :host {
    align-items: center;
    display: block;
    transition: transform 600ms ${unsafeCSS('cubic-bezier(0.445, 0.05, 0.55, 0.95)')};
  }
`;

It seems that postcss-lit is manipulating ${unsafeCSS('cubic-bezier(0.445, 0.05, 0.55, 0.95)')} before the linter is running over it.

And when I run the stylelint with the fix flag the runtime code is changed to

transition: transform 600ms postcss_lit_0;

I'm not sure what's happening or if it's something on my side but it's very unexpected behaviour.

43081j commented 3 months ago

this'll be the standard config conflicting with postcss-lit i imagine

you're interpolating cubic-bezier rather than writing it inline, so postcss-lit has no option but to turn that into a placeholder (since it isn't feasible to try turn your JS expressions into strings).

due to that, it'll become transition: transform 600ms POSTCSS_LIT_0 (i.e. the expression is replaced with a placeholder)

we could lowercase our placeholders to fix this, though anyone with a config requiring uppercase names will have the same problem then. there's not really any true solution to this, only best-effort.

aligning to the standard config seems to make sense, so lowercase probably is a sensible change

evertmonk commented 3 months ago

Ok, I understand. Thanks for clearing up.

I do think it's weird that the code is transformed on runtime and actively overwrites the code. I understand that placeholders are necessary for running the linter but I would expect that the placeholder is removed after the linter has run.

I'll see if there's anything in the standard config that could cause this behaviour. Maybe because it exits after running into an error and that causes the placeholder to stay in the code.

43081j commented 3 months ago

The placeholder only exists during linting and transform

E.g. if you have a postcss plugin transforming your CSS, it can't possibly transform or understand your JS. So it has to transform the CSS produced by inserting the placeholders, then replace the placeholders with the original JS at the end

Make sense?

There aren't any simple solutions to this. This is the one we settled on here.

evertmonk commented 2 months ago

Yes makes sense. I'm saying that the placeholder stays in my code after the linter throws an error on the rule. This means that the placeholders are not replaced back to the original JS.

43081j commented 2 months ago

The placeholders are replaced, the error will just be happening before then so postcss will throw and bail

What are you seeing that makes you think they stay in there? postcss shouldn't output anything since it errored

We can fix your particular problem by lower casing our placeholders

evertmonk commented 2 months ago

I'm working in Webstorm and I have the linters running whenever I save a file. Once I save the file, the linter runs and throws an error, after that my file is updated and shows transition: transform 600ms POSTCSS_LIT_0 in my file.

I'm looking into where the actual issue is located. It's also difficult to determine the order in which these things are happening. I'll do some tests in other editors to see if it's actually something with Webstorm.

evertmonk commented 2 months ago

https://github.com/user-attachments/assets/1807a505-9634-4c0a-be2d-3788a3b686a0

Here's a screencap of what is happening. The placeholder is automatically lowercased by prettier in this instance.

43081j commented 2 months ago

that's so strange 😬 certainly not what should be happening

postcss consumes this as a parser and stringifier. there should be no way it skips the stringifier, so it shouldn't be possible for that to happen

i suspect its specific to webstorm somehow. is there any chance you can try in another editor (vscode maybe?)? and similarly, does it still happen with prettier disabled?

evertmonk commented 2 months ago

Yes it appears to be webstorm specific. I ran it in a few different editors and they do not alter the code like what happened in webstorm.

They do complain about the uppercase though. I'm bypassing it by adding this in the rules

"value-keyword-case": ["lower", {"ignoreKeywords": ["/POSTCSS_LIT_[0-9]+/"]}]