async function processModule()

in packages/metro/src/DeltaBundler/traverseDependencies.js [193:280]


async function processModule<T>(
  path: string,
  graph: Graph<T>,
  delta: Delta,
  options: InternalOptions<T>,
): Promise<Module<T>> {
  // Transform the file via the given option.
  const result = await options.transform(path);

  // Get the absolute path of all sub-dependencies (some of them could have been
  // moved but maintain the same relative path).
  const currentDependencies = resolveDependencies(
    path,
    result.dependencies,
    options,
  );

  const previousModule = graph.dependencies.get(path) || {
    inverseDependencies: delta.inverseDependencies.get(path) || new Set(),
    path,
  };
  const previousDependencies = previousModule.dependencies || new Map();

  // Update the module information.
  const module = {
    ...previousModule,
    dependencies: new Map(),
    getSource: result.getSource,
    output: result.output,
  };
  graph.dependencies.set(module.path, module);

  for (const [relativePath, dependency] of currentDependencies) {
    module.dependencies.set(relativePath, dependency);
  }

  Array.from(previousDependencies.entries())
    .filter(
      ([relativePath, dependency]) =>
        !currentDependencies.has(relativePath) ||
        nullthrows(currentDependencies.get(relativePath)).absolutePath !==
          dependency.absolutePath,
    )
    .forEach(([relativePath, dependency]) =>
      removeDependency(
        module,
        dependency.absolutePath,
        graph,
        delta,
        new Set(),
      ),
    );

  // Check all the module dependencies and start traversing the tree from each
  // added and removed dependency, to get all the modules that have to be added
  // and removed from the dependency graph.
  const promises = [];

  for (const [relativePath, dependency] of currentDependencies) {
    if (!options.shallow) {
      if (
        options.experimentalImportBundleSupport &&
        dependency.data.data.asyncType != null
      ) {
        graph.importBundleNames.add(dependency.absolutePath);
      } else if (
        !previousDependencies.has(relativePath) ||
        nullthrows(previousDependencies.get(relativePath)).absolutePath !==
          dependency.absolutePath
      ) {
        promises.push(
          addDependency(module, dependency.absolutePath, graph, delta, options),
        );
      }
    }
  }

  try {
    await Promise.all(promises);
  } catch (err) {
    // If there is an error, restore the previous dependency list.
    // This ensures we don't skip over them during the next traversal attempt.
    // $FlowFixMe[cannot-write]
    module.dependencies = previousDependencies;
    throw err;
  }
  return module;
}