t49tran / react-google-recaptcha-v3

Google Recaptcha V3 integration for React
MIT License
427 stars 91 forks source link

Incompatible with Webpack 5 (“process is not defined”) #107

Open Michael-1 opened 2 years ago

Michael-1 commented 2 years ago

The function logWarningMessage in utils.js depends on the process variable being defined. But Webpack 5 does no longer include a polyfill for this Node.js variable. So, when a warning should be logged, an error is thrown instead, and you see this in the browser console:

Uncaught ReferenceError: process is not defined

Suggestion: disable this heuristic on a “production mode,” and instead always log warnings.

(Webpack provides an option to restore the process variable with the DefinePlugin or the EnvironmentPlugin, but a library should not depend on them, in my opinion.)

t49tran commented 2 years ago

Hi @Michael-1, thanks for bringing this up, I will add an extra condition to check if process is undefined. However, process is not something Webpack specific and this library is not written only to build with Webpack regardless of versions. This library is not written to depedent on Webpack or a webpack plugin.

Also, using process.env to inject environment variables is a common practice and all the bundling tool I have used support it (parcel, rollup, webpack, CRA, snowpack, .etc).

I have never thought about a situation when it's not available but thank for letting me know, I will add an extra condition to cover it in the next release.

qnighy commented 2 years ago

The actual problem is how it looks for the environment variable: https://github.com/t49tran/react-google-recaptcha-v3/blob/v1.9.7/src/utils.ts#L147-L148

  const isDevelopmentMode =
    !!process.env && process.env.NODE_ENV !== 'production';

Webpack inserts DefinePlugin for process.env.NODE_ENV by default, but this replacement is syntactic. Therefore the code is transformed into the following:

const isDevelopmentMode =
  !!process.env && 'production' !== 'production';

!!process.env still remains. Webpack 4 had the ability to mock process and Buffer and it's enabled by default, so it's transformed to something similar to this:

const process = require.webpackProcessStub;
const isDevelopmentMode =
  !!process.env && 'production' !== 'production';

Webpack 5 removed the functionality therefore it ends up being unable to find process.

As an example, React uses a simpler condition for environment detection:

if (process.env.NODE_ENV === 'production') {