Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide migration guide for setupMiddlewares #4129

Closed
2 tasks
oobles opened this issue Dec 22, 2021 · 14 comments · Fixed by webpack/webpack.js.org#5875
Closed
2 tasks

Provide migration guide for setupMiddlewares #4129

oobles opened this issue Dec 22, 2021 · 14 comments · Fixed by webpack/webpack.js.org#5875
Assignees

Comments

@oobles
Copy link

oobles commented Dec 22, 2021

Documentation Is:

  • [x ] Missing
  • [x ] Needed
  • Confusing
  • Not Sure?

Please Explain in Detail...

The recent change for issue #4068 deprecates onAfterSetupMiddleware and onBeforeSetupMiddleware. The commit making the change provides a new example, but there's no migration guide on how to migrate away from the deprecated configuration options.

Your Proposal for Changes

@snitin315
Copy link
Member

Before

module.exports = {
  //...
  devServer: {
    onAfterSetupMiddleware: function (devServer) {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

      devServer.app.get('/some/after/path', function (req, res) {
        res.json({ custom: 'response-after' });
      });
    },

    onBeforeSetupMiddleware: function (devServer) {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

      devServer.app.get('/some/before/path', function (req, res) {
        res.json({ custom: 'response-before' });
      });
    },
  },
};

After

module.exports = {
  // ...
  devServer: {
    setupMiddlewares: (middlewares, devServer) => {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

       // onBeforeSetupMiddleware
      devServer.app.get('/some/before/path', (_, response) => {
         response.json({ custom: 'response-before' });
      });

      // onAfterSetupMiddleware
      middlewares.push({
        name: 'after-middleware',
        // `path` is optional
        path: '/some/after/path',
        middleware: (req, res) => {
          res.json({ custom: 'response-after' });
        },
      });

      // another after middleware
      middlewares.push((req, res) => {
        res.send('Hello World!');
      });

      return middlewares;
    },
  },
};

I believe this should be the migration. /cc @alexander-akait

@markcipolla
Copy link

Thanks @snitin315 🙏🏻

How would you migrate a before and after block with server.use instead of server.get?
e.g. the below:

before(app, server) {
      // Keep `evalSourceMapMiddleware` and `errorOverlayMiddleware`
      // middlewares before `redirectServedPath` otherwise will not have any effect
      // This lets us fetch source contents from webpack for the error overlay
      app.use(evalSourceMapMiddleware(server));
      // This lets us open files from the runtime error overlay.
      app.use(errorOverlayMiddleware());

      if (fs.existsSync(paths.proxySetup)) {
        // This registers user provided middleware for proxy reasons
        require(paths.proxySetup)(app);
      }
    },
    after(app) {
      // Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match
      app.use(redirectServedPath(paths.publicUrlOrPath));

      // This service worker file is effectively a 'no-op' that will reset any
      // previous service worker registered for the same host:port combination.
      // We do this in development to avoid hitting the production cache if
      // it used the same host and port.
      // https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
      app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath));
    },

@alexander-akait
Copy link
Member

middlewares is just array, put it before or after, as you work with arrays and return modified array

@otakustay
Copy link

Note that app.get(...) in onAfterSetupMiddleware is not the same as app.get(...) in setupMiddlewares.

It seems app.get() in setupMiddlewares are always applied before middlewares are applied, if we have a config like this:

{
    onAfterSetupMiddleware: server => {
        server.app.get('/__index__.html', (req, res) => res.send('foo'));
    },
    config.historyApiFallback = {
        index: '/__index__.html',
        disableDotRule: true,
    };
}

The route /__index__.html will take place for history api fallback, however if we changed it to this:

{
    setupMiddlewares: (middlewares, server) => {
        server.app.get('/__index__.html', (req, res) => res.send('foo'));
        return middlewares;
    },
    config.historyApiFallback = {
        index: '/__index__.html',
        disableDotRule: true,
    };
}

History api fallback are broken, we have to transform it into a middleware like:

middlewares.unshift({
    path: '/__index__.html',
    handler: (req, res, next) => {
        if (req.method === 'GET') {
            res.send('foo');
        }
        else {
            next();
        }
    }
});

In this way we have to add a request.method check in middleware implementation.

@alexander-akait
Copy link
Member

Yes, it is good solution 👍

@coderXaj
Copy link

(node:9304) [DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE] DeprecationWarning: 'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
(Use node --trace-deprecation ... to show where the warning was created)
(node:9304) [DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE] DeprecationWarning: 'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.

Can any one please tell me how solve to this error my localhost is not opening after i get this error.

@umair39
Copy link

umair39 commented Dec 30, 2021

Before

module.exports = {
  //...
  devServer: {
    onAfterSetupMiddleware: function (devServer) {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

      devServer.app.get('/some/after/path', function (req, res) {
        res.json({ custom: 'response-after' });
      });
    },

    onBeforeSetupMiddleware: function (devServer) {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

      devServer.app.get('/some/before/path', function (req, res) {
        res.json({ custom: 'response-before' });
      });
    },
  },
};

After

module.exports = {
  // ...
  devServer: {
    setupMiddlewares: (middlewares, devServer) => {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

       // onBeforeSetupMiddleware
      devServer.app.get('/some/before/path', (_, response) => {
         response.json({ custom: 'response-before' });
      });

      // onAfterSetupMiddleware
      middlewares.push({
        name: 'after-middleware',
        // `path` is optional
        path: '/some/after/path',
        middleware: (req, res) => {
          res.json({ custom: 'response-after' });
        },
      });

      // another after middleware
      middlewares.push((req, res) => {
        res.send('Hello World!');
      });

      return middlewares;
    },
  },
};

I believe this should be the migration. /cc @alexander-akait

i am facing same issue how i use that code in node module files

@umair39
Copy link

umair39 commented Dec 30, 2021

where i can find file to isert modified code

@alexander-akait
Copy link
Member

webpack.config.js file

@darkcohiba
Copy link

@snitin315 I can not find where to replace the code with the updated segment, what is the module this goes in?

@snitin315
Copy link
Member

@darkcohiba inside webpack.config.js, devServer option to be specific.

@darkcohiba
Copy link

@snitin315 this is my webpack config js dev server, I don't see what I need to replace;

`// @remove-on-eject-begin
/**

  • Copyright (c) 2015-present, Facebook, Inc.
  • This source code is licensed under the MIT license found in the
  • LICENSE file in the root directory of this source tree.
    */
    // @remove-on-eject-end
    'use strict';

const fs = require('fs');
const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware');
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
const ignoredFiles = require('react-dev-utils/ignoredFiles');
const redirectServedPath = require('react-dev-utils/redirectServedPathMiddleware');
const paths = require('./paths');
const getHttpsConfig = require('./getHttpsConfig');

const host = process.env.HOST || '0.0.0.0';
const sockHost = process.env.WDS_SOCKET_HOST;
const sockPath = process.env.WDS_SOCKET_PATH; // default: '/ws'
const sockPort = process.env.WDS_SOCKET_PORT;

module.exports = function (proxy, allowedHost) {
const disableFirewall =
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true';
return {
// WebpackDevServer 2.4.3 introduced a security fix that prevents remote
// websites from potentially accessing local content through DNS rebinding:
// #887
// https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
// However, it made several existing use cases such as development in cloud
// environment or subdomains in development significantly more complicated:
// facebook/create-react-app#2271
// facebook/create-react-app#2233
// While we're investigating better solutions, for now we will take a
// compromise. Since our WDS configuration only serves files in the public
// folder we won't consider accessing them a vulnerability. However, if you
// use the proxy feature, it gets more dangerous because it can expose
// remote code execution vulnerabilities in backends like Django and Rails.
// So we will disable the host check normally, but enable it if you have
// specified the proxy setting. Finally, we let you override it if you
// really know what you're doing with a special environment variable.
// Note: ["localhost", ".localhost"] will support subdomains - but we might
// want to allow setting the allowedHosts manually for more complex setups
allowedHosts: disableFirewall ? 'all' : [allowedHost],
headers: {
'Access-Control-Allow-Origin': '',
'Access-Control-Allow-Methods': '
',
'Access-Control-Allow-Headers': '*',
},
// Enable gzip compression of generated files.
compress: true,
static: {
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files won’t automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in public directory
// get served. Our build script will copy public into the build folder.
// In index.html, you can get URL of public folder with %PUBLIC_URL%:
//
// In JavaScript code, you can access it with process.env.PUBLIC_URL.
// Note that we only recommend to use public folder as an escape hatch
// for files like favicon.ico, manifest.json, and libraries that are
// for some reason broken when imported through webpack. If you just want to
// use an image, put it in src and import it from JavaScript instead.
directory: paths.appPublic,
publicPath: [paths.publicUrlOrPath],
// By default files from contentBase will not trigger a page reload.
watch: {
// Reportedly, this avoids CPU overload on some systems.
// facebook/create-react-app#293
// src/node_modules is not ignored to support absolute imports
// facebook/create-react-app#1065
ignored: ignoredFiles(paths.appSrc),
},
},
client: {
webSocketURL: {
// Enable custom sockjs pathname for websocket connection to hot reloading server.
// Enable custom sockjs hostname, pathname and port for websocket connection
// to hot reloading server.
hostname: sockHost,
pathname: sockPath,
port: sockPort,
},
overlay: {
errors: true,
warnings: false,
},
},
devMiddleware: {
// It is important to tell WebpackDevServer to use the same "publicPath" path as
// we specified in the webpack config. When homepage is '.', default to serving
// from the root.
// remove last slash so user can land on /test instead of /test/
publicPath: paths.publicUrlOrPath.slice(0, -1),
},

https: getHttpsConfig(),
host,
historyApiFallback: {
  // Paths with dots should still use the history fallback.
  // See https://github.com/facebook/create-react-app/issues/387.
  disableDotRule: true,
  index: paths.publicUrlOrPath,
},
// `proxy` is run between `before` and `after` `webpack-dev-server` hooks
proxy,
onBeforeSetupMiddleware(devServer) {
  // Keep `evalSourceMapMiddleware`
  // middlewares before `redirectServedPath` otherwise will not have any effect
  // This lets us fetch source contents from webpack for the error overlay
  devServer.app.use(evalSourceMapMiddleware(devServer));

  if (fs.existsSync(paths.proxySetup)) {
    // This registers user provided middleware for proxy reasons
    require(paths.proxySetup)(devServer.app);
  }
},
onAfterSetupMiddleware(devServer) {
  // Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match
  devServer.app.use(redirectServedPath(paths.publicUrlOrPath));

  // This service worker file is effectively a 'no-op' that will reset any
  // previous service worker registered for the same host:port combination.
  // We do this in development to avoid hitting the production cache if
  // it used the same host and port.
  // https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
  devServer.app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath));
},

};
};
`

@alielachkar
Copy link

alielachkar commented Mar 18, 2024

@snitin315 I don't think the question to migrate onBeforeSetupMiddleware with use instead of get has been answered. How would migrate something like this?

 onBeforeSetupMiddleware: function (devServer) {
            devServer.app.use(function(req, res, next) {
                res.setHeader('Access-Control-Allow-Origin', '*');
                res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
                res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
                next();
            });
        }
},

I tried using unshift as mentioned in the DevServer documentation, but without success.

@alielachkar
Copy link

FIgured it out! return wasn't necessary in onBeforeSetupMiddleware, but it is with setupMiddlewares

        setupMiddlewares: function (middlewares) {
            middlewares.unshift(function(req, res, next) {
                res.setHeader('Access-Control-Allow-Origin', '*');
                res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
                res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
                next();
            });
            return middlewares;
        },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants