This demo illustrates advanced Webpack features and techniques:
- Configuration merging
- Server app bundling (for server side rendering)
- Hot Module Reloading
Checkout the start branch
and npm install
all dependencies.
Explain that:
- The app is the same as Demo 1, but comes with a server written in Express.
- It compiles the server and serves the client bundle via
webpack-dev-middleware
. Explain the needed changes in the webpack configuration to make this work: mainlyprocess.env.APP_ROOT_DIR
.
- Update Webpack config with the commented code (at the bottom).
entry: [
'webpack-hot-middleware/client?dynamicPublicPath=true',
'react-hot-loader/patch',
join(sourcePath, 'index.tsx'),
],
// In loaders
{ test: /\.tsx?$/, loaders: ['react-hot-loader/webpack', `awesome-typescript-loader?tsconfig=${join(sourcePath, 'tsconfig.json')}`] },
// In plugins
new webpack.HotModuleReplacementPlugin()
- Update
App.tsx
to accept the change:
- Use
AppContainer
to wrap the root component:
const { AppContainer } = require('react-hot-loader');
...
ReactDOM.render(
<AppContainer>
<Root />
</AppContainer>,
document.getElementById('root')
);
Explain what AppContainer
does and why it is needed.
- Re-render the app on hot change:
if (process.env.NODE_ENV !== 'production' && module.hot) {
module.hot.accept('./App', () => {
const NewApp = require('./App').default;
renderApp(NewApp);
});
}
Explain that the App has a default
export and that's the reason we need to require it like this.
- Change the
home.tsx
to render theApp
component. Mention that the file has an.tsx
extension.
import * as React from 'react';
import { renderToString } from 'react-dom/server';
//...
export const home: RequestHandler = (req, res, next) => {
const app = renderToString(
<App />
);
res.send(renderIndex(app));
};
// Uncomment the renderIndex function:
const indexTemplate = template(readFileSync(join(__dirname, 'index.html')).toString(), {
interpolate: /{{([\s\S]+?)}}/g,
});
const renderIndex = (app: string) => (
indexTemplate({
app,
})
);
Run the app show that it does not compile because the client is bundled with Webpack and the server is not.
- Extract a common Webpack config that should be used for server and client bundling. Explain the server Webpack configuration and its differences with the client one: mainly:
target: 'node'
andexternals
.
Change npm start
script to use webpack for bundling. Run the app and show that it does not compile due to CSS imports.
-
Use the ExtractTextPlugin to extract the CSS into separate file. Run the app again and show that it does not work. Explain that it is never easy with Webpack 😜
-
Change the
process.env.APP_ROOT_DIR
to one level up. Run the app and show that everything works now 🎉