-
Notifications
You must be signed in to change notification settings - Fork 167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom parser and visitor API #94
Conversation
Oooo yes please! 👌 Sounds like this could be used to build in some sort of |
@devongovett Any plans to continue with this? |
Sure. Mainly I was waiting for someone to have a need for it. |
I have a need for it! 🙋🏻♂️😃 |
This looks very cool! We have a framework we use that is a bunch of postcss plugins implementing different at-rules with a centralized config file at the heart of it. It would be supercool if we could implement it in parcel-css/lightning-css instead! |
I have a need for something similar to this: custom value parsing. At Discord we (unfortunately) have a bunch of legacy code that uses $variables (from postcss-simple-vars), and it'd help us migrate to Lightning if we could reimplement that plugin without forking 😀 |
Having it in the rust api and having plugins are two different things. With this, you'd need to compile your own CLI or node bindings to use it. Plugin support would be much much more difficult. |
I would imagine plugins being a huge deal, both as far as implementing support for them - and the effort it would take - and the impact they could make. Realistically, the only alternative is PostCSS, but that can be very slow, especially when compared to lightningcss ⚡️ FWIW I'd be happy with compiling my own CLI. My use case is simply a way to implement mixin's, which is kinda similar to Tailwind's Come to think of it, this would be the same syntax as CSS modules Anyway, any kind of progress on this front would be amazing 😄 |
Plugins are much harder with a compiled tool than with a scripting language. The main challenge is that Rust is not ABI-stable. What this means is that the binary interfaces that are generated for functions, structs, enums, etc. may differ between compiler versions (even minor ones). So plugins would have to be compiled using exactly the same Rust compiler version in order to work. There are ways of making this work by exposing a very intentionally designed C API instead, but it would be a huge amount of work to do this given the scope of Lightning CSS's AST. Not to mention maintaining both forward and backward compatibility over time. Personally, I think PostCSS is a great tool for building custom plugins. You can use PostCSS and Lightning CSS together by passing the output of one to the other. Even just reducing the number of PostCSS plugins you use to just the custom ones, and removing autoprefixer/preset-env/cssnano will improve the performance of your build by quite a bit. Another way to handle this could be to use PostCSS to codemod your source CSS. For example, you could write a PostCSS plugin to convert the Lightning CSS will generally try to stick to standards and not deviate too much into supporting non-standard syntax. We may eventually have plugins, but it is a long way off and will be a lot of work for IMO questionable gain. I'd love to collect some of the top PostCSS plugins that people use, and discuss what alternatives could be used on a case-by-case basis. That said, I do want Lightning CSS to be able to be used by other higher level tools. For example, it would be cool if Tailwind CSS could be implemented in Rust using our parser. That was the goal of this PR. This inverts the plugin model - rather than injecting things into a pre-compiled CLI or Node module, you'd compile your own CLI/Node module with the customizations you need. That solves all of the hard points of a plugin system, at the expense of ease of use. But for tooling, it might be ok. |
Yeah, that's the fallback plan, and certainly better from a "make your code as non-weird as possible" standpoint. I'll also keep in mind what you mentioned about combining Lightning CSS and PostCSS as well, perhaps I'm overestimating the time PostCSS spends parsing. |
…stom-at-rule # Conflicts: # src/bundler.rs # src/declaration.rs # src/logical.rs # src/parser.rs # src/properties/mod.rs # src/rules/document.rs # src/rules/layer.rs # src/rules/media.rs # src/rules/mod.rs # src/rules/nesting.rs # src/rules/style.rs # src/rules/supports.rs # src/selector.rs # src/stylesheet.rs
e56a521
to
305733f
Compare
…stom-at-rule # Conflicts: # src/selector.rs
… into custom-at-rule
This has expanded to include a Visitor API, which will allow custom transforms to be built much more easily. For example, you could implement a custom function like tailwind's The The example implements a basic transform for cc. @adamwathan @RobinMalfait this may be relevant to your interests 😉 |
Please,
Do u think you could help me? How mucg would u charge me to do this for me?
I definitely need a professional!
(I have way too many email addresses)
Thank you,
Renee Brutcher
6364284242
***@***.***
…On Sun, Sep 11, 2022, 11:17 AM Joel Moss ***@***.***> wrote:
I would imagine plugins being a huge deal, both as far as implementing
support for them - and the effort it would take - and the impact they could
make. Realistically, the only alternative is PostCSS, but that can be very
slow, especially when compared to lightningcss ⚡️
FWIW I'd be happy with compiling my own CLI. My use case is simply a way
to implement mixin's, which is kinda similar to Tailwind's @apply. But
really is just replacing an at rule with some standard CSS rules.
Come to think of it, this would be the same syntax as CSS modules composes,
but would actually mixin the rules from the referenced class, instead of
just referencing the class name.
Anyway, any kind of progress on this front would be amazing 😄
—
Reply to this email directly, view it on GitHub
<#94 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AX26CFBBFDJXVJDG6NJET6LV5YAX5ANCNFSM5O4YZ6DA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
This is an experiment that adds support for custom (non-standard) at rules to be parsed via the Rust API, allowing something like Tailwind to be implemented. It's accomplished by passing a custom
AtRuleParser
trait implementation to theParserOptions
struct. During parsing, the methods of this trait are called if no standard at rule is seen. TheCssRule
type has been extended to support aCustom
variant, which wraps theAtRuleParser::AtRule
type. This allows custom structs provided by the user to be stored as part of the stylesheet.An example is included that implements simple
@tailwind
and@apply
support via this API. It can be run by cloning the branch and runningcargo run --example custom_at_rule test.css
, wheretest.css
might look something like this:output:
We'd need to expose more things if we wanted to implement it for real, e.g. the printer for better formatting/sourcemaps and maybe a way to hook into the transform/minify pass. Mainly wanted to get feedback to see if this is a useful direction before continuing too far. Tailwind also has custom functions like
theme
, and I'm not sure how we'd handle those yet (probably by exposing thePropertyHandler
trait for unparsed properties).It's worth noting that this approach is a bit different from how something like PostCSS works. PostCSS would accept any unknown at rule and try to guess what it can contain (does it have a block? does the block accept declarations, rules, or something else? etc.), whereas Parcel CSS works more like how browsers parse CSS where only known rules are supported which control how the rule is parsed. This results in much better performance, better error handling, and more predictable results. Hopefully it is flexible enough. If not, I suppose we could try to implement that but I'm not sure it's possible without potentially unbounded lookahead in the parser...