text: // @flow
  import path from 'path';
  import sourceMapSupport from 'source-map-support';
  import MemoryFileSystem from 'memory-fs';
  import registerRequireHook from '../../util/registerRequireHook';
  import { ensureAbsolutePath } from '../../util/paths';
  import type { Compiler, Stats } from '../types';
  
  export default function registerInMemoryCompiler(compiler: Compiler) {
    // register memory fs to webpack
    const memoryFs = new MemoryFileSystem();
    compiler.outputFileSystem = memoryFs; // eslint-disable-line no-param-reassign
  
    // build asset map to allow fast checks for file existence
    const assetMap = new Map();
    compiler.hooks.done.tap('mochapack', (stats: Stats) => {
      assetMap.clear();
  
      if (!stats.hasErrors()) {
        Object.keys(stats.compilation.assets)
          .forEach((assetPath) => assetMap.set(ensureAbsolutePath(assetPath, compiler.options.output.path), true));
      }
    });
  
    // provide file reader to read from memory fs
    let readFile = (filePath) => {
      if (assetMap.has(filePath)) {
        try {
          const code = memoryFs.readFileSync(filePath, 'utf8');
          return code;
        } catch (e) {
          return null;
        }
      }
      return null;
    };
  
    // module resolver for require calls from memory fs
    const resolveFile = (filePath, requireCaller) => {
      // try to read file from memory-fs as it is
      let code = readFile(filePath);
      let resolvedPath = filePath;
  
      if (code === null && requireCaller != null) {
        const { filename } = requireCaller;
        if (filename != null) {
          // if that didn't work, resolve the file relative to it's parent
          resolvedPath = path.resolve(path.dirname(filename), filePath);
          code = readFile(resolvedPath);
        }
      }
      return { path: code !== null ? resolvedPath : null, source: code };
    };
  
    // install require hook to be able to require webpack bundles from memory
    const unmountHook = registerRequireHook('.js', resolveFile);
  
    // install source map support to read source map from memory
    sourceMapSupport.install({
      emptyCacheBetweenOperations: true,
      handleUncaughtExceptions: false,
      environment: 'node',
      retrieveFile: (f) => readFile(f), // wrapper function to fake an unmount function
    });
  
    return function unmount() {
      unmountHook();
      readFile = (filePath) => null; // eslint-disable-line no-unused-vars
    };
  }
  