exports.createResolveFn = function()

in packages/metro/src/ModuleGraph/node-haste/node-haste.js [113:188]


exports.createResolveFn = function (options: ResolveOptions): ResolveFn {
  const {
    assetExts,
    assetResolutions,
    extraNodeModules,
    transformedFiles,
    sourceExts,
    platform,
    platforms,
  } = options;
  const files = Object.keys(transformedFiles);
  function getTransformedFile(path: string): TransformedCodeFile {
    const result = transformedFiles[path];
    if (!result) {
      throw new Error(`"${path} does not exist`);
    }
    return result;
  }

  const hasteFS = new HasteFS(files);
  const moduleCache = new ModuleCache(
    (filePath: string) => hasteFS.closest(filePath, 'package.json'),
    getTransformedFile,
  );

  const assetExtensions = new Set(assetExts.map(asset => '.' + asset));
  const isAssetFile = file => assetExtensions.has(path.extname(file));

  const moduleResolver = new ModuleResolver({
    dirExists: (filePath: string): boolean => hasteFS.dirExists(filePath),
    disableHierarchicalLookup: options.disableHierarchicalLookup,
    doesFileExist: (filePath: string): boolean => hasteFS.exists(filePath),
    emptyModulePath: options.emptyModulePath,
    extraNodeModules,
    isAssetFile,
    mainFields: options.mainFields,
    // $FlowFixMe -- error revealed by types-first codemod
    moduleCache,
    moduleMap: new ModuleMap({
      duplicates: new Map(),
      map: createModuleMap({files, moduleCache, sourceExts, platforms}),
      mocks: new Map(),
      rootDir: '',
    }),
    nodeModulesPaths: options.nodeModulesPaths,
    preferNativePlatform: true,
    projectRoot: '',
    resolveAsset: (
      dirPath: string,
      assetName: string,
      extension: string,
    ): ?$ReadOnlyArray<string> => {
      const basePath = dirPath + path.sep + assetName;
      const assets = [
        basePath + extension,
        ...assetResolutions.map(
          resolution => basePath + '@' + resolution + 'x' + extension,
        ),
      ].filter(candidate => hasteFS.exists(candidate));
      return assets.length ? assets : null;
    },
    resolveRequest: options.resolveRequest,
    sourceExts,
  });

  return (id: string, sourcePath: ?string) => {
    const from =
      sourcePath != null
        ? new Module(sourcePath, moduleCache, getTransformedFile(sourcePath))
        : NULL_MODULE;
    const allowHaste = !isNodeModules(from.path);
    // $FlowFixMe -- error revealed by types-first codemod
    return moduleResolver.resolveDependency(from, id, allowHaste, platform)
      .path;
  };
};