At the time of development, if we need to get data interface from subdomain or other web sites, may encounter cross-domain problem, this time the commonly used way is to modify the hosts file, or configure a reverse proxy server, the hard to avoid some trouble, and sometimes need to test the interface is the development environment, are more cumbersome. Webpack-dev-server is used as a reverse proxy, but http-proxy-middleware is used as a reverse proxy

         foo://example.com:8042/over/there?name=ferret#nose
         \_/   \______________/\_________/ \_________/ \__/
          |           |            |            |        |
       scheme     authority       path        query   fragment
Copy the code

So I explored a common solution to implement the cross-domain interface of the test environment without interfering with the source code and production environment as much as possible. This article introduces two ways to use webpack-dev-server to implement the reverse proxy of the interface by simply modifying the configuration file and source code without affecting the packaging results in the production environment. Both ways are the same principle:

  1. throughpluginorloaderTo replace all other domain name interfacesscheme+authorityFor a non-repeating relative path prefix, this article isunique_dev_server
  2. letwebpack-dev-serverReverse proxy these relative paths.

The first is via definePlugin

This solution needs to modify the source code, if not acceptable to see the second solution first introduced the first step of the configuration.

// webpack.prod.js
    plugins: [...new webpack.DefinePlugin({
	      USER_SERVER: JSON.stringify('https://user.domain.com/')})]// webpack.dev.js
    plugins: [...new webpack.DefinePlugin({
      //unique_dev_server write whatever you want, as long as it is unique and non-conflicting
      	USER_SERVER: JSON.stringify('/unique_dev_server/')})]Copy the code

The development environment configures a path prefix to ensure that the value is unique and does not conflict with the interface of the domain name. Also, after this is configured, change the URL in all the corresponding JS that call the cross-domain interface

/* global USER_SERVER */
fetch(USER_SERVER+"/api/test").then((res) = > {
// fetch("https://user.doamin.com/api/test").then((res) => {
Copy the code

If you’re using ESLint, you’ll need to comment out the global variable.

  1. Step two, target/unique_dev_serverThis URL adds the reverse proxy configuration
devServer: {
    contentBase: path.join(__dirname, 'dist'),
    port: 9000.proxy: {
      '/unique_dev_server/': {
        target: 'http://localhost:8088/'.pathRewrite: {'^/unique_dev_server/': ' '},
        headers: {
          'referer': 'http://domain.com/'}}}},Copy the code

The important thing is that target should be changed to the corresponding domain address, and pathRewrite should be removed from the front key. If your cross-domain interface also requires referer or other headers, you can add them here. These two steps are done, if you have any other domain interface, just add the corresponding domain name to definePlugin and Proxy.

The second is through string-replace-loader

Another way to do this without affecting the source code is through string-replace-loader, which is installed first

npm i string-replace-loader -D

Then modify the development environment WebPack configuration

// webpack.dev.js
    rules: [{test: /\.js$/,
        loader: 'string-replace-loader'.options: {
          search: 'https://dev.example.com/'.replace: '/unique_dev_server/'}}]Copy the code

See step 2 of the first solution for proxy configuration. The advantage of this approach is that it does not modify the source code, but the disadvantage is that

  1. Too many test files may affect the compilation speed
  2. Unable to concatenate URL (usually no domain name will be concatenated)
  3. The probability of misreplacing is extremely low

If you don’t want to affect the source code and can accept the above disadvantages, you are advised to use the Loader solution.