I' m interested in the internal of NextJS. But it' s pretty difficult for me to read the source code of NextJS directly. So I decide to make a simple SSR server with react server API to learn NextJS progressively.
The logic is very simple, server side renders a react component and streams it to the client. On the client side, React hydrate the html from server. I can write a server easily with Express. The problem is that I have to write JSX on the both server and client side, so there comes how to compile. The solutions I found as following,
- swc + rollup
- rspack and rsbuild
- esbuild + rollup
In my practice, I have tried rspack and rsbuild.
├── README.md
├── package.json
├── pnpm-lock.yaml
├── public
│ ├── client.js # generated by rspack during build
│ └── client.js.map
├── rspack.config.mjs
└── src
├── app.client.jsx
├── app.jsx
├── client.jsx
├── server-comp.jsx
└── server.jsx
The logic is that server returns a html rendered by renderToPipeableStream, in which there is a script access from route '/client.js' inserted by renderToPipeableStream. In the client.js, hydrateRoot combines server html and client html, both of htmls read from app.jsx. Let's execute following commands, make the server run.
pnpm run build
pnpm run devI access http://localhost:3000, the html shows. It seems worked, but if I add <ServerComp /> with function of reading current dirs, the complied client.js includes nodejs api path and fs. It' s obvious, the new complied client.js will not work in browsers. So the question is how I can include the server part of code to the App.jsx and make it work both in client and server side.
TODO
I have used NextJS for some of projects. The functions of it are very great. And I feel very comfortable during development stage, because of the speed of hot compiling. However, I often found when I access some pages of my projects, it will load for a while. Ok, I could do some optimation in my code. I do want if the backend of NextJS is some other runtime or language, such as Rust. I found some one already tried this, Tuono