docs: function compileJsAsync(
      projectOptions, buildOptions, outDirs, cssRenamingFile, jsModules) {
    var isDebug = (buildOptions.type == common.DEBUG);
  
    // Standard options:
    var jsCompilerArgs = [
      '-jar',
      JS_COMPILER_PATH,
      '--compilation_level',
      isDebug ? 'SIMPLE_OPTIMIZATIONS' : 'ADVANCED_OPTIMIZATIONS',
      '--module_output_path_prefix',
      outDirs.tmp
    ];
  
    // Debug- and release-specific options:
    if (isDebug) {
      jsCompilerArgs.push('--formatting');
      jsCompilerArgs.push('PRETTY_PRINT');
    } else {
      jsCompilerArgs.push('--define');
      jsCompilerArgs.push('goog.DEBUG=false');
    }
  
    if (projectOptions.jsWarningsWhitelistFile) {
      jsCompilerArgs.push('--warnings_whitelist_file');
      jsCompilerArgs.push(projectOptions.jsWarningsWhitelistFile);
    }
  
    projectOptions.jsExterns.forEach(function(externsFile) {
      jsCompilerArgs.push('--externs');
      jsCompilerArgs.push(externsFile);
    });
  
    // TODO: Consider support for --process_jquery_primitives.
  
    // No-op if there is no JS that needs to be compiled.
    var modulesToCompile = getModulesToCompile(jsModules, cssRenamingFile);
    if (modulesToCompile.length == 0) {
      return kew.resolve(null);
    }
  
    // List input files for each module with JS files to be compiled.
    modulesToCompile.forEach(function(jsModule) {
      jsCompilerArgs.push('--module');
      jsCompilerArgs.push(jsModule.name + ':' +
          jsModule.compiledInputFiles.length + ':' +
          jsModule.alwaysLoadedAfterModules.join(','));
  
      jsModule.compiledInputFiles.forEach(function(inputFile) {
        jsCompilerArgs.push('--js');
        jsCompilerArgs.push(inputFile);
      });
    });
  
    // Launch JS compiler in a child process.
    var stderrBehavior = buildOptions.suppressOutput ? 'ignore' : process.stderr;
    var jsCompilation = child_process.spawn(buildOptions.javaCommand,
        jsCompilerArgs, {stdio: ['ignore', 'pipe', stderrBehavior]});
  
    var promise = kew.defer();
    jsCompilation.on('close', function(exitCode) {
      if (exitCode == common.EXIT_SUCCESS) {
        promise.resolve(null);
      } else {
        promise.reject(new Error('Had errors compiling JavaScript'));
      }
    });
    return promise;
  }