stylelint/postcss-css-in-js

Deprecate package

jeddy3 opened this issue ยท 27 comments

We've been working on a new major release of Stylelint. There are quite a few changes (and a lot of refactoring). One of the biggest changes we've made is removing the syntax option (context here) and no longer bundling syntaxes (this one included) in Stylelint itself. Users will need to extend stylelint (via shared-configs, plugins and custom syntaxes) to lint something other than vanilla CSS.

To make this easier for users to do, we've added two properties to the configuration object:

  • customSyntax - which accepts an PostCSS syntax like postcss-scss
  • overrides - which allows users to configure stylelint to lint two or more languages or libraries, e.g. CSS and LitElement.

The migration guide has examples of these in use.

We also intend to deprecate this package (not for the 14.0.0 release, though) in favour of smaller packages that focus on a single CSS-in-JS library or small group of related libraries. This package currently tries to support all CSS-in-JS libraries, but there is too much churn and too many differences in the growing number of them for this to be sustainable. We're left with a growing list of issues related to CSS-in-JS.

If you use Stylelint to lint CSS-in-JS, please consider creating a syntax for the library you use. The Document node added in PostCSS@8.3 may be of use, and you can avoid using postcss-syntax. If you do create a syntax, please post a link to it below so that everyone is aware of it.

To make things easier for users, we're also recommending syntax authors create a shared-config that bundles their syntax, so that it can more easily be consumed by users. For example, for Stitches:

// stylelint-config-standard-stitches
module.exports = {
  extends: [
    "stylelint-config-standard",
  ],
  overrides: [
    {
      files: ["**/*.{js,ts}"],
      customSyntax: ["postcss-stitches"],
      // turn off any rules not compatible with Stitches
      // or turn on and configure any built-in rules for to it
      rules: {
        /* ..  */
      }
    }
  ]
};

If a plugin pack of rules exist for a library, that could also be bundled in the shared-config. For example:

// stylelint-config-standard-stitches
module.exports = {
  extends: [
    "stylelint-config-standard",
  ],
  plugins: ["stylelint-stitches"],
  overrides: [
    {
      files: ["**/*.{js,ts}"],
      customSyntax: ["postcss-stitches"],
      // turn off any rules not compatible with Stitches
      // or turn on and configure any built-in rules for to it
      rules: {
        /* ..  */
        "stitches/some-rule": true
      }
    }
  ]
};

@abdonrd Thanks for merging pull requests this last while! Am I right in thinking you're linting LitElement components? That's a good candidate for a separate syntax.

It'll take a while for new syntaxes to appear, as such we suggest users install this package in our 14.0.0 migration guide. This package will still be in use for a while yet. If anyone fancies maintaining this package during this transition phase (or @abdonrd if you need npm access to publish), then please say so and I'll make sure you have the necessary permissions for this repo and the npm package. New versions (including major ones) can now be published independently of Stylelint.

we also use stylelint for lit. i'd be happy to put together a syntax for it (unless you're already on it @abdonrd :D)

definitely makes a lot of sense to make stylelint much more focused. a lot like how rollup works and many other "modern" tools

@43081j I'm not on it. I need more time! ๐Ÿ˜… So go for it!

Also ping to @web-padawan & @bennypowers who were also interested.

@jeddy3 is there now a reference package anywhere? a syntax someone has made already.

are they identical to postcss syntaxes? or is there a difference between syntax we pass to stylelint and one we pass to postcss? we don't need a reference if its just a standard postcss syntax

@43081j It's great that you're happy to put together a syntax for lit!

is there now a reference package anywhere?

I'm not aware of one for CSS-in-JS libraries, i.e. one that uses a JavaScript parser like Babel under the hood. If that is needed for a lit custom syntax, then you're probably best using this package as a reference.

However, postcss-html and postcss-markdown were recently migrated to PostCSS 8. Both these integrate parsers, htmlparser2 and remark respectively. You may find some useful pointers there, especially the migration away from postcss-syntax to PostCSS@8's Document node.

Other syntaxes that are compatible with PostCSS 8 include:

  • postcss-scss
  • postcss-less
  • sugarss

are they identical to postcss syntaxes?

I believe so. The syntax should work (and can be tested) with any PostCSS plugin, e.g. autoprefixer.

We have a fledging guide in our docs. After working on your syntax, you're welcome to share any suggestions for improvements to that guide.

sounds good to me, i'll have a look.

i quickly put one together already which extracts template literals in the parse function, but figure the heft of the code will be correcting location information. do love that rabbit hole (been there many times in eslint plugins ๐Ÿ˜‚ )

i'll get it published to a WIP repo at some point as there's many questions i can't answer myself (not only for you, but for consumers, etc)

The postcss-lit source is available, thanks to @43081j. I believe it's the first CSS-in-JS library syntax to use PostCSS@8.3's Document node. If you intend to write a custom syntax for another template-literal library, e.g. styled-components, you may want to use it for reference.

If you're writing a custom syntax for an object-based library, e.g. Stitches, you may still want to use it for reference but also refer to the object extraction code in this package.

Once there's an object-based reference syntax available, I believe we can deprecate this package (and discontinue the use of postcss-syntax as both postcss-html and postcss-markdown have also been migrated to use PostCSS@8.3's Document nodes).

@jeddy3 @hudochenkov Since the postcss-lit source is available, is there's any update regarding a syntax for styled-components?

@stovmascript since there's no activity, i'll give it a go. will try report back in a few days and hopefully have something

is there's any update regarding a syntax for styled-components?

I'm not aware of one.

since there's no activity, i'll give it a go

Fantastic, thank you!

I was working on styled components syntax, but didn't have time to investigate deep enough. The main problem is interpolation. It could be very extensive. I used similar approach as postcss-lit: replace interpolation with comments (way before postcss-lit was public :)). But it doesn't work reliably โ€” PostCSS parses code with comment replacements in unexpected way. Because comment appears, when it wouldn't in normal CSS.

postcss-css-in-js parses code with interpolations more or less reliably. My next step is to look into how it is done. Here some examples from my notes that should be parsed correctly as it's all valid styled components syntax:

Parse simple interpolation

styled.div`color: red;${borderWidth}; border-color: blue;`;
styled.div`color: red;${borderWidth}`;
styled.div`color: red;${borderWidth};`;
styled.div`${borderWidth}color: red`;
styled.div`${borderWidth};color: red`;
styled.div`color: ${red}`;
styled.div`color: ${red};`;
styled.div`${color}: red`;
styled.div`${color}`;

styled.div`${Component} { color: red; }`;
styled.div`${Component}, a { color: red; }`;
styled.div`a, ${Component} { color: red; }`;
styled.div`a, ${Component}, b { color: red; }`;

Parse interpolation with css (one level deep)

styled.div`color: green;${css`color: red`}`;
styled.div`${css`color: red`}${css`color: blue`}`;
styled.div`${css`color: red`}color: green;${css`color: blue`}`;
styled.div`color: green;${props => `color: red`}`;

Parse interpolation with css (many levels deep)

styled.div`${css`color: red;${css`color: blue`}`}`;
styled.div`${css`color: red;${css`color: blue;${css`color: green;`}`}`}`;

Parse interpolations with props

styled.div`color: green;${props => css`color: red`}`;

yeah im well aware the comment placeholders aren't suitable for all cases in both lit and styled-components, its an open issue i just haven't got time to sort yet (but do have a solution, and did when i wrote it, just didn't have time to do it).

its pretty easy to spin up a styled-components variation of my lit syntax. the expression placeholder problem has to be solved for both of them anyway, nothing special with styled-components really.

feel free to build such a syntax though. ill probably still finish mine since its helping me tidy up some of my core code, but doesn't necessarily have to become the syntax people use.

but do have a solution, and did when i wrote it, just didn't have time to do it

@43081j do you mind sharing your idea how to reliably parse interpolations?

sorry, times got busy so i still have a half-finished styled-components syntax lying around somewhere.

for the expressions, we currently replace them with comments except when they're prefixed with an = in the lit syntax, which is good enough for now. styled-components has a lot more scenarios though.

a proper solution would be to look behind at what precedes our expression to guess what kind of position it is in. for example, if its after a : and any space, its more than likely a value position so we'd need our placeholder to be a valid value (syntactically at least). if its before a :, its probably a property position, etc etc.

most older syntaxes/plugins did it this way too IIRC.

@43081j Analyzing code around might be the only solution, indeed. Thank you.

Hi folks,

What is the current status of this package? It seems to not detect lint errors anymore: is that totally dead?

I made styled-components linting work again thanks to @lbragile solution, thanks for that.

But I quickly faced an issue which is the unavailability of stylelint --fix when using a processor :|

Did anyone find a durable solution for stylelint usage on styled-components in 2022?
And/or gave postcss-lit a try (not clear if it could do the job, or just process literals)?

Hi folks,

What is the current status of this package? It seems to not detect lint errors anymore: is that totally dead?

I made styled-components linting work again thanks to @lbragile solution, thanks for that.

But I quickly faced an issue which is the unavailability of stylelint --fix when using a processor :|

Did anyone find a durable solution for stylelint usage on styled-components in 2022? And/or gave postcss-lit a try (not clear if it could do the job, or just process literals)?

postcss-lit seems to work out of the box with --fix! Thank you.

I couldn't find a way to use the vscode extension properly though -- so that it would lint on save.

edit: extension works fine.

@Lippiece Which CSS in JS lib are you using? ๐Ÿค”

Really a styled components custom syntax is needed for a proper solution, though the lit one might mostly work for common use cases.

I did start writing one but haven't really had the time to finish it unfortunately.

@Lippiece Which CSS in JS lib are you using? ๐Ÿค”
@monsieurnebo
Emotion