function runChildCompiler (compiler) {
  return new Promise((resolve, reject) => {
    compiler.compile((err, compilation) => {
      // still allow the parent compiler to track execution of the child:
      compiler.parentCompilation.children.push(compilation);
      if (err) return reject(err);

      // Bubble stat errors up and reject the Promise:
      if (compilation.errors && compilation.errors.length) {
        const errorDetails = compilation.errors.map(error => error.details).join('\n');
        return reject(Error('Child compilation failed:\n' + errorDetails));
      }

      resolve(compilation);
    });
  });
}
Promisified version of compiler.runAsChild() with error hoisting and isolated output/assets.
(runAsChild() merges assets into the parent compilation, we don't want that)