parse = (args = [], defaultValues = {}, ...configObjects) => {
  // save node-specific args for special handling.
  // 1. when these args have a "=" they should be considered to have values
  // 2. if they don't, they are just boolean flags
  // 3. to avoid explicitly defining the set of them, we tell yargs-parser they
  //    are ALL boolean flags.
  // 4. we can then reapply the values after yargs-parser is done.
  const allArgs = Array.isArray(args) ? args : args.split(' ');
  const nodeArgs = allArgs.reduce((acc, arg) => {
    const pair = arg.split('=');
    let flag = pair[0];
    if (isNodeFlag(flag, false)) {
      flag = flag.replace(/^--?/, '');
      return acc.concat([[flag, arg.includes('=') ? pair[1] : true]]);
    }
    return acc;
  }, []);

  const result = yargsParser.detailed(args, {
    configuration,
    configObjects,
    default: defaultValues,
    coerce: coerceOpts,
    narg: nargOpts,
    alias: aliases,
    string: types.string,
    array: types.array,
    number: types.number,
    boolean: types.boolean.concat(nodeArgs.map(pair => pair[0]))
  });
  if (result.error) {
    console.error(pc.red(`Error: ${result.error.message}`));
    process.exit(1);
  }

  const numericPositionalArg = result.argv._.find(arg => isNumeric(arg));
  if (numericPositionalArg) {
    createErrorForNumericPositionalArg(
      numericPositionalArg,
      allArgs,
      result.argv
    );
  }

  // reapply "=" arg values from above
  nodeArgs.forEach(([key, value]) => {
    result.argv[key] = value;
  });

  return result.argv;
}
Wrapper around `yargs-parser` which applies our settings
@param {string|string[]} args - Arguments to parse
@param {Object} defaultValues - Default values of mocharc.json
@param  {...Object} configObjects - `configObjects` for yargs-parser
@private
@ignore