This is a very useful pattern I was using with my team at TransferWise to mock the backend. Spinning up an entire stack in a codebase with many microservices is a no go, so this is the best solution to improve the productivity of the frontend teams, that I found.

To begin with I opted for creating two different webpack.config.xxx.js files, a dev file and a prod file.

At webpack.config.dev.js you add the following:

import devServer from './devServer';

export default () => ({
  mode: 'development',
  // more stuff here
	devServer, // this is the important bit.
	module: {...},
	plugins: [...],
});

And then in the devServer/index.js file you do the following:

const onProxyReq = require('./onProxyRequest');

module.exports = {
  port: 3000,
  proxy: [
    {
      context: ['/api'], //add more here if you want
      target: 'localhost',
      secure: false,
      changeOrigin: true,
      onProxyReq,
    },
  ],
};

And finally inside the onProxyRequest.js you add the following:

const STUBS = {
  features: require('./__stubs__/features.json'),
  'activity/list': require('./__stubs__/activities.json'),
}

module.exports = (proxyRequest, { originalUrl }, res) => {
  const matchingStub = Object.keys(STUBS).find(url => originalUrl.includes(url));

// Here you can do more stuff like adding specific headers etc
 // if (originalUrl.includes('session/details')) {
 //  res.setHeader('set-cookie', 'oauthToken=abc');
 //  }


  if (matchingStub) {
    return res.json(STUBS[matchingStub]);
  }

  return res.json({});
};

Note that the names in the STUBS variable are important. They are part of the api that you are trying to mock here. So they can’t be random.

Caveats

The stubs are going to need maintenance. But even still this is a better approach in many cases for things like UI work and creating a new first version of a feature. It speeds up developing so much and you save so much time from having to fuff around with backend services and killing your laptops memory and CPU.

Hope it helps someone.