facebook / create-react-app

Set up a modern web app by running one command.
https://create-react-app.dev
MIT License
102.71k stars 26.84k forks source link

Don't compile async/await in node_modules in development #7383

Open firatoezcan opened 5 years ago

firatoezcan commented 5 years ago

Is your proposal related to a problem?

The problem that I have with the preset transpiling async/await is that debugging gets really hard. With the uprising of hooks a lot of libraries are abstracting a lot of functionality away which is great but this also means that if they expose functionality as a HOF that debugging and reading these is near impossible in development. It's not that I am bad at debugging either but more that the function get's compiled down more than it needs to be apart from reaching through another few layers for the generator part and the syntax gets completely fumbled up.

image

Code before transpiling

  const handleSubmit = (callback) => async (e) => {
    if (e && !nativeValidation) {
      e.preventDefault();
      e.persist();
    }
    let fieldErrors;
    let fieldValues;
    let firstFocusError = true;
    const fields = fieldsRef.current;
    const currentFieldValues = validationFields ? (validationFields.map(name => fieldsRef.current[name])) : Object.values(fields);
    isSubmittingRef.current = true;
    reRenderForm({});

    const { errors, values } = await currentFieldValues.reduce(
      async (previous, field) => {
        if (!field) return previous;
        const resolvedPrevious = await previous;
        const ref = field.ref
        const name = field.ref
        if (!fields[name]) return Promise.resolve(resolvedPrevious);

        const fieldError = await validateField(field, fields, nativeValidation);

        if (fieldError[name]) {
          if (submitFocusError && firstFocusError && ref.focus) {
            ref.focus();
            firstFocusError = false;
          }
          resolvedPrevious.errors = {
            ...(resolvedPrevious.errors || {}),
            ...fieldError,
          };
          return Promise.resolve(resolvedPrevious);
        }

        resolvedPrevious.values[name] = getFieldValue(fields, ref);
        return Promise.resolve(resolvedPrevious);
      },
      Promise.resolve({ errors, values, }),
    );

    fieldErrors = errors;
    fieldValues = values;

    if (isEmptyObject(fieldErrors)) {
      await callback(combineFieldValues(fieldValues), e);
      errorsRef.current = {};
    } else {
      errorsRef.current = fieldErrors as any;
    }
    if (isUnMount.current) return;
    isSubmittedRef.current = true;
    submitCountRef.current += 1;
    isSubmittingRef.current = false;
    reRenderForm({});
  };

Code after transpiling

var handleSubmit = function handleSubmit(callback) {
    return (
      /*#__PURE__*/
      function () {
        var _ref26 = _asyncToGenerator(
        /*#__PURE__*/
        _regeneratorRuntime.mark(function _callee5(e) {
          var fieldErrors, fieldValues, fields, currentFieldValues, _ref27, errors, values;

          return _regeneratorRuntime.wrap(function _callee5$(_context5) {
            while (1) {
              switch (_context5.prev = _context5.next) {
                case 0:
                  if (e) {
                    e.preventDefault();
                    e.persist();
                  }

                  fields = fieldsRef.current;
                  currentFieldValues = Object.values(fields);
                  isSubmittingRef.current = true;
                  reRenderForm({});

                  if (!validationSchema) {
                    _context5.next = 12;
                    break;
                  }

                  fieldValues = getFieldsValues(fields);
                  _context5.next = 9;
                  return validateWithSchema(validationSchema, fieldValues);

                case 9:
                  fieldErrors = _context5.sent;
                  _context5.next = 19;
                  break;

                case 12:
                  _context5.next = 14;
                  return currentFieldValues.reduce(
                  /*#__PURE__*/
                  function () {
                    var _ref28 = _asyncToGenerator(
                    /*#__PURE__*/
                    _regeneratorRuntime.mark(function _callee4(previous, field) {
                      var resolvedPrevious, ref, name, fieldError;
                      return _regeneratorRuntime.wrap(function _callee4$(_context4) {
                        while (1) {
                          switch (_context4.prev = _context4.next) {
                            case 0:
                              _context4.next = 2;
                              return previous;

                            case 2:
                              resolvedPrevious = _context4.sent;
                              ref = field.ref, name = field.ref.name;

                              if (fields[name]) {
                                _context4.next = 6;
                                break;
                              }

                              return _context4.abrupt("return", Promise.resolve(resolvedPrevious));

                            case 6:
                              _context4.next = 8;
                              return validateField(field, fields);

                            case 8:
                              fieldError = _context4.sent;

                              if (!fieldError[name]) {
                                _context4.next = 12;
                                break;
                              }

                              resolvedPrevious.errors = Object.assign({}, resolvedPrevious.errors || {}, fieldError);
                              return _context4.abrupt("return", Promise.resolve(resolvedPrevious));

                            case 12:
                              // @ts-ignore
                              resolvedPrevious.values[name] = getFieldValue(fields, ref);
                              return _context4.abrupt("return", Promise.resolve(resolvedPrevious));

                            case 14:
                            case "end":
                              return _context4.stop();
                          }
                        }
                      }, _callee4);
                    }));

                    return function (_x10, _x11) {
                      return _ref28.apply(this, arguments);
                    };
                  }(), Promise.resolve({
                    errors: {},
                    values: {}
                  }));

                case 14:
                  _ref27 = _context5.sent;
                  errors = _ref27.errors;
                  values = _ref27.values;
                  fieldErrors = Object.assign({}, errors, filterUndefinedErrors(errorsRef.current));
                  fieldValues = values;

                case 19:
                  isSubmittedRef.current = true;
                  submitCountRef.current += 1;
                  isSubmittingRef.current = false;

                  if (isEmptyObject(fieldErrors)) {
                    callback(combineFieldValues(fieldValues), e);
                  } else {
                    errorsRef.current = fieldErrors;
                    reRenderForm({});
                  }

                case 23:
                case "end":
                  return _context5.stop();
              }
            }
          }, _callee5);
        }));

        return function (_x9) {
          return _ref26.apply(this, arguments);
        };
      }()
    );
  };

Disable transpiling of node_modules in development. Is there a reason for that?

Additional context

The library in use is react-hook-form and source-map support is enabled (the after code is the source mapped version)

stevenroussey-privicy commented 5 years ago

Would be great if this paid attention to browserslist for either production or development.