async function executeScript(cmd, opts, args = []) {
    assertSupportedNodeVersion();

    const env = getEffectiveEnv(opts);

    // We MUST use a relative path because the files
    // created by npm dont correctly handle paths
    // containg spaces on Windows (yarn does)
    const configPath = path.relative(
        process.cwd(),
        require.resolve('../setup/webpack.config.js')
    );

    const script = [
        commandScript(cmd, opts),
        `--config="${configPath}"`,
        ...quoteArgs(args)
    ].join(' ');

    const scriptEnv = {
        NODE_ENV: env,
        MIX_FILE: opts.mixConfig
    };

    const nodeEnv = requiresLegacyOpenSSLProvider()
        ? { NODE_OPTIONS: process.env.NODE_OPTIONS || `--openssl-legacy-provider` }
        : {};

    if (isTesting()) {
        process.stdout.write(
            JSON.stringify({
                script,
                env: scriptEnv
            })
        );

        return;
    }

    function restart() {
        let child = spawn(script, {
            stdio: 'inherit',
            shell: true,
            env: {
                ...process.env,
                ...nodeEnv,
                ...scriptEnv
            }
        });

        let shouldOverwriteExitCode = true;

        child.on('exit', (code, signal) => {
            // Note adapted from cross-env:
            // https://github.com/kentcdodds/cross-env/blob/3edefc7b450fe273655664f902fd03d9712177fe/src/index.js#L30-L31

            // The process exit code can be null when killed by the OS (like an out of memory error) or sometimes by node
            // SIGINT means the _user_ pressed Ctrl-C to interrupt the process execution
            // Return the appropriate error code in that case
            if (code === null) {
                code = signal === 'SIGINT' ? 130 : 1;
            }

            if (shouldOverwriteExitCode) {
                process.exitCode = code;
            }
        });

        process.on('SIGINT', () => {
            shouldOverwriteExitCode = false;
            child.kill('SIGINT');
        });

        process.on('SIGTERM', () => {
            shouldOverwriteExitCode = false;
            child.kill('SIGTERM');
        });
    }

    restart();
}
Execute the script.

@param {"build"|"watch"} cmd
@param {{[key: string]: any}} opts
@param {string[]} args