Skip to content

Commit 90af0d8

Browse files
wuctSpaceK33z
authored andcommitted
Support for server-side rendering (#118)
If `options.serverSideRender` is true, the middleware will set the `stat` object, which is generated by webpack, to `res`, and all requests will wait for building.
1 parent 9f82b70 commit 90af0d8

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ app.use(webpackMiddleware(webpack({
4141
// but it will work with other paths too.
4242
}
4343
}), {
44-
// publicPath is required, whereas all other options are optional
44+
// publicPath is required, whereas all other options are optional
4545

4646
noInfo: false,
4747
// display no info to console (only warnings and errors)
@@ -70,6 +70,9 @@ app.use(webpackMiddleware(webpack({
7070
colors: true
7171
}
7272
// options for formating the statistics
73+
74+
serverSideRender: false,
75+
// Turn off the server-side rendering mode. See Server-Side Rendering part for more info.
7376
}));
7477
```
7578

@@ -109,3 +112,18 @@ This part shows how you might interact with the middleware during runtime:
109112
console.log('Package is in a valid state');
110113
});
111114
```
115+
116+
## Server-Side Rendering
117+
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.
118+
119+
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.
120+
121+
```JavaScript
122+
app.use(webpackMiddleware(compiler, { serverSideRender: true })
123+
124+
// The following middleware would not be invoked until the latest build is finished.
125+
app.use((req, res) => {
126+
const assetsByChunkName = res.locals.webpackStats.toJson().assetsByChunkName
127+
// then use `assetsByChunkName` for server-sider rendering
128+
})
129+
```

middleware.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ module.exports = function(compiler, options) {
5858
compiler.plugin("done", function(stats) {
5959
// We are now on valid state
6060
state = true;
61+
webpackStats = stats
62+
6163
// Do the stuff in nextTick, because bundle may be invalidated
6264
// if a change happened while compiling
6365
process.nextTick(function() {
@@ -108,6 +110,8 @@ module.exports = function(compiler, options) {
108110
// the state, false: bundle invalid, true: bundle valid
109111
var state = false;
110112

113+
var webpackStats;
114+
111115
// in lazy mode, rebuild automatically
112116
var forceRebuild = false;
113117

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

195199
// The middleware function
196200
function webpackDevMiddleware(req, res, next) {
201+
function goNext() {
202+
if(!options.serverSideRender) return next()
203+
ready(function() {
204+
res.locals.webpackStats = webpackStats
205+
next()
206+
}, req)
207+
}
208+
197209
if(req.method !== 'GET') {
198-
return next();
210+
return goNext();
199211
}
200212

201213
var filename = getFilenameFromUrl(req.url);
202-
if(filename === false) return next();
214+
if(filename === false) return goNext();
203215

204216
// in lazy mode, rebuild on bundle request
205217
if(options.lazy && (!options.filename || options.filename.test(filename)))
@@ -229,7 +241,7 @@ module.exports = function(compiler, options) {
229241
}
230242
}
231243
} catch(e) {
232-
return next();
244+
return goNext();
233245
}
234246

235247
// server content

0 commit comments

Comments
 (0)