Manually rewrite requests to specific URLs in Browsersync
<p>I'm using BrowserSync in a somewhat strange setup, where I'm proxying my web server (Apache in a Docker container), but also serving hot module replacement (HMR) from a Webpack dev server.</p>

<p>In my local dev environment, the setup looks something like this:</p>

<p><code>https://mytestsite.localhost</code> – an Apache service in a Docker container</p>

<p><code>https://localhost:8888</code> – Webpack Dev server, serving HMR</p>

<p><code>https://localhost:3000</code> – BrowserSync`</p>

<p>For hard reloads, this all works fine – the webpack dev server appears to pass on the message that a reload is needed and all is well.</p>

<p>The issue that I'm having is with hot reloads. The document being served by the BS proxy should be reading the <code>hotupdate.json</code> served by webpack-dev-server. On receiving a hot update, the page tries to load <code>/hotupdate.json</code> (which I believe tells it which snippet of code to pick up), however, because it's a relative URL, the browser tries to <code>GET https://localhost:3000/hotupdate.json</code>, which 404s, because this <code>hotupdate.json</code> is actually served by the Webpack server, e.g. <code>https://localhost:8888/hotupdate.json</code>.</p>

<p>Because I know the absolute URL to this resource, I'd like to force BrowserSync to redirect any requests to <code>/hotupdate.json</code> to <code>https://localhost:8888/hotupdate.json</code>. I thought I could do this with some middleware, but I'm struggling, possibly because I've never fully groked Express-style middleware.</p>

<p>I've tried something like this, but no worky! </p>

<pre><code>browserSync({
    proxy: {
        target: `https://${process.env.APP_HOST_PATH}`,
        middleware: [
            dontProxyHotUpdate,
            require('webpack-dev-middleware')(bundler, {
                noInfo: true,
                publicPath: webpackConfig.output.path
            }),
        ]
    },
    files: [
      'app/css/*.css',
      'app/*.html'
    ]
});

function dontProxyHotUpdate (req, res, next){
    if(req.url === '/hotupdate.json'){
        req.url = 'https://127.0.0.1:8888/hotupdate.json';
    }
    next();
}
</code></pre>

<p>It definitely loads the middleware as I can, say, <code>console.log(req.url)</code>, but I'm not able to rewrite the request URL. I suppose possible solutions would either be to rewrite the request URL, or to overwrite the response directly.</p>

<p>N.B. One might ask why I'm not using webpack-dev-server directly, as it serves HMR nicely on its own. It does, but it also doesn't allow for nice rewriting of the anchor elements within a page, e.g. changing <code>https://mytestsite.localhost/link</code> to <code>https://localhost:3000/link</code>. This is important obviously for navigating through a site while developing (which is nice, but not essential), but even more important for rewriting links to assets – SVGs, in particular, which won't load unless the path, host and port all match.</p>