Since we aim to have a lot more UI, it would be a great step forwards if we could use a frontend framework. For that reason, I have implemented a React pipeline.
Complete details can be found in the TDD, but in short: We create a base page on the server and attach a root component. The server renders the page (creates the HTML markup) and sends it to the client. The client can then hydrate the components to re-attach the interactivity to the components.
It also requires some new steps in the project setup:
Server code is now also built and bundled. To run the server, first run yarn build:server and then yarn start.
For a possible easier workflow, I added a launch.example.json for vscode. Change the filename (or make a copy) to `launch.json. This will allow you to run the debugger in vscode for the server. Simply hit F5 and it will build & run the server.
I'll add this to the wiki when the PR is merged.
I had to go for some suboptimal solutions here and there though:
We still have to manually add an entry point to the webpack.client.config.js (would be nice if this was taken care of on a per-route basis).
For each route, we need to manually hydrate the server-side rendered React components. I looked for a solution that does this for every page, but I couldn't find a good way to have a common client script that points to the corresponding RootComponent for every route.
The server renders HTML during runtime. It's a minor performance impact that could be solved by saving the rendered HTML to disk (minify while we're at it) and serving that as a static page. Downside would be that it complicates any dynamic content, such as having a user logged in and displaying it on the page.
NOTE: It also rendered the HTML during runtime before this PR, so compared to that there's no performance hit.
Additional findings
Whilst further experimenting and researching this topic, I stumbled upon the problem of passing server side data to the client. With SSR, we render the HTML on the server, which has to be hydrated on the client side to attach the correct interactivity (such as event listeners). This unfortunately also requires the data that was used to render it on the server. That means we'll have to somehow also pass along the raw data from the server to the client, which is rather wasteful since the data had already been rendered. A good example can be found here: https://developers.google.com/web/updates/2019/02/rendering-on-the-web#rehydration-issues
Since we aim to have a lot more UI, it would be a great step forwards if we could use a frontend framework. For that reason, I have implemented a React pipeline. Complete details can be found in the TDD, but in short: We create a base page on the server and attach a root component. The server renders the page (creates the HTML markup) and sends it to the client. The client can then hydrate the components to re-attach the interactivity to the components.
It also requires some new steps in the project setup:
yarn build:server
and thenyarn start
.launch.example.json
for vscode. Change the filename (or make a copy) to `launch.json. This will allow you to run the debugger in vscode for the server. Simply hit F5 and it will build & run the server. I'll add this to the wiki when the PR is merged.I had to go for some suboptimal solutions here and there though:
webpack.client.config.js
(would be nice if this was taken care of on a per-route basis).Additional findings Whilst further experimenting and researching this topic, I stumbled upon the problem of passing server side data to the client. With SSR, we render the HTML on the server, which has to be hydrated on the client side to attach the correct interactivity (such as event listeners). This unfortunately also requires the data that was used to render it on the server. That means we'll have to somehow also pass along the raw data from the server to the client, which is rather wasteful since the data had already been rendered. A good example can be found here: https://developers.google.com/web/updates/2019/02/rendering-on-the-web#rehydration-issues
Related issues Makes the following issues easier:
199
197 maybe
185
158
155
148
91
90
89
88