function()

in internal/node/require_patch.js [354:487]


    function(request, parent, isMain, options) {
  const parentFilename = (parent && parent.filename) ? parent.filename : undefined;
  if (SILLY_VERBOSE) log_verbose(`resolve ${request} from ${parentFilename}`);

  const failedResolutions = [];

  // Attempt to resolve to module root.
  // This should be the first attempted resolution because:
  // - it's fairly cheap to check (regex over a small array);
  // - it is be very common when there are a lot of packages built from source;
  if (!isMain) {
    // Don't resolve to module root if this is the main entry point
    // as the main entry point will always be fully qualified with the
    // workspace name and full path.
    // See https://github.com/bazelbuild/rules_nodejs/issues/834
    const moduleRoot = resolveToModuleRoot(request);
    if (moduleRoot) {
      const moduleRootInRunfiles = resolveRunfiles(undefined, moduleRoot);
      const filename = module.constructor._findPath(moduleRootInRunfiles, []);
      if (filename) {
        return filename;
      } else {
        failedResolutions.push(
            `module root ${moduleRoot} - No file ${request} found in module root ${moduleRoot}`);
      }
    }
  }

  // Built-in modules, relative, absolute imports and npm dependencies
  // can be resolved using request
  try {
    const resolved = originalResolveFilename(request, parent, isMain, options);
    if (resolved === request || request.startsWith('.') || request.startsWith('/') ||
        request.match(/^[A-Z]\:[\\\/]/i)) {
      if (SILLY_VERBOSE)
        log_verbose(
            `resolved ${request} to built-in, relative or absolute import ` +
            `${resolved} from ${parentFilename}`);
      return resolved;
    } else {
      // Resolved is not a built-in module, relative or absolute import
      // but also allow imports within npm packages that are within the parent files
      // node_modules, meaning it is a dependency of the npm package making the import.
      const parentSegments = parentFilename ? parentFilename.replace(/\\/g, '/').split('/') : [];
      const parentNodeModulesSegment = parentSegments.indexOf('node_modules');
      if (parentNodeModulesSegment != -1) {
        const parentRoot = parentSegments.slice(0, parentNodeModulesSegment).join('/');
        const relative = path.relative(parentRoot, resolved);
        if (!relative.startsWith('..')) {
          // Resolved within parent node_modules
          log_verbose(
              `resolved ${request} within parent node_modules to ` +
              `${resolved} from ${parentFilename}`);
          return resolved;
        } else {
          throw new Error(
              `Resolved to ${resolved} outside of parent node_modules ${parentFilename}`);
        }
      }
      throw new Error('Not a built-in module, relative or absolute import');
    }
  } catch (e) {
    failedResolutions.push(`built-in, relative, absolute, nested node_modules - ${e.toString()}`);
  }

  // If the import is not a built-in module, an absolute, relative import or a
  // dependency of an npm package, attempt to resolve against the runfiles location
  try {
    const resolved =
        originalResolveFilename(resolveRunfiles(parentFilename, request), parent, isMain, options);
    log_verbose(`resolved ${request} within runfiles to ${resolved} from ${parentFilename}`);
    return resolved;
  } catch (e) {
    failedResolutions.push(`runfiles - ${e.toString()}`);
  }

  // If the parent file is from an external repository, attempt to resolve against
  // the external repositories node_modules (if they exist)
  let relativeParentFilename =
      parentFilename ? path.relative(process.env.RUNFILES, parent.filename) : undefined;
  if (relativeParentFilename && !relativeParentFilename.startsWith('..')) {
    // Remove leading USER_WORKSPACE_NAME/external so that external workspace name is
    // always the first segment
    // TODO(gregmagolan): should not be needed when --nolegacy_external_runfiles is default
    const externalPrefix = `${USER_WORKSPACE_NAME}/external/`;
    if (relativeParentFilename.startsWith(externalPrefix)) {
      relativeParentFilename = relativeParentFilename.substr(externalPrefix.length);
    }
    const parentSegments = relativeParentFilename.split('/');
    if (parentSegments[0] !== USER_WORKSPACE_NAME) {
      try {
        const resolved = originalResolveFilename(
            resolveRunfiles(undefined, parentSegments[0], 'node_modules', request), parent, isMain,
            options);
        log_verbose(
            `resolved ${request} within node_modules ` +
            `(${parentSegments[0]}/node_modules) to ${resolved} from ${relativeParentFilename}`);
        return resolved;
      } catch (e) {
        failedResolutions.push(`${parentSegments[0]}/node_modules - ${e.toString()}`);
      }
    }
  }

  // If import was not resolved above then attempt to resolve
  // within the node_modules filegroup in use
  try {
    const resolved = originalResolveFilename(
        resolveRunfiles(undefined, NODE_MODULES_ROOT, request), parent, isMain, options);
    log_verbose(
        `resolved ${request} within node_modules (${NODE_MODULES_ROOT}) to ` +
        `${resolved} from ${parentFilename}`);
    return resolved;
  } catch (e) {
    failedResolutions.push(`node_modules attribute (${NODE_MODULES_ROOT}) - ${e.toString()}`);
  }

  // Print the same error message that vanilla nodejs does.
  // See https://github.com/bazelbuild/rules_nodejs/issues/1015
  let moduleNotFoundError = `Cannot find module '${request}'. ` +
      'Please verify that the package.json has a valid "main" entry';
  if (VERBOSE_LOGS) {
    moduleNotFoundError += `\nrequired in target ${TARGET} by '${parentFilename}'\n  looked in:\n` +
        failedResolutions.map(r => `    ${r}`).join('\n') + '\n';
  }
  const error = new Error(moduleNotFoundError);
  error.code = 'MODULE_NOT_FOUND';
  // todo - error.path = ?;
  error.requestPath = parentFilename;
  error.bazelTarget = TARGET;
  error.failedResolutions = failedResolutions;

  throw error;
}