rakkasjs / rakkasjs

Bleeding-edge React framework powered by Vite
https://rakkasjs.org
MIT License
1.07k stars 29 forks source link

use preact instead of react #45

Open sharmapukar217 opened 2 years ago

sharmapukar217 commented 2 years ago

is there any way to use preact rather than react. Currently preact/compat doesn't seems to work

cyco130 commented 2 years ago

Hi!

I definitely hope to support Preact at some point but to my knowledge preact/compat doesn't support streaming SSR with Suspense that Rakkas relies on. So the integration will not be as straightforward.

I'll keep the issue open but it's low priority until the core functionality becomes more stable.

patdx commented 2 years ago

I was curious so I made an attempt to set up preact here: https://github.com/patdx/rakkasjs/pull/1/files

It seems to be working including prerendering however some features like client-side routing seem to crash, and no hot reloading feature.

https://github.com/patdx/rakkasjs/pull/1/files

When I tried building the kitchen sink app, here is the size with React:

rakkas: Bundling for cloudflare-workers (4/4)

  dist/server/cloudflare-workers-bundle.js  214.9kb

⚡ Done in 34ms
(Note: doing a dry run, not uploading or deleting anything.)
Total Upload: 282.95 KiB / gzip: 73.51 KiB
--dry-run: exiting now.

Here is the size with Preact:

rakkas: Bundling for cloudflare-workers (4/4)

  dist/server/cloudflare-workers-bundle.js  167.3kb

⚡ Done in 47ms
Retrieving cached values for userId from node_modules/.cache/wrangler
(Note: doing a dry run, not uploading or deleting anything.)
Total Upload: 213.23 KiB / gzip: 58.07 KiB
--dry-run: exiting now.

The gzipped difference is smaller than I expected.

From a distribution/testing perspective, it is also complicated by the fact that preact needs react and react-dom to be aliased to preact/compat. For the browser part you can use the Vite alias feature. For SSR build with external dependencies, you would need to use pnpm.overrides or use some Node-compatible tool like module-alias to override the react imports. That is what next-plugin-preact uses but I am worried it may only work for require() not import.

cyco130 commented 2 years ago

I have my own experiment going on here: https://stackblitz.com/github/rakkasjs/rakkasjs/tree/release/preact/examples/preact It uses preact/compat and preact-ssr-prepass to make suspense possible in SSR (without streaming support).

Client-side navigation doesn't work at all in dev. That's probably fixable but, in production, although it works, you will see a flash of a blank page before the new page is rendered. That's not fixable: Preact doesn't support concurrent mode yet so it's incompatible Rakkas's data fetching system. But it's still somewhat usable as long as you don't use Link and navigate. Or you can wrap layout children in <Suspense> and you will have a somewhat acceptable user experience; the layout will stay still but the content will show a brief loading state. Lots of SPAs still work that way so it's not" unreasonable.

My Cloudflare Workers bundle size difference is 41K uncompressed and slightly below 11K with gzip -9.