ssr with react and express and requiring stats.json explanation
This is likely to be a file generated by a webpack plugin (https://github.com/danethurber/webpack-manifest-plugin) after building the client-side bundle, that file name is hashed and necessary to the server so it knows how to render the base template which will then bootstrap the client.
Of course that's a guess since we don't have access to your json
file, webpack
configuration or package.json
..
This repository uses a similar approach: https://github.com/CheesecakeLabs/react-redux-boilerplate/It builds the client, generates the same kind of file and then builds the server bundle using that JSON file as information point to understand how the client bundle is named.
The JSON file should be similar to this:
{ "apple-touch-icon.png": "114dec1694406188ff0cb2698607cbca.png", "production.css": "production.fbee6dc76218b122f7ff.css", "production.css.map": "production.fbee6dc76218b122f7ff.css.map", "production.js": "production.fbee6dc76218b122f7ff.js", "production.js.map": "production.fbee6dc76218b122f7ff.js.map", "safari-pinned-tab.svg": "f157afc1cf258044878dab6647d2800b.svg"}
The stats.json
file is generated by the webpack-stats-plugin
and can be use by the Node process to "identify the correct bundle path in your server": https://github.com/FormidableLabs/webpack-stats-plugin
The project you are looking at is below
https://github.com/rherwig/template-react-16-ssr/blob/master/src/index.js
If you look at the client.production.js
file on below
The code uses
plugins: [ new ExtractCssChunks(), new webpack.optimize.CommonsChunkPlugin({ names: ['bootstrap'], filename: '[name].js', minChunks: Infinity }), new StatsWebpackPlugin('stats.json'), new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production') } })]
As you can see it uses StatsWebpackPlugin
to save the stats in stats.json
. Now let's look at the usage
const serverRender = require('./assets/app.server.js').default;app.use(serverRender({ clientStats, outputPath }));
So it is passing the clientStats
and outputPath
to the serverRender
, which the default export of the assets/app.server.js
. Now if you look at file
https://github.com/rherwig/template-react-16-ssr/blob/master/src/server/index.js
export default ({ clientStats }) => async (req, res) => { const app = ( <App/> ); const appString = ReactDOM.renderToString(app); const chunkNames = flushChunkNames(); const { js, styles, cssHash } = flushChunks(clientStats, { chunkNames }); .... };
It passes the clientStats
to flushChunks
which is from webpack-flush-chunks
. Which is to get the css
, js
include scripts for the generated files. This is then used to render the template
res.render('index', { appString, js, styles, cssHash });
If you look at the index.ejs
template
<html><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <%- styles %> <title>React 16 | Sample</title></head><body><div id="react-root"><%- appString %></div><%- cssHash %><%- js %></body></html>
It uses the CSS, JS links on the rendered page. All this was needed because we need information of chunks which generated because of the plugins ExtractCssChunks
and webpack.optimize.CommonsChunkPlugin