Learner
Learner

Reputation: 571

How to apply createProxyMiddleware in webpack?

How to apply createProxyMiddleware in webpack?

I have a webpack.config.js with default proxy:

// development config
require('dotenv').config()
const package = require('../../package.json')
const { merge } = require('webpack-merge')
const webpack = require('webpack')
const commonConfig = require('./common')
const agent = require('agentkeepalive')

module.exports = (webpackConfigEnv, argv) =>
    merge(commonConfig(argv), {
        mode: 'development',
        entry: [
            'react-hot-loader/patch', // activate HMR for React
            'webpack-dev-server/client?http://localhost:3030', 
            'webpack/hot/only-dev-server', 
            './index.tsx', // the entry point of our app
        ],
        devServer: {
            port: 3030,
            hot: true, // enable HMR on the server
            historyApiFallback: true, 
            proxy: {
                '/api/*': {
                    target: 'http://foobar:8080/',
                    secure: false,
                    changeOrigin: true,
                    agent: new agent({
                        maxSockets: 100,
                        keepAlive: true,
                        maxFreeSockets: 10,
                        keepAliveMsecs: 100000,
                        timeout: 6000000,
                        freeSocketTimeout: 90000, // free socket keepalive for 90 seconds
                    }),
                    onProxyRes: (proxyRes) => {
                        var key = 'www-authenticate'
                        proxyRes.headers[key] =
                            proxyRes.headers[key] && proxyRes.headers[key].split(',')
                    },
                },
            },
        },
        // ... other code is omitted for the brevity
    })
    

Now I would like to use this http-proxy-middleware because of this.

So I edit the above config to:

         // ... other code is omitted for the brevity
            proxy: createProxyMiddleware('/api/*', {
                target: 'http://foobar:8080/',
                secure: false,
                changeOrigin: true,
                agent: new agent({
                    maxSockets: 100,
                    keepAlive: true,
                    maxFreeSockets: 10,
                    keepAliveMsecs: 100000,
                    timeout: 6000000,
                    freeSocketTimeout: 90000, // free socket keepalive for 90 seconds
                }),
                onProxyRes: (proxyRes) => {
                    var key = 'www-authenticate'
                    proxyRes.headers[key] =
                        proxyRes.headers[key] && proxyRes.headers[key].split(',')
                },
            }),
        },
        // ... other code is omitted for the brevity
    })

However, when I try to build my application, it throws an error:

> [webpack-cli] webpack Dev Server Invalid Options

> options.proxy should be {Object|Array} (https://webpack.js.org/configuration/dev-server/#devserverproxy)

Please, tell me how can is it possible to aplly createProxyMiddleware for proxy in webpack config?

Upvotes: 3

Views: 2756

Answers (1)

code
code

Reputation: 6319

AFAIK it's not possible to use custom middleware using Webpack's dev server. If you need the proxy bad enough, you can hook a custom Express server to Webpack and use middleware thus.

Make sure you additionally install express, webpack-dev-middleware, and webpack-hot-middleware (if you still want HMR). Then create your server file with the following (like) contents:

const express = require("express");
const { createProxyMiddleware } = require("http-proxy-middleware");
const webpack = require("webpack");
const webpackHotMiddleware = require("webpack-hot-middleware");
const webpackDevMiddleware = require("webpack-dev-middleware");
const webpackConfig = require("./webpack.config"); // path to your `webpack.config.js`

const webpackCompiler = webpack(webpackConfig); // create webpack compiler with config

const app = express();
app.use(createProxyMiddleware(/* ... */));
app.use(webpackDevMiddleware(webpackCompiler, {
  publicPath: webpackConfig.output.publicPath, // provide the public path for the middleware
}));
// if you need HMR:
app.use(webpackHotMiddleware(webpackCompiler));

// you need "*" if you're creating a SPA like if you're using react router
app.get("*", (req, res) => {
  res.sendFile(/* absolute path to index.html */);
});

app.listen(3030, () => console.log("Webpack running on express server"));

For the HMR to work, you need to slightly alter your webpack.config.js. Replace the second and third elements in config.entry with "webpack-hot-middleware/client", then in config.plugins add new webpack.HotModuleReplacementPlugin().

Now fire up your server with node server.js and treat http://localhost:3030 as your ordinary Webpack dev server and hope for the best.

Remember that we're only doing this for development. We don't need webpack when running in prod.

Your webpack.config.js should end up something like:

// development config
require('dotenv').config()
const package = require('../../package.json')
const {
  merge
} = require('webpack-merge')
const webpack = require('webpack')
const commonConfig = require('./common')
const agent = require('agentkeepalive')

module.exports = (webpackConfigEnv, argv) =>
  merge(commonConfig(argv), {
    mode: 'development',
    entry: [
      'webpack-hot-middleware/client', // this powers our HMR
      'react-hot-loader/patch', // activate HMR for React'
      './index.tsx', // the entry point of our app
    ],
    devServer: {
      port: 3030,
      hot: true, // enable HMR on the server
      historyApiFallback: true,
    },
    plugins: [new webpack.HotModuleReplacementPlugin()]
    // ... other code is omitted for the brevity
  })

Upvotes: 1

Related Questions