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

Setting exclude / include options to the plugin is required when I have module.rules.exclude are required? This is not working with a type of regex #324

Closed
rocalvo-meli opened this issue Mar 2, 2021 · 5 comments · Fixed by #370 or #380

Comments

@rocalvo-meli
Copy link

Hi! 👋 😄

Is this option exclude required when I have module.rules.exclude inside my webpack.config.js?


I'm trying to set the exclude option in the follow format and is not working:

new ReactRefreshWebpackPlugin({
  overlay: false,
  exclude: [/\/node_modules\/(?!frontend-lazy)\//],
},

I also try with the following format and didn't work:
exclude: /\/node_modules\/(?!frontend-lazy)\//

That is the format that I use inside my module.rules.exclude

The error that I see on the browser console is:

react-refresh-runtime.development.js:672 Uncaught TypeError: __react_refresh_utils__.getModuleExports is not a function
    at Object.<anonymous> (react-refresh-runtime.development.js:672)
    at Object../node_modules/react-refresh/cjs/react-refresh-runtime.development.js (react-refresh-runtime.development.js:672)
    at __webpack_require__ (bootstrap:788)
    at fn (bootstrap:150)
    at Object.<anonymous> (runtime.js:6)
    at Object../node_modules/react-refresh/runtime.js (runtime.js:8)
    at __webpack_require__ (bootstrap:788)
    at fn (bootstrap:150)
    at Object../node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils.js (RefreshUtils.js:2)

Thank you in advance! 🙏 😊

@pmmmwh
Copy link
Owner

pmmmwh commented Mar 2, 2021

Hi, can you give a bit more information on how your Webpack config look like? If you use module.rules.exclude then you probably would want to use the exclude option to also make us not inject loaders to process those files you've excluded.

Apart from that, your regex doesn't see to do what you want - I am assuming you want to exclude everything under node_modules that is within the frontend-lazy directory.

You test with the following cases:

/node_modules/frontend-lazy/
/node_modules/test/
/node_modules//

I think you would want this instead - \/node_modules\/(?!frontend-lazy)[^/]+\/ - or simpler just remove the path separator in the end.

@rocalvo-meli
Copy link
Author

Hi! thank you for your response!

Apart of the regex test target, I don't understand why if I use exclude: [ /\/node_modules\/(?!frontend-lazy)\// ] the plugin throws an error on the console.

webpack.config.js

     mode: 'development',
      module:{ 
        rules:[ 
            ....,
            { test: /\.(js|jsx)$/,
              use: { 
                   loader: 'babel-loader',
                   options: { 
                      cacheDirectory: true,
                      babelrc: false,
                      plugins: [Array],
                      presets: [Array],
                      sourceType: 'unambiguous' } 
                },
                exclude: [ /\/node_modules\/(?!frontend-lazy)\// ] }
            ] },
      resolve: { extensions: [ '.js', '.jsx', '.json', '.ts', '.tsx' ] },
      entry: { example: [ 'webpack-hot-middleware/client', './app/mobile.js' ] },
      stats: { all: false,
         assets: true,
         builtAt: true,
         modules: true,
         moduleTrace: true,
         maxModules: 100,
         reasons: true,
         children: false,
         chunks: true,
         chunkOrigins: true,
         entrypoints: true,
         performance: true,
         publicPath: false,
         errors: true,
         errorDetails: true,
         warnings: true,
         timings: true,
         version: true },
      plugins:
       [ ManifestPlugin { opts: [Object] },
         LoadablePlugin {
           handleEmit: [Function],
           writeAssetsFile: [Function],
           opts: [Object],
           compiler: null },
         MiniCssExtractPlugin {
           _sortedModulesCache: [WeakMap],
           options: [Object],
           runtimeOptions: [Object] },
         CopyPlugin { patterns: [], options: {} },
         HotModuleReplacementPlugin {
          options: {},
          multiStep: undefined,
          fullBuildTimeout: 200,
          requestTimeout: 10000 },
         ReactRefreshPlugin {
          options:
           { overlay: false,
             exclude:  [ /\/node_modules\/(?!frontend-lazy)\// ]
             include: /\.([jt]sx?|flow)$/i } },
          DefinePlugin { definitions: [Object] } ],
      output: { 
         filename: '[name].js',
         path:  'REMOVED_FULL_PATH_FOR_EXAMPLE/build',
         publicPath: '/'
      },
      devtool: 'cheap-module-source-map' }

@pmmmwh
Copy link
Owner

pmmmwh commented Apr 24, 2021

I've identified a bug, this would be fixed in the next release.

@Birch-san
Copy link

Birch-san commented Sep 2, 2021

@pmmmwh I got this same error just now on 0.10.0.

I expect that the intention of @rocalvo-meli's regex was "exclude everything in node_modules, except for files in node_modules/frontend-lazy/".

this is a common requirement in monorepo setups, where you are actively modifying the source code of another package that you read via a symlink in node_modules. in fact, Jest has a section on their docs to explain this exact path matching problem:
https://jestjs.io/docs/configuration#transformignorepatterns-arraystring
https://jestjs.io/docs/tutorial-react-native#transformignorepatterns-customization

@rocalvo-meli's regex actually looks fine, but will go bang on Windows because paths are separated by backslashes. you can support all platforms by changing the regex like so (this got fast-refresh working in my monorepo):

exclude: /node_modules[/\\](?!frontend-lazy)[/\\]/,

otherwise, the matcher will end up excluding nothing (because it insists that files need certain forwardslashes in order to be excluded, and a Windows filepath would have no forwardslashes).

with no files excluded: the webpack plugin attempts to inject itself into everything, including some files which are not targeted by the ProvidePlugin. those files have had no definition of __react_refresh_utils__ provided to them, and thus throw this error.

@pmmmwh
Copy link
Owner

pmmmwh commented Sep 2, 2021

@pmmmwh I got this same error just now on 0.10.0.

Are you using 0.4.3 or 0.5.0-rc? Only the latter contain the required fixes.

@rocalvo-meli's regex actually looks fine, but will go bang on Windows because paths are separated by backslashes. you can support all platforms by changing the regex like so (this got fast-refresh working in my monorepo):

exclude: /node_modules[/\\](?!frontend-lazy)[/\\]/,

otherwise, the matcher will end up excluding nothing (because it insists that files need certain forwardslashes in order to be excluded, and a Windows filepath would have no forwardslashes).

It has nothing to do with Windows - the RegExp was problematic as it didn;t include any actual match-able characters within the two slashes, so essentially it only match node_modules// and not anything else. I still think my correction to the RegExp is correct.

with no files excluded: the webpack plugin attempts to inject itself into everything, including some files which are not targeted by the ProvidePlugin. those files have had no definition of __react_refresh_utils__ provided to them, and thus throw this error.

The issue with no files excluded actually would yield recursive dependencies - React Refresh Utils would try to inject itself into itself. This is now avoided since we explicitly blacklist things related to that.

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