2

I am suddenly unable to build my Webpack frontend, I randomly began getting this error despite not making any changes to the code:

Starting the development server...

/home/username/Documents/frontend/node_modules/react-dev-utils/ModuleScopePlugin.js:32
          request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
                                      ^

TypeError: Cannot read properties of undefined (reading 'indexOf')
    at /home/username/Documents/frontend/node_modules/react-dev-utils/ModuleScopePlugin.js:32:39
    at Hook.eval [as callAsync] (eval at create (/home/username/Documents/frontend/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:52:1)
    at Resolver.doResolve (/home/username/Documents/frontend/node_modules/enhanced-resolve/lib/Resolver.js:715:16)
    at /home/username/Documents/frontend/node_modules/enhanced-resolve/lib/TryNextPlugin.js:32:14
    at _next0 (eval at create (/home/username/Documents/frontend/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:173:1)
    at eval (eval at create (/home/username/Documents/frontend/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:195:1)
    at /home/username/Documents/frontend/node_modules/enhanced-resolve/lib/ConditionalPlugin.js:40:47
    at Hook.eval [as callAsync] (eval at create (/home/username/Documents/frontend/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:187:1)
    at Resolver.doResolve (/home/username/Documents/frontend/node_modules/enhanced-resolve/lib/Resolver.js:715:16)
    at /home/username/Documents/frontend/node_modules/enhanced-resolve/lib/ConditionalPlugin.js:42:14
    at Hook.eval [as callAsync] (eval at create (/home/username/Documents/frontend/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:22:1)
    at Resolver.doResolve (/home/username/Documents/frontend/node_modules/enhanced-resolve/lib/Resolver.js:715:16)
    at /home/username/Documents/frontend/node_modules/enhanced-resolve/lib/NextPlugin.js:30:14
    at _next0 (eval at create (/home/username/Documents/frontend/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:8:1)
    at eval (eval at create (/home/username/Documents/frontend/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:30:1)
    at /home/username/Documents/frontend/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:64:16
    at /home/username/Documents/frontend/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:152:14
    at /home/username/Documents/frontend/node_modules/enhanced-resolve/lib/forEachBail.js:39:13
    at /home/username/Documents/frontend/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:76:16
    at process.processTicksAndRejections (node:internal/process/task_queues:81:21)

Node.js v20.19.2
 node:internal/process/promises:391
    triggerUncaughtException(err, true /* fromPromise */);
    ^

RpcIpcMessagePortClosedError: Cannot send the message - the message port has been closed for the process 146051.
    at /home/username/Documents/frontend/node_modules/fork-ts-checker-webpack-plugin/lib/rpc/rpc-ipc/RpcIpcMessagePort.js:47:47
    at process.processTicksAndRejections (node:internal/process/task_queues:81:21) {
  code: undefined,
  signal: undefined
}

Node.js v20.19.2

My app was ejected from create-react-app years ago, and I haven't had any issues until they just sprung up today.

I am still running the same "react-dev-utils": "^12.0.1" and "webpack": "^5.92.1" that I have been using, nothing has changed that I am aware of. Re-running npm install --legacy-peer-deps does not introduce any changes to package-lock.json. What could be the cause, and how can I fix this?

0

1 Answer 1

2

I have not been able to find a dependency-based fix, or to truly pinpoint the cause, but I got a workaround that is able to hold me over until a better solution is found. I created a patches/PatchedModuleScopePlugin.js file that looks like this:

'use strict';

const chalk = require('chalk');
const path = require('path');
const os = require('os');

class PatchedModuleScopePlugin {
  constructor(appSrc, allowedFiles = []) {
    this.appSrcs = Array.isArray(appSrc) ? appSrc : [appSrc];
    this.allowedFiles = new Set(allowedFiles);
    this.allowedPaths = [...allowedFiles].map(path.dirname).filter(p => path.relative(p, process.cwd()) !== '');
  }

  apply(resolver) {
    const { appSrcs } = this;
    resolver.hooks.file.tapAsync(
      'ModuleScopePlugin',
      (request, contextResolver, callback) => {
        // Unknown issuer, probably webpack internals
        if (!request.context.issuer) {
          return callback();
        }
        if (
          // If this resolves to a node_module, we don't care what happens next
          !request.descriptionFileRoot ||
          request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
          request.descriptionFileRoot.indexOf('\\node_modules\\') !== -1 ||
          // Make sure this request was manual
          !request.__innerRequest_request
        ) {
          return callback();
        }
        // Resolve the issuer from our appSrc and make sure it's one of our files
        // Maybe an indexOf === 0 would be better?
        if (
          appSrcs.every(appSrc => {
            const relative = path.relative(appSrc, request.context.issuer);
            // If it's not in one of our app src or a subdirectory, not our request!
            return relative.startsWith('../') || relative.startsWith('..\\');
          })
        ) {
          return callback();
        }
        const requestFullPath = path.resolve(
          path.dirname(request.context.issuer),
          request.__innerRequest_request
        );
        if (this.allowedFiles.has(requestFullPath)) {
          return callback();
        }
        if (this.allowedPaths.some((allowedFile) => {
          return requestFullPath.startsWith(allowedFile);
        })) {
          return callback();
        }
        // Find path from src to the requested file
        // Error if in a parent directory of all given appSrcs
        if (
          appSrcs.every(appSrc => {
            const requestRelative = path.relative(appSrc, requestFullPath);
            return (
              requestRelative.startsWith('../') ||
              requestRelative.startsWith('..\\')
            );
          })
        ) {
          const scopeError = new Error(
            `You attempted to import ${chalk.cyan(
              request.__innerRequest_request
            )} which falls outside of the project ${chalk.cyan(
              'src/'
            )} directory. ` +
              `Relative imports outside of ${chalk.cyan(
                'src/'
              )} are not supported.` +
              os.EOL +
              `You can either move it inside ${chalk.cyan(
                'src/'
              )}, or add a symlink to it from project's ${chalk.cyan(
                'node_modules/'
              )}.`
          );
          Object.defineProperty(scopeError, '__module_scope_plugin', {
            value: true,
            writable: false,
            enumerable: false,
          });
          callback(scopeError, request);
        } else {
          callback();
        }
      }
    );
  }
}

module.exports = PatchedModuleScopePlugin;

Then updated my webpack.config.js like so:

// Old definition
const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin");

// New definition
const PatchedModuleScopePlugin = require("./patches/PatchedModuleScopePlugin");
Sign up to request clarification or add additional context in comments.

1 Comment

I couldn’t fix the root issue, but I made a custom PatchedModuleScopePlugin to bypass the import restriction outside src/. Then I replaced the default ModuleScopePlugin in webpack.config.js with my patched version. It works for now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.