Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for server-side rendering #118

Merged
merged 8 commits into from Sep 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 19 additions & 1 deletion README.md
Expand Up @@ -41,7 +41,7 @@ app.use(webpackMiddleware(webpack({
// but it will work with other paths too.
}
}), {
// publicPath is required, whereas all other options are optional
// publicPath is required, whereas all other options are optional

noInfo: false,
// display no info to console (only warnings and errors)
Expand Down Expand Up @@ -70,6 +70,9 @@ app.use(webpackMiddleware(webpack({
colors: true
}
// options for formating the statistics

serverSideRender: false,
// Turn off the server-side rendering mode. See Server-Side Rendering part for more info.
}));
```

Expand Down Expand Up @@ -109,3 +112,18 @@ This part shows how you might interact with the middleware during runtime:
console.log('Package is in a valid state');
});
```

## Server-Side Rendering
In order to develop a server-side rendering application, we need access to the [`stats`](https://github.com/webpack/docs/wiki/node.js-api#stats), which is generated with the latest build.

In the server-side rendering mode, __webpack-dev-middleware__ sets the `stat` to `res.locals.webpackStats`, then call `next()` to trigger the next middleware, where we can render pages and response to clients. During the webpack building process, all requests will be pending until the build is finished and the `stat` is available.

```JavaScript
app.use(webpackMiddleware(compiler, { serverSideRender: true })

// The following middleware would not be invoked until the latest build is finished.
app.use((req, res) => {
const assetsByChunkName = res.locals.webpackStats.toJson().assetsByChunkName
// then use `assetsByChunkName` for server-sider rendering
})
```
18 changes: 15 additions & 3 deletions middleware.js
Expand Up @@ -58,6 +58,8 @@ module.exports = function(compiler, options) {
compiler.plugin("done", function(stats) {
// We are now on valid state
state = true;
webpackStats = stats

// Do the stuff in nextTick, because bundle may be invalidated
// if a change happened while compiling
process.nextTick(function() {
Expand Down Expand Up @@ -108,6 +110,8 @@ module.exports = function(compiler, options) {
// the state, false: bundle invalid, true: bundle valid
var state = false;

var webpackStats;

// in lazy mode, rebuild automatically
var forceRebuild = false;

Expand Down Expand Up @@ -194,12 +198,20 @@ module.exports = function(compiler, options) {

// The middleware function
function webpackDevMiddleware(req, res, next) {
function goNext() {
if(!options.serverSideRender) return next()
ready(function() {
res.locals.webpackStats = webpackStats
next()
}, req)
}

if(req.method !== 'GET') {
return next();
return goNext();
}

var filename = getFilenameFromUrl(req.url);
if(filename === false) return next();
if(filename === false) return goNext();

// in lazy mode, rebuild on bundle request
if(options.lazy && (!options.filename || options.filename.test(filename)))
Expand Down Expand Up @@ -229,7 +241,7 @@ module.exports = function(compiler, options) {
}
}
} catch(e) {
return next();
return goNext();
}

// server content
Expand Down