Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/michalczaplinski/hydration-mitosis-demo

An experiment to create Gutenberg blocks using Mitosis and compile them to both a Liquid template and a React component that hydrates the server-rendered HTML.
https://github.com/michalczaplinski/hydration-mitosis-demo

gutenberg gutenberg-blocks react

Last synced: 3 months ago
JSON representation

An experiment to create Gutenberg blocks using Mitosis and compile them to both a Liquid template and a React component that hydrates the server-rendered HTML.

Awesome Lists containing this project

README

        

## Hydration Mitosis Demo

This is an experiment that uses the
[Mitosis](https://github.com/BuilderIO/mitosis) compiler to create Gutenberg
blocks using the Mitosis syntax and compile them to both React for frontend
and a Liquid template to be rendered on the server in PHP.

This approach tackles both the problems of duplication of logic between the PHP
and JS parts of the block. It also addresses the issue of hydration of blocks
as the final JS that hydrates the block is generated by the compiler.

## Usage

1. Clone this project inside your `wp-content/plugins` directory or you can use `wp-env`.

2. `npm start`.

3. `npm run compile` - This will compile the `block.mitosis.js` component to both
React and a Liquid template and place them in `src/_generated/`. You'll have
to run this manually after every change to `block.mitosis.js`.

If you'd like to see the server rendered output, you can toggle the request blocking in
your browser's DevTools like:

Screen Shot 2021-12-08 at 13 31 16

## Where to go from here

Even though this repo was created with `@wordpress/create-block`, there is no
reason why we could not generate files on the fly in the same way as Blocky
does. This way, we could define our block with just a plain `block.json` file and a
`block.mitosis.js` file and the rest could be generated dynamically.

I think it would also be interesting to be able to provide custom "loaders" in PHP,
which could be a bit similar to
[`getServerSideProps()`](https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering)
in Next.js or [Loaders](https://remix.run/docs/en/v1/api/conventions#loader) in
Remix.

Of course, this would not provide any additional functionality but rather
simplify creation of blocks by requiring only the following files to create a block:

- `block.json`
- `block.js` - in the Mitosis format, or whaterver other format we might finally
settle on.
- `loader.php` - the file that defines a single "loader" function which has to
return props in a JSON format. Under the hood, this function is used on the
server side to pass the props to the generated template.

I could imagine that while for now those "loaders" would return JSON, they could
also in the future return [React Server
Components](https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html)!

## Q&A

### Could it work with frameworks other than React?

Yup, Mitosis could output code for Vue, Svelte, Solid and a couple other
frameworks.

### Ok, this is nice, but I'm concerned about javascript bloat. Like, when I create 5 blocks, I will generate 5 bundles and each one of them will include React?

Good point. Currently, each block does its own bundling which means that yes,
you would include React 5 times on your page. You could configure webpack to
output shared libraries to shared chunks **if** you are the author of each of
the block. However, if you'd like to just use third-party blocks where you don't
control the bundling, you're out of luck.

I think the real solution (which is beyond the scope here) would be to output
ESM and [import maps](https://github.com/WICG/import-maps) which has started
being discussed in https://github.com/WordPress/gutenberg/issues/36716.

## Limitations and weaknesses

- _The compiled output is far from perfect_. The generated react component does not
actually work out-of-the-box and needs a few search-and-replace regexes in order
to run fine (look in the `./compile.sh` file). Mitosis also does not generate the correct Liquid tags if
we pass a more complex expression to `` like e.g.
``.

- For some reason, Mitosis wants to by default handle state with `mobx-react`
and CSS with Emotion. I see no inherent reason for that, but I'm sure it
could be configured to output more vanilla components.

- _Mitosis syntax is meh_. The syntax is similar to React but it's not React and
it kinda shows. It's definitely a bit more tedious to define your components
this way and there are [some gotchas](https://github.com/BuilderIO/mitosis/blob/main/docs/overview.md#gotchas-and-limitations), too.

## Inspiration

- [Blocky](https://github.com/youknowriad/blocky)
- [Hybrid block demo](https://github.com/nerrad/hybrid-block-demo/)