redfin / react-server

:rocket: Blazing fast page load and seamless navigation.
https://react-server.io/
Apache License 2.0
3.89k stars 184 forks source link

CLI still runs webpack build with `--js-url=...` #774

Open gigabo opened 7 years ago

gigabo commented 7 years ago

Looks like it's just building up the manifest.json? Need to bypass this for production.

gigabo commented 7 years ago

Thanks for tracking down the cause here @auskast. Are you interested in taking this on?

aickin commented 7 years ago

How would you bypass it? Pass in a manifest at the command line?

One other thing to note: I intended but never implemented a safety check here, where the hash in the manifest could be compared between the server and the static JS to make sure they were the same version. If you bypass the build on the server side, you'll never be able to do that check. But maybe that doesn't matter?

gigabo commented 7 years ago

Oh, right... good question @aickin. Maybe pass in a path to a build output directory?

That would also help us find pre-babelified server code.

It could probably default to a known relative path so that it would generally be unnecessary. :thinking:

aickin commented 7 years ago

Just so we are all on the same page: manifest.json is required on the server-side because it contains the names of the chunks with their content hashes. Without manifest.json, all the JS and CSS URLs will be wrong.

When I wrote this, I thought that there were three reasonable ways to get the manifest info on the server-side on startup:

  1. Rebuild the static files and generate manifest.json, throwing away the client build. (This is the currently implemented strategy.)
  2. Pass in a manifest.json file path (which was presumably previously generated during an earlier client build step) at the command line.
  3. Include manifest.json in the client output, and then download http(s)://{jsUrl}/manifest.json when the server is started up.

The benefit of option 1 is that you can in theory do an integrity check to make sure that the server codebase and client codebase are in fact identical. If you don't care about that, I'd personally prefer option 3. I do, however, have moderate worries that the requirement that the HTML server can reach the jsUrl server might trip up folks in some configurations. Thoughts?

gigabo commented 7 years ago

Oh, option 3 is interesting. Hadn't thought of that.

I think my suggestion above is a variant of option 2. The only difference is rather than passing in the file path to manifest.json, my thought was we could pass in the directory that contains it. That directory could then also contain other build artifacts that might be useful to make available at run time (such as pre-transformed babel output) without requiring additional CLI flags.

Then, as an extension: if react-server compile puts the output directory into a default location and react-server run looks for it that same location then ideally the option wouldn't even be necessary in the default case.

manifest.json is required on the server-side because it contains the names of the chunks with their content hashes. Without manifest.json, all the JS and CSS URLs will be wrong.

Thanks for the context!

pr1ntr commented 7 years ago

My current solution to this problem is I have to compile on one (or Travis) server and then SCP it to the others and restart all those servers. Not ideal for all deployments IMO.

How about this. Can we base the HASH on an MD5 Checksum of the files that are generated? That way as long as the source doesn't change you will always get the same hash, thus you can compile it as many times as you want without conflicting manifests.