diff --git a/examples/node-api-middleware/server.js b/examples/node-api-middleware/server.js index 5b9253e886..eaa59584a2 100644 --- a/examples/node-api-middleware/server.js +++ b/examples/node-api-middleware/server.js @@ -9,7 +9,7 @@ const server = new WebpackDevServer(compiler, { stats: { colors: true }, - setup(app) { + before(app) { app.use((req, res, next) => { console.log(`Using middleware for ${req.url}`); next(); diff --git a/lib/Server.js b/lib/Server.js index 1a31eca021..ac3cd74b37 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -321,11 +321,19 @@ function Server(compiler, options) { } }, + before: () => { + if (typeof options.before === 'function') { options.before(app, this); } + }, + middleware: () => { // include our middleware to ensure it is able to handle '/index.html' request after redirect app.use(this.middleware); }, + after: () => { + if (typeof options.after === 'function') { options.after(app, this); } + }, + headers: () => { app.all('*', this.setContentHeaders.bind(this)); }, @@ -335,16 +343,18 @@ function Server(compiler, options) { }, setup: () => { + log('Using "setup" is deprecated and will be removed in the next major version. Please use the "before" and "after" hooks instead.'); + log('If "setup" was working fine for you until now, simply replace it with "before"'); if (typeof options.setup === 'function') { options.setup(app, this); } } }; - const defaultFeatures = ['setup', 'headers', 'middleware']; - if (options.proxy) { defaultFeatures.push('proxy', 'middleware'); } + const defaultFeatures = ['before', 'setup', 'headers', 'middleware', 'after']; + if (options.proxy) { defaultFeatures.push('proxy', 'middleware', 'after'); } if (contentBase !== false) { defaultFeatures.push('contentBaseFiles'); } if (options.watchContentBase) { defaultFeatures.push('watchContentBase'); } if (options.historyApiFallback) { - defaultFeatures.push('historyApiFallback', 'middleware'); + defaultFeatures.push('historyApiFallback', 'middleware', 'after'); if (contentBase !== false) { defaultFeatures.push('contentBaseFiles'); } } defaultFeatures.push('magicHtml'); diff --git a/lib/optionsSchema.json b/lib/optionsSchema.json index 8f9f7706b3..1c8e8765e6 100644 --- a/lib/optionsSchema.json +++ b/lib/optionsSchema.json @@ -274,6 +274,14 @@ "description": "Exposes the Express server to add custom middleware or routes.", "instanceof": "Function" }, + "before": { + "description": "Exposes the Express server to add custom middleware or routes before webpack-dev-middleware will be added.", + "instanceof": "Function" + }, + "after": { + "description": "Exposes the Express server to add custom middleware or routes after webpack-dev-middleware got added.", + "instanceof": "Function" + }, "stats": { "description": "Decides what bundle information is displayed.", "anyOf": [ diff --git a/test/Validation.test.js b/test/Validation.test.js index a04e329111..c4f6933c52 100644 --- a/test/Validation.test.js +++ b/test/Validation.test.js @@ -51,7 +51,7 @@ describe('Validation', () => { ' object { hot?, hotOnly?, lazy?, bonjour?, host?, allowedHosts?, filename?, publicPath?, port?, socket?, ' + 'watchOptions?, headers?, clientLogLevel?, overlay?, progress?, key?, cert?, ca?, pfx?, pfxPassphrase?, requestCert?, ' + 'inline?, disableHostCheck?, public?, https?, contentBase?, watchContentBase?, open?, useLocalIp?, openPage?, features?, ' + - 'compress?, proxy?, historyApiFallback?, staticOptions?, setup?, stats?, reporter?, ' + + 'compress?, proxy?, historyApiFallback?, staticOptions?, setup?, before?, after?, stats?, reporter?, ' + 'noInfo?, quiet?, serverSideRender?, index?, log?, warn? }' ] }];