postcss / postcss-custom-properties

Use Custom Properties in CSS
https://postcss.github.io/postcss-custom-properties
MIT License
596 stars 77 forks source link

Make non-async if there's no need for awaits #181

Closed eteeselink closed 5 years ago

eteeselink commented 5 years ago

This makes postcss-custom-properties act as a synchronous plugin (i.e. so users don't need to await the result of postcss(..).process()), if and only if nothing is imported nor exported.

Some background: we're trying to use postcss-custom-properties in a server setup where user-written CSS is compiled down. For many practical reasons, making the entire pipeline asynchronous is prohibitively hard, and given that we don't use any importing/exporting, we found ourselves wishing postcss-custom-properties was just a synchronous thing altogether. Well, now it is :-)

Given that some of the existing tests don't import or export things, the new code is automatically covered. So I've not added any tests.

I don't have an extremely detailed understanding of the internals of postcss, but if I understand it right, plugins can either return or promise or not, and postcss papers over the difference pretty transparently. Notably, I believe that you can await a postcss pipeline even if all plugins happened to have run synchronously - that would be pretty important for this change to be backward compatible. My limited manual testing shows that this is indeed the case but I might have missed some edge case.

jonathantneal commented 5 years ago

Very interesting idea. I wasn’t aware of a big need to provide a strictly synchronous setup.

Is this in a major piece of software? If so, where is the async bottleneck?

eteeselink commented 5 years ago

It's commercial software (https://talkjs.com). We're writing a layer that lets customers write their own HTML and CSS components in a secure and extremely low-friction way.

This includes a custom template language that's designed to allow writing vue-style single file components in a safe way (no custom JavaScript). We're planning to open source this language. These single file components include a <style> element that allows for custom, scoped, css.

Somewhere deep in the compiler we run postcss on this user css to scope the classes (using postcss-prefixer), to compile css variables down (using your excellent work), and a few more things. The entire compiler pipeline is synchronous (because it takes a string and produces a react component), and wrapping it all in promises and awaits would needlessly complicate all the functions and data structures. Especially since there's actually no I/O going on - the promises would all resolve right away.

Is this the sort of background info you were asking for?

Thanks for all your excellent work on postcss, by the way! It's splendid stuff.

jonathantneal commented 5 years ago

Yes, that is exactly what I needed to help understand this problem. The context is wonderful. I really appreciate it. I am tentatively merging this, but I’ll want to be sure the pattern looks right before publishing. I’m probably publishing soon, even if I can’t finish the integration with PostCSS Custom Utils that would also manage your particular issue.

eteeselink commented 5 years ago

Great to hear!

That said, I'm not entirely sure how PostCSS Custom Utils would help solve our particular issue, I'm missing some understanding I think.

Let me know if there's any way I can help!