Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instrument Hot Module Replacement #38

Open
chichiwang opened this issue Mar 20, 2024 · 5 comments
Open

Instrument Hot Module Replacement #38

chichiwang opened this issue Mar 20, 2024 · 5 comments
Assignees
Labels
enhancement New feature or request on hold Task is on hold

Comments

@chichiwang
Copy link
Owner

Implement HMR to preserve state while working on the React application in the development workflow without a hard refresh to the page.

Investigate if this is feasible given the server-side-rendering setup, and if so instrument the workflow.

Acceptance Criteria:

  • HMR is instrumented into the watch process
    • Changes to Application modules will not refresh the entire page, but the application will reflect the changes
@chichiwang
Copy link
Owner Author

After some cursory research, it appears HMR may not be worth implementing into this project:

  • The universal JS code may need HMR-specific logic
  • The server code needs HMR-specific logic

The server HMR-specific logic will need to have build awareness (production code vs non-production code) which is a little bit bothersome - this is necessary to gate the webpack middleware being loaded into the server in the first place. But the application logic needing HMR logic is more offensive to me, as app files should be application-focused and not configuration/tool-chain/development-tooling aware in any way.

It may still be worth a prototype branch to see what it actually takes to instrument HMR, but application awareness of HMR would be a dealbreaker, and server-awareness of HMR would be a little bit icky to me.

@chichiwang
Copy link
Owner Author

After a good amount of research: setting up HMR is not trivial when combined with SSR and an Express server. However, it is very possible. Using react-ssr-setup by Manuel Bieh as reference, one strategy is to use a third express server as the webpack watch server to run the middleware necessary for HMR.

It is now my opinion that HMR should be revisited after tackling the full configuration differentiating between dev and production builds (Issue #45). Moving this issue back into TODO for the time being.

@chichiwang chichiwang moved this from In Progress to Todo in React TS SSR boilerplate Mar 28, 2024
@chichiwang chichiwang moved this from Todo to In Progress in React TS SSR boilerplate Apr 3, 2024
@chichiwang
Copy link
Owner Author

I built a prototype, studying the react-ssr-setup repository, using an Express server as a watch server, and using nodemon as a module to rebuild/restart the web server, and I failed to get it to work.

The watcher would rebuild assets correctly, but the webserver failed to pick up changes to /pages/Home/index.tsx resulting in hydration mismatch errors from React.

While I could spend time debugging these issues to see where they are coming from, this will take an indeterminate amount of time. The prototype did teach me a bit about how webpack-dev-middleware and webpack-hot-middleware work.

Before abandoning this for now (as I know it is possible to instrument), I am going to attempt a second prototype by studying the pipeable-stream branch of ssr-boilerplate by Karl Aleksandrov. I am more optimistic about Karl's approach:

  • His branch was updated recently
    • Manuel Bieh's repository has not had commits for a couple of years now
  • He uses React 18's renderToPipeableStream method on the server as we do
  • His approach bypasses a custom watch server to make the server environment aware and loads HMR as an Express middlware method
    • While I do not love making the webserver environment aware, this does reduce the number of moving pieces

@chichiwang
Copy link
Owner Author

After days of research it is apparent that implementing HMR is non-trivial. Deferring this task to later in the boilerplate setup.

@chichiwang chichiwang moved this from In Progress to Todo in React TS SSR boilerplate Apr 9, 2024
@chichiwang
Copy link
Owner Author

After more in-depth research HMR functionality in this boilerplate is being tabled. The trouble is the complexity of instrumenting HMR in an SSR setup, and the fact that a lot of instrumentation requires the code to contain module replacement logic. We have not yet made the code itself even environment-aware (although that is coming), nor is it even fed environment-specific/configuration variables/values (also being thought about).

It seems that the additional complexities of the SSR implementation using React 18's streaming server-side render is going to add additional hurdles for the implementation of HMR. The strategy of using a <Link /> tag to load generated stylesheets in development may also need to be replaced with webpack-style-loader in development (currently only used in the server configurations). This means the application itself will need to become environment-aware, rather than the Webpack configurations.

It would no doubt be a nice quality-of-life feature to have for application development, but at the moment it will add a large amount of complexity to the setup of the current boilerplate, which is aiming for a degree of simplicity (insofar as possible given the technologies instrumented).

Perhaps HMR will be something desired in the future, but for now we are going to forego the feature.

Resources:

@chichiwang chichiwang moved this from Todo to Tabled in React TS SSR boilerplate Apr 18, 2024
@chichiwang chichiwang added the on hold Task is on hold label Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request on hold Task is on hold
Projects
None yet
Development

No branches or pull requests

1 participant