Repository: facebook/jest
File: packages/jest-haste-map/src/index.ts (TypeScript)

Code before:
 *
 *  2. crawl the file system.
 *     * empty cache: crawl the entire file system.
 *     * cache available:
 *       * if watchman is available: get file system delta changes.
 *       * if watchman is unavailable: crawl the entire file system.
 *     * build metadata objects for every file. This builds the `files` part of
 *       the `HasteMap`.
 *
 *  3. parse and extract metadata from changed files.
 *     * this is done in parallel over worker processes to improve performance.
 *     * the worst case is to parse all files.
 *     * the best case is no file system access and retrieving all data from
 *       the cache.
 *     * the average case is a small number of changed files.
 *
 *  4. serialize the new `HasteMap` in a cache file.
 *     Worker processes can directly access the cache through `HasteMap.read()`.
 *
 */
class HasteMap extends EventEmitter implements IHasteMap {
  private _buildPromise: Promise<InternalHasteMapObject> | null = null;
  private _cachePath = '';
  private _changeInterval?: ReturnType<typeof setInterval>;
  private readonly _console: Console;
  private _isWatchmanInstalledPromise: Promise<boolean> | null = null;
  private readonly _options: InternalOptions;
  private _watchers: Array<Watcher> = [];
  private _worker: JestWorkerFarm<HasteWorker> | HasteWorker | null = null;

  static getStatic(config: Config.ProjectConfig): HasteMapStatic {
    if (config.haste.hasteMapModulePath) {
      return require(config.haste.hasteMapModulePath);
    }
    return HasteMap;
  }

  static async create(options: Options): Promise<IHasteMap> {
    if (options.hasteMapModulePath) {
      const CustomHasteMap = require(options.hasteMapModulePath);
      return new CustomHasteMap(options);
    }
    const hasteMap = new HasteMap(options);

    await hasteMap.setupCachePath(options);

    return hasteMap;
  }

  private constructor(options: Options) {
    super();

Review comment (suggestion):
this made the check happens once _per project_, while we now do it once per module scope (i.e. once per worker/thread/process)

Code after:
 * The HasteMap is created as follows:
 *  1. read data from the cache or create an empty structure.
 *
 *  2. crawl the file system.
 *     * empty cache: crawl the entire file system.
 *     * cache available:
 *       * if watchman is available: get file system delta changes.
 *       * if watchman is unavailable: crawl the entire file system.
 *     * build metadata objects for every file. This builds the `files` part of
 *       the `HasteMap`.
 *
 *  3. parse and extract metadata from changed files.
 *     * this is done in parallel over worker processes to improve performance.
 *     * the worst case is to parse all files.
 *     * the best case is no file system access and retrieving all data from
 *       the cache.
 *     * the average case is a small number of changed files.
 *
 *  4. serialize the new `HasteMap` in a cache file.
 *     Worker processes can directly access the cache through `HasteMap.read()`.
 *
 */
class HasteMap extends EventEmitter implements IHasteMap {
  private _buildPromise: Promise<InternalHasteMapObject> | null = null;
  private _cachePath = '';
  private _changeInterval?: ReturnType<typeof setInterval>;
  private readonly _console: Console;
  private readonly _options: InternalOptions;
  private _watchers: Array<Watcher> = [];
  private _worker: JestWorkerFarm<HasteWorker> | HasteWorker | null = null;

  static getStatic(config: Config.ProjectConfig): HasteMapStatic {
    if (config.haste.hasteMapModulePath) {
      return require(config.haste.hasteMapModulePath);
    }
    return HasteMap;
  }

  static async create(options: Options): Promise<IHasteMap> {
    if (options.hasteMapModulePath) {
      const CustomHasteMap = require(options.hasteMapModulePath);
      return new CustomHasteMap(options);
    }
    const hasteMap = new HasteMap(options);

    await hasteMap.setupCachePath(options);

    return hasteMap;
  }

  private constructor(options: Options) {