What am I missing for HMR, here?

I have an old project where I was able to set up HMR with SSR. However, I went to make some changes to it today, and noticed that HMR wasn't working. After a few hours of trying to fix it, I thought I'd try starting fresh: https://stackblitz.com/edit/stackblitz-starters-pjadua, and from what I can see, it should work, however, despite vite recognizing file updates and logging that it has performed an HMR update, and the browser console indicating that it received and performed that HMR update, there is no hot replacement of modules. Am I just missing something?
5 Replies
deluksic
deluksic4mo ago
Make sure you dont have any import cycles. Vite simply gives up on those and they can easily happen as it is a supported feature of javascript module system. Though if this is the case, you can run vite in debug mode to see where the cycle is
GodBleak
GodBleak4mo ago
Yeah, I don't think I have any cyclical imports. I did just try to remove all imports that aren't strictly necessary, and I get the same behaviour
GodBleak
GodBleak4mo ago
Looks like I got it figured it out: https://stackblitz.com/edit/stackblitz-starters-i1dhxl
GodBleak
StackBlitz
node.new Starter (forked) - StackBlitz
Starter project for Node.js, a JavaScript runtime built on Chrome's V8 JavaScript engine
deluksic
deluksic4mo ago
What was the problem?
GodBleak
GodBleak2mo ago
Sorry, I must've missed the notification for this. It seems it was a hydration issue (or rather, a lack of understanding, on my part, when it comes to hydration). Initially I had a component that had the head, and the body tags which had the noscript tag and the children -- which would be the app itself. I'd use it like this:
export const App: Component = () => {
return (
<Document>
/* app content */
</Document>
);
};
export const App: Component = () => {
return (
<Document>
/* app content */
</Document>
);
};
However, when making changes to the app content, HMR would break, likely because it was updating the entire document; due to them being in the same module. I started to clue into this, so I moved the most of everything that was in the Document component to just be static HTML streamed by the server, and just have Solid render App:
const { render } = await vite.ssrLoadModule('src/web/render.tsx');
res.status(200);
res.write(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
<title>Solid App</title>
</head>
<body>
`);
res.write(await render());
res.end(`</body>
</html>`);
const { render } = await vite.ssrLoadModule('src/web/render.tsx');
res.status(200);
res.write(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
<title>Solid App</title>
</head>
<body>
`);
res.write(await render());
res.end(`</body>
</html>`);
However, unbeknownst to me, this caused an entirely different problem; this likely broke hydration. However, thinking it was the same issue, that's when I created this thread. So the solution was to get rid of that static html, and go back to the original Document component, but instead of wrapping the app content with it, wrap the App component with with it, in a different module. So I did that in the renderToStream and hydrate functions, as they're each in their own module:
export const render = () =>
renderToStream(() => (
<Document>
<App />
</Document>
));
export const render = () =>
renderToStream(() => (
<Document>
<App />
</Document>
));
Want results from more Discord servers?
Add your server
More Posts