stylex
stylex copied to clipboard
Vite plugin
It would be nice to have a Vite plugin. I tried the rollup plugin with a fresh React + Vite and got an error:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import stylex from '@stylexjs/rollup-plugin'
export default defineConfig({
plugins: [react(), stylex()],
})
Error:
[vite] Internal server error: /Users/walmartwarlord/tmp/react-stylex-test/src/index.css: Unexpected token (1:0)
> 1 | :root {
| ^
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
Plugin: rollup-plugin-stylex
File: /Users/walmartwarlord/tmp/react-stylex-test/src/index.css:1:0
1 | :root {
| ^
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
at constructor (/Users/walmartwarlord/tmp/react-stylex-test/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:356:19)
Edit: Cleaned up the fresh project; dev
now runs successfully. However, running build
leads to a different error.:
import stylex from '@stylexjs/stylex'
const s = stylex.create({
main: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 10,
paddingTop: 20,
}
})
function App() {
return (
<main className={stylex(s.main)}>
<h1>Hello</h1>
</main>
)
}
vite v5.0.5 building for production...
✓ 0 modules transformed.
[rollup-plugin-stylex] /Users/walmartwarlord/tmp/react-stylex-test/index.html: Unexpected token (1:1)
> 1 | <!doctype html>
| ^
2 | <html lang="en">
3 | <head>
4 | <meta charset="UTF-8" />
file: /Users/walmartwarlord/tmp/react-stylex-test/index.html:1:1
error during build:
SyntaxError: /Users/walmartwarlord/tmp/react-stylex-test/index.html: Unexpected token (1:1)
> 1 | <!doctype html>
| ^
2 | <html lang="en">
3 | <head>
4 | <meta charset="UTF-8" />
at constructor (/Users/walmartwarlord/tmp/react-stylex-test/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:356:19)
I encountered the same issue and put together a vite plugin based on the rollup plugin implementation: https://github.com/HorusGoul/vite-plugin-stylex
Install it with npm install --save-dev vite-plugin-stylex
and use it like this:
// ... other imports
import styleX from "vite-plugin-stylex";
export default defineConfig({
plugins: [react(), styleX()],
});
I haven't tried more complex use cases like SSR yet, but I guess we can add support for those as needed by users (already thinking of trying this with the new Remix Vite plugin)
Question for maintainers: Is there a plan for an official Vite plugin? Or is this expected to be covered by the community using lower-level plugins like the Babel one? Thanks!
Unplugin could be interesting to consider, since it would allow only maintaining one implementation: https://github.com/unjs/unplugin
I think it would be easier to implement based on the rollup version than to switch to unplugin :)
We do want to support an official Vite plugin, but we want it to support "complex use cases like SSR" as well. This is important to us as many Vite projects like Remix, Qwik, Astro or the upcoming Solid-Start won't ship some components to the browser at all. Even in development.
We want our Vite plugin to work for these scenarios.
Perhaps our Rollup plugin can be enhanced to work in the simpler case with Vite as well?
@nmn I'm interested in this. I can create a pull request until the test case be passed in my local.
So does this mean I can't spin up a project using Vite, and start using this simply straight away?
@JakeSaterlay
Depends on the complexity of the setup you're using, for example, my unofficial plugin doesn't support Astro or Qwik yet, but it works with a basic create vite app that uses React (SPA) or even Remix using the unstable vite template.
@HorusGoul, I am currently experimenting with vite-plugin-stylex
using Remix. But it seems that including import 'virtual:stylex.css'
in root.tsx
causes some problems.
In dev mode there is a duplication of styles with built-in styles from vite.
In the production build, the <head>
contains only one style reference (root-I-XxiNSD.css
) but no stylex reference (stylex.cdf3995e.css
).
> vite build && vite build --ssr
vite v5.0.6 building for production...
⚠️ Remix support for Vite is unstable
and not recommended for production
✓ 70 modules transformed.
public/build/.vite/manifest.json 0.89 kB │ gzip: 0.27 kB
public/build/assets/root-I-XxiNSD.css 0.45 kB │ gzip: 0.28 kB
public/build/assets/stylex.cdf3995e.css 2.84 kB │ gzip: 1.18 kB
public/build/assets/root-VHjyehqh.js 1.37 kB │ gzip: 0.81 kB
public/build/assets/jsx-runtime-NroC4D4D.js 8.09 kB │ gzip: 3.05 kB
public/build/assets/entry.client-Zz46Ypws.js 9.51 kB │ gzip: 3.73 kB
public/build/assets/_index-VynOg2Ww.js 11.95 kB │ gzip: 4.49 kB
public/build/assets/components-WD7OCPmZ.js 211.54 kB │ gzip: 68.46 kB
✓ built in 650ms
vite v5.0.6 building SSR bundle for production...
⚠️ Remix support for Vite is unstable
and not recommended for production
1:07:08 PM [vite] page reload virtual:stylex.css
1:07:08 PM [vite] page reload virtual:stylex.css (x2)
1:07:08 PM [vite] page reload virtual:stylex.css (x3)
✓ 14 modules transformed.
1:07:08 PM [vite] page reload virtual:stylex.css
1:07:08 PM [vite] page reload virtual:stylex.css (x2)
build/.vite/manifest.json 0.18 kB
build/assets/_virtual_server-entry-Whtg1KgZ.css 0.47 kB
build/assets/stylex.cdf3995e.css 2.84 kB
build/index.js 12.16 kB
✓ built in 171ms
I worked with a team member from Qwik.js and have a Vite plugin working with it. The code is a bit messy, but it all works. Probably worth trying to port over the same plugin and trying to make it work with Remix as well.
https://github.com/nmn/qwik-stylex
Important things to note:
-
vite.config.mjs
-
vite-stylex-plugin/index.mjs
-
root.tsx
containsimport "virtual:stylex.css";
which is required.
On my end, I'm going to try and it make it work with SvelteKit.
Any upates. I created a repo to record the progress of the vite plugin.
https://github.com/nonzzz/vite-plugin-stylex
CheckList
- [x] Add remix and qwik demo
- [ ] unit test case
- [ ] Make logic better
It's work well for those demo. But i can't balance some designs like should we need fileName option? AFAK. vite can already handle css internally. So we only set a virtual module for eacth entry is enough. And then in production mode we only update the renderChunk vite will collect all of styles and do the rest.
@nmn
I have a Vite plugin that's working with Qwik and Svelte on my end that doesn't rely on renderChunk etc. I worked on people from the Qwik team and got it to work. It worked in Svelte without many tweaks.
https://github.com/nmn/sveltekit-stylex
It shouldn't need a fileName
arg IMO.
@nmn, is there any time frame when we can expect an official adapter for Vite? Thx
@predaytor You're welcome to use the one from https://github.com/nmn/sveltekit-stylex if you want. Other than that, I don't have any timelines for you. When I feel confident in an implementation, we will add it to the repo. Don't let stop you from using it in the meantime.
Anyone interested in using StyleX in Vue3? I've tried @HorusGoul 's vite plugin and although it compiles without error, I couldn't get it to work. Are there gonna be official support for all major frameworks in the future?
@berkgulmus see https://github.com/facebook/stylex/discussions/154 . I have implemented a version and am currently preparing unit tests and e2e tests.
NUXT 3 + Vite usage example: https://stackblitz.com/edit/nuxt-3-vite-stylex Vue 3 + Vite usage example: https://stackblitz.com/edit/vue-3-vite-stylex
btw, as inspired by this finding: https://github.com/JakeSaterlay/stylex-playground/blob/main/vite.config.ts seems that using the @stylexjs/rollup-plugin as a vite plugin works just fine, even in ssr! (at least with NUXT3)
@HorusGoul's solution works for vite
@HorusGoul solution works, rollup-plugin however throws the Unexpected token on Vite
I haven't had time to look at the implementation of the Vite plugin by @HorusGoul but people have been generally happy with it.
Once we verify that it works in all the scenarios we care about, we can start recommending it officially. The community can do a better job at this than us trying to understand the idiosyncrasies of each bundler!
I tried @HorusGoul's vite-plugin-stylex
version and it didn't work for me in production, only development (missing styles, tried about a week ago). I've been using @nonzzz's vite-plugin-stylex-dev
since and it hasn't given me any problems. Sometimes the app appears before the styles are ready but if I reload it works. I haven't had any issues with it working in production.
I'm sure this comment won't be relevant long term but it's worth stating that if Stylex doesn't work with one plugin doesn't mean that it doesn't work in general. Like @nmn said, bundlers and dev servers are very idiosyncratic said so just try a few. I'm sure they'll all converge on working solutions anyway.
@zaydek I've experienced it too. I figured it's because it doesn't set the path correctly in the HTML. Check vite-plugin-stylex#28
@zaydek @movahhedi Did you try the using the plugin as written in the Qwik and Svelte examples I shared above?
- https://github.com/nmn/qwik-stylex
- https://github.com/nmn/sveltekit-stylex
I don't want to publish an official package until I can verify that this approach works in a wide range scenarios. Vite is so popular that it is used in many different ways. However, since the approach works in Qwik which has many of the same characteristics as RSCs I'm hopeful it can work in most cases.
I used vite-plugin-stylex
v0.4.1 with a React spa project with Vite and it worked successfully in dev and production.
However, since I updated StyleX to v0.4.1, I am getting the following error: Uncaught TypeError: stylex.inject is not a function
, not sure if this is related to the plugin or to something else with the new package. I have tried the same setup on a new project from scratch but it also failed. I also tried clearing Vite cache.
Trying to use the official @stylexjs/babel-plugin
and @stylexjs/rollup-plugin
without vite-plugin-stylex
did not work from the beginning.
@zaydek @movahhedi Did you try the using the plugin as written in the Qwik and Svelte examples I shared above?
- https://github.com/nmn/qwik-stylex
- https://github.com/nmn/sveltekit-stylex
I don't want to publish an official package until I can verify that this approach works in a wide range scenarios. Vite is so popular that it is used in many different ways. However, since the approach works in Qwik which has many of the same characteristics as RSCs I'm hopeful it can work in most cases.
@nmn Is your Vite plugin implementation published to NPM, even as a beta or alpha release? You can release the version namespaced with alpha or beta or canary if you like. I'd be happy to give feedback on that. I'm just using React (CSR style) but I am using Vite.
Alternatively do you have a React example I should install from GitHub instead?
used
vite-plugin-stylex
v0.4.1 with a React spa project with Vite and it worked successfully in dev and production.However, since I updated StyleX to v0.4.1, I am getting the following error:
Uncaught TypeError: stylex.inject is not a function
, not sure if this is related to the plugin or to something else with the new package. I have tried the same setup on a new project from scratch but it also failed. I also tried clearing Vite cache.Trying to use the official
@stylexjs/babel-plugin
and@stylexjs/rollup-plugin
withoutvite-plugin-stylex
did not work from the beginning.
I think maybe esm cause it.I am currently looking for a better way to balance between multiple frameworks
I will test esm after this weekend.
I will test esm after this weekend.
Just wanted to say thanks. Your plugin has been working nearly perfectly for me.
Is your Vite plugin implementation published to NPM, even as a beta or alpha release?
Not yet. I'm testing a few more frameworks before I do this.
Alternatively do you have a React example I should install from GitHub instead?
I don't have a React example, you should be able to copy the setup from the Qwik example to try it with a React app.
Is your Vite plugin implementation published to NPM, even as a beta or alpha release?
Not yet. I'm testing a few more frameworks before I do this.
Alternatively do you have a React example I should install from GitHub instead?
I don't have a React example, you should be able to copy the setup from the Qwik example to try it with a React app.
Yes, can try once I start a project tabula rasa that uses Stylex.