fix(v2): map loaded modules to bundles (#1056)

* fix(v2): map loaded modules to bundles

* nits
This commit is contained in:
Endilie Yacop Sucipto 2018-10-23 15:53:18 +08:00 committed by Yangshun Tay
parent 2ce6ca5854
commit 5d60739f7c
3 changed files with 37 additions and 16 deletions

View file

@ -2,20 +2,26 @@ import React from 'react';
import {StaticRouter} from 'react-router-dom';
import ReactDOMServer from 'react-dom/server';
import Helmet from 'react-helmet';
import {getBundles} from 'react-loadable/webpack';
import Loadable from 'react-loadable';
import App from './App';
import preload from './preload';
import routes from '@generated/routes'; // eslint-disable-line
import reactLoadableStats from '@build/react-loadable.json'; //eslint-disable-line
import webpackClientStats from '@build/client.stats.json'; //eslint-disable-line
import routes from '@generated/routes'; // eslint-disable-line
import preload from './preload';
import App from './App';
// Renderer for static-site-generator-webpack-plugin (async rendering via promises)
export default function render(locals) {
return preload(routes, locals.path).then(() => {
const modules = [];
const context = {};
const appHtml = ReactDOMServer.renderToString(
<StaticRouter location={locals.path} context={context}>
<App />
</StaticRouter>,
<Loadable.Capture report={moduleName => modules.push(moduleName)}>
<StaticRouter location={locals.path} context={context}>
<App />
</StaticRouter>
</Loadable.Capture>,
);
const helmet = Helmet.renderStatic();
@ -28,7 +34,11 @@ export default function render(locals) {
];
const metaHtml = metaStrings.filter(Boolean).join('\n ');
const assets = webpackClientStats.assetsByChunkName.main;
const bundles = getBundles(reactLoadableStats, modules);
const assets = [
...webpackClientStats.assetsByChunkName.main,
...bundles.map(b => b.file),
];
const jsFiles = assets.filter(value => value.match(/\.js$/));
const cssFiles = assets.filter(value => value.match(/\.css$/));
const {baseUrl} = locals;
@ -40,17 +50,21 @@ export default function render(locals) {
${metaHtml}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
${cssFiles.map(
cssFile =>
`<link rel="stylesheet" type="text/css" href="${baseUrl}${cssFile}" />`,
)}
${cssFiles
.map(
cssFile =>
`<link rel="stylesheet" type="text/css" href="${baseUrl}${cssFile}" />`,
)
.join('\n')}
</head>
<body${bodyAttributes ? ` ${bodyAttributes}` : ''}>
<div id="app">${appHtml}</div>
${jsFiles.map(
jsFile =>
`<script type="text/javascript" src="${baseUrl}${jsFile}"></script>`,
)}
${jsFiles
.map(
jsFile =>
`<script type="text/javascript" src="${baseUrl}${jsFile}"></script>`,
)
.join('\n')}
</body>
</html>
`;

View file

@ -60,6 +60,7 @@ module.exports = function createBaseConfig(props, isServer) {
presets: ['@babel/env', '@babel/react'],
plugins: [
isServer ? 'dynamic-import-node' : '@babel/syntax-dynamic-import',
'react-loadable/babel',
],
});
}

View file

@ -1,6 +1,7 @@
const path = require('path');
const webpackNiceLog = require('webpack-nicelog');
const {StatsWriterPlugin} = require('webpack-stats-plugin');
const {ReactLoadablePlugin} = require('react-loadable/webpack');
const cleanWebpackPlugin = require('clean-webpack-plugin');
const createBaseConfig = require('./base');
const {applyChainWebpack} = require('./utils');
@ -17,8 +18,13 @@ module.exports = function createClientConfig(props) {
// write webpack stats object so we can pickup correct client bundle path in server.
config
.plugin('stats')
.plugin('client-stats')
.use(StatsWriterPlugin, [{filename: 'client.stats.json'}]);
config
.plugin('react-loadable-stats')
.use(ReactLoadablePlugin, [
{filename: path.join(outDir, 'react-loadable.json')},
]);
// show compilation progress bar and build time
const isProd = process.env.NODE_ENV === 'production';