SSR and Client-only refreshes. Is it possible?

So, every file in client will not generate a server restart if modified. Similarly, every file in server will not make your browser refresh.

If I want to have Server Side Rendering, I can’t import from **/client/** because it says not found, ofcourse, it’s not necessary to load that in the module tree.

I think the question boils down to:
Can I import stuff from **/client/** in SSR, but simply avoid watching them ?

Something like having your cake and eating it too!

1 Like

I’ve been thinking about this lately too, after dusting off an old Blaze project. Things refresh so fast with Blaze, because you don’t have to wait for the server to recompile.

It’d be great if we could somehow reduce the need to recompile the server so much. I tried wrapping all my SSR imports with a !Meteor.isDevelopment but it didn’t have any impact. Meteor seems to just monitor everything in the import folder and recompile everything whenever anything changes. This makes sense since dynamic imports can be hiding places - either that or it is building a graph of everything (including dynamic imports) for the bundler, and watching what it finds (which would be just about everything).

Being able to disable or reduce server rebuilds would be a big win in perceived performance (especially on Windows…).

Things get fast with React as well, as long as you store them all inside a client folder. Did you manage to have SSR with Blaze and refreshes only happened on the client ?

Also if I think about it. With SSR, even if let’s say only client refreshes. Then on the next refresh it will hold in memory old code, creating a ton of confusion and hydrate() warnings.

I tried commenting out the SSR code, and I think it has a very small impact, but nothing substantial (on my Windows laptop 90% of the time is spend on “Building the application …” with my fans whining).

If you wanted to use the client folder, you wouldn’t be able to do SSR, because the server needs access to those files. Blaze doesn’t do SSR, afaik - and if it does, my particular application doesn’t have that.

What you could do is split your code. Put SSR code in imports and put components that don’t need to be rendered on the server (like authenticated routes) in client and use dynamic imports to block SSR (I think that can work) - that seems like it could be a headache though.

1 Like

I think I have found my solution (for now).

I’m using module alias, to specify the uiPath, so I can do things like:

import App.jsx from 'ui/App.jsx';

Now, if I point ui to a folder that is inside a client can’t be read on the server. SSR dies. However! I can easily plug-in SSR and out. And for example before releasing my app, I can just make these changes:

  1. Enable SSR
  2. Rename client folder to something else
  3. Modify .babelrc to make it point correctly.

I can hack a bash script that does this no problem. But with SSR I found out that there may be a lot of hidden issues that you don’t expect. (Like this for eg: https://github.com/vazco/uniforms/issues/462)

So I don’t know what to think. But I’m happy with this solution for now.

I did this too. Also would love for a way for this to happen.

But why do you put something in client folder then want to import it from server? Why not just put them in a directory like imports?

@minhna even if you put it in imports/client you can’t import it from server. This is not a very known thing about Meteor!

I know, I don’t put it in any level with client directory name.

The reason for this was because I don’t want full server reloads when changing a React component.

That explains the reason you did that. But I think (personally) it is not worth it. You must change your components very often then.

The build times are an order of magnitude faster if components are in client instead of imports - it’s faster enough to warrant the change IMHO - especially on slow as molasses Windows!

2 Likes

That seems workable! For working out SSR issues (yes there are issues - it’s very much a port to make a React app work with SSR), you could rename your client folder to whatever while working on SSR issues, and still run locally - you’ll just have to deal with slow rebuild times during SSR work - this seems a fine tradeoff.

I wonder whether there is a way to use symlinks (and/or whatever Windows has) for this, to avoid messing with git.

BTW, could you describe how you set up module aliases? I’ve been interested in that, but haven’t spent the time to figure it out yet.