Why isn't my Webpack devServer property working?

Angry Mets fans, you got what you wanted. Now please do us all a favor and shut up already.

While working on a small Redux application for work I wanted to proxy some requests to an Express API I had also built. According to the Webpack documentation, this was an easy task.

1
2
3
4
5
6
7
8
9
10
{
devServer: {
proxy: {
'/some/path*': {
target: 'https://other-server.example.com',
secure: false,
},
},
},
}

Alright, let me just go into webpack.config.js (I was using a boilerplate to get started, as many do) and add that property.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./index'
],
//...
devServer: {
proxy: {
'/auth/*': 'http://localhost:8081/',
'/event/*': 'http://localhost:8081/',
}
},
//...
};

I reloaded the server and issued a request to /auth/login. Nothing happened. Checked the console for the Express app, no request logged. Hmm, should be straightforward enough, why isn’t it working?

I tried routing every request to the API, just to be sure:

1
2
3
proxy: {
'*': 'http://localhost:8081/'
}

No dice. All requests went to the Redux application. After moving the proxy config all over the file, trying to intercept the request and inspect it (using bypass), and Googling with no luck, I suddenly thought, How is the server getting created, anyway?

Then it hit me. The server.js file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true,
stats: {
colors: true
},
}).listen(3000, 'localhost', function (err) {
if (err) {
console.log(err);
}
console.log('Listening at localhost:3000');
});

Duh.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true,
stats: {
colors: true
},
proxy: {
'/auth/*': 'http://localhost:8081/',
'/event/*': 'http://localhost:8081/',
}
}).listen(3000, 'localhost', function (err) {
if (err) {
console.log(err);
}
console.log('Listening at localhost:3000');
});

Worked like a charm. This served as a good reminder to really understand the boilerplate you’re working with before you get too far into a project.