Skip to content
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

Explore using Lightning CSS instead of PostCSS in core (or as an option) #11029

Closed
4 tasks done
surajondev opened this issue Nov 22, 2022 · 16 comments · Fixed by #12807
Closed
4 tasks done

Explore using Lightning CSS instead of PostCSS in core (or as an option) #11029

surajondev opened this issue Nov 22, 2022 · 16 comments · Fixed by #12807
Assignees
Labels
enhancement New feature or request p4-important Violate documented behavior or significantly improves performance (priority) performance Performance related enhancement

Comments

@surajondev
Copy link

Description

I was developing a project with ViteJS and needed to integrate Lightning CSS as the CSS parser. I couldn't able to find any plugin for its integration.

Suggested solution

Will love to see, if you create a plugin for its support.

Alternative

No response

Additional context

No response

Validations

@devongovett
Copy link

devongovett commented Nov 25, 2022

Hi, I'm the main author of Lightning CSS. I think it would be awesome if Vite switched to Lightning CSS for its builtin CSS plugin. I have received several issues on the Lightning CSS repo asking for a Vite plugin, and while there is https://github.com/lawrencecchen/vite-plugin-lightningcss, this cannot handle the tasks that Vite has builtin such as bundling (via postcss-import), CSS modules, URL rebasing, and minification. As far as I can tell, those cannot be replaced by user plugins and are hard coded into Vite. So, while you could use the above plugin as a replacement for something like postcss-preset-env and autoprefixer, you'd still be running PostCSS for some builtin tasks. Would be great if everything could either be swapped by the user, or if Vite switched its builtin code to use Lightning CSS instead.

I made a prototype of replacing the current PostCSS-based bundler and esbuild-based minifier with Lightning CSS a while ago: devongovett#1. The tests were mostly passing at the time, so it shows that it is possible to replace the builtin CSS plugin with a Lightning CSS version.

In addition, Vite could add new features such as automatically down leveling CSS for the configured browser targets like you do for JS (equivalent to manually configuring postcss-preset-env and autoprefixer now). You could also potentially use the Lightning CSS minifier rather than esbuild for CSS, which can produce smaller output even faster. PostCSS plugins could still be supported for custom transforms of course, but by default, this would eliminate them and improve performance.

Lightning CSS is maintained by the Parcel team, and has been the default in Parcel since March. Please let me know if you need any help if you decide to move forward on this. The PR on my fork above is a good starting point, but it would need someone from the Vite team who is more familiar with the code to clean it up and integrate it more fully I think.

@LeoDog896
Copy link
Contributor

Given that Vite uses ESBuild for CSS minificatition, it could be swapped out (but it also takes in config options which would make it a breaking change).

@patak-dev patak-dev changed the title A plugin support for Lightning CSS Explore using Lightning CSS instead of PostCSS in core (or as an option) Mar 10, 2023
@patak-dev patak-dev added p4-important Violate documented behavior or significantly improves performance (priority) performance Performance related enhancement labels Mar 10, 2023
@silverwind
Copy link

silverwind commented Mar 19, 2023

Why not have a plugin system for CSS? A modern project written with plain CSS does not need any CSS processor at all and the job of bundling CSS is mostly just simple concatenation. This is how modern webpack configs do it and it's amazingly fast if when no CSS processor is involved.

So I think it could be made a user's choice if they want PostCSS, LightningCSS or any other processor.

@ArnaudBarre
Copy link
Member

Internally PostCSS is "just a plugin". The goal is to provide a new one and allow to disable the current one.

I think this is nice that CSS modules are handled by default. And LightningCSS is so fast that you if it takes more than 10ms for your project, you probably shipping too much CSS.

What I'm thinking of is two new options like this:

cssTransformer?: "PostCSS" | "LightningCSS" | null
cssMinifier?: "esbuild"  | "LightningCSS"

cssTransformer:

  • defaults to: "PostCSS" in v4
  • defaults to: "LightningCSS" in v5, with LightningCSS as a peerDependency.
  • null would disable both and let you provide your own (can be implemented in ~10 lines if just just serving files from disk)

cssMinifier:

  • defaults to: "esbuild" in v4
  • defaults to: "LightningCSS" in v5, with LightningCSS as a peerDependency

@devongovett
Copy link

If it's a peer dependency but used by default for CSS, would that mean that CSS would no longer be handled out of the box? You'd need to stop, npm install lightningcss, and restart Vite the first time you add a CSS file?

My understanding is that Vite uses PostCSS internally for CSS bundling and URL rebasing, not just when you have custom PostCSS plugins configured. Ideally that part would be swappable too so you avoid an additional parse, which means any time you have a CSS file at all an additional dependency would be needed.

@mxdvl
Copy link

mxdvl commented Mar 27, 2023

If it's a peer dependency but used by default for CSS, would that mean that CSS would no longer be handled out of the box? You'd need to stop, npm install lightningcss, and restart Vite the first time you add a CSS file?

In theory, you have to install all peer dependencies unless they are explicitely marked as optional. This is now the default in npm v7.

@silverwind
Copy link

silverwind commented Mar 27, 2023

If it's a peer dependency but used by default for CSS, would that mean that CSS would no longer be handled out of the box? You'd need to stop, npm install lightningcss, and restart Vite the first time you add a CSS file?

I guess the ideal flow would be npm create vite to interactively ask for CSS transformer and possibly minifier (just like it does for other plugins) and then install the explicit dependency, no peerDependency needed, because those just bloat the install/download size of vite when unused.

@devongovett
Copy link

My point is that it's not really optional. Seems like it would be very rare not to have any CSS at all in a web application, and therefore you'd almost always need to install one of these options. This makes sense as a plugin if you're only interested in swapping PostCSS for transformations (e.g. postcss-preset-env, autoprefixer, etc.) or custom plugins, but I think it would be great to swap out the minifier, bundler, etc. as well. If the default is not installed by default almost every user of Vite will need to do that manually.

@silverwind
Copy link

silverwind commented Mar 27, 2023

Every app needs CSS and maybe also a CSS minifier. But not every app needs a CSS transformations.

In a sense it's similar to JS where previous transpilation/polyfills/etc are now mostly unnecessary baggage that slows down the build and may even introduce bugs of its own.

@ArnaudBarre
Copy link
Member

Yep sorry if this was not clear, the default CSS bundler will always come as a dependency of Vite. Using the non-default one will require to install it to reduce default install size. Both plugins will be built-in. The proposed null option would be an edge case for experimenting external CSS plugins.

I need to start working on it to be sure everything here is feasible, but that's really on top of my todo list for Vite.

@silverwind
Copy link

silverwind commented Mar 27, 2023

Yeah, I do see this null handler also as something for plugins first and if it proves usable, it could be made a third official option.

i assume some transformations will always be necessary, like @import and url() handling. Basically what webpack does with just css-loader alone, no postcss-loader.

@alexanderniebuhr

This comment was marked as outdated.

@ArnaudBarre
Copy link
Member

Yep didn't have time in the last week to finish the work on it. But yeah hoping to merge in the coming weeks :)

@nstepien
Copy link

I'd recommend against making lightningcss the default until these issues (parcel-bundler/lightningcss#109 parcel-bundler/lightningcss#292) are fixed, as they may break existing stylesheets.

@alexanderniebuhr
Copy link

I'd recommend against making lightningcss the default

I would be happy if it is an opt-in option to choose.

@alexanderniebuhr
Copy link

I'm seeing some progress in the PR. Could you maybe plan to release a beta. For me personally I would be able to use it in current state, without all the options discussed in the PR.

@github-actions github-actions bot locked and limited conversation to collaborators Jul 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request p4-important Violate documented behavior or significantly improves performance (priority) performance Performance related enhancement
Projects
None yet
9 participants