Использование async await в ReactJS с Babel приводит к ошибке: неожиданный токен

Хотел использовать ES8 async/await для своего проекта. Недавно использовал его в ReactNative с Expo, поэтому не ожидал никаких проблем с ReactJS. Хотя приложение не может быть собрано сейчас... Вот ошибка, которую я получаю:

    Syntax error: C:/projects/project1/src/containers/OfferOverview.js: Unexpected token (84:40)
      83 |
    > 84 |   initialGetProduct = async (productId) => {
         |                                         ^
      85 |     const { dispatch } = this.props;
      86 |     await dispatch(resetOfferStateAction());
      87 |     dispatch(getProductAction(productId));

Это компонент, я вырезал большую часть его содержимого, так как сомневаюсь, что они могут быть связаны с проблемой:

export class OfferOverview extends Component {
  componentWillMount() {
    this.initialGetProduct(this.props.location.query.product_id);
  }

  // same error will be using async initialGetProduct() {
  initialGetProduct = async (productId) => {
    const { dispatch } = this.props;
    await dispatch(resetOfferStateAction());
    dispatch(getProductAction(productId));
    this.selectProduct(productId);
  }

  render() { ... }
}

Я попытался установить предустановку es2017 в конфигурации babel, так же, как с помощью плагина «transform-async-to-generator». Это то, что у меня есть в файле .babelrc:

{
  "presets": [
    "es2017",
    "react",
    "stage-0"
  ],
  "plugins": [
    "react-hot-loader/babel",
    "transform-async-to-generator",
    "transform-class-properties",
    ["import", { "libraryName": "antd", "style": "css" }]
  ]
}

Это моя конфигурация eslint. В обсуждении eslint они сказали, что это больше проблема babel-eslint, хотя я добавил parserOptions ecmaVersion = 2017:

module.exports = {
  root: true,

  parser: 'babel-eslint',

  // import plugin is termporarily disabled, scroll below to see why
  plugins: [/*'import', */'flowtype', 'jsx-a11y', 'react'],

  env: {
    browser: true,
    commonjs: true,
    node: true
  },

  parserOptions: {
    ecmaVersion: 2017,
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
      generators: true,
      experimentalObjectRestSpread: true
    }
  },

  settings: {
    'import/ignore': [
      'node_modules',
      '\\.(json|css|jpg|png|gif|eot|svg|ttf|woff|woff2|mp4|webm)$',
    ],
    'import/extensions': ['.js'],
    'import/resolver': {
      node: {
        extensions: ['.js', '.json']
      }
    }
  },

  rules: { ... }
};

и упакуйте json-зависимости:

"devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.13.2",
    "babel-eslint": "^6.1.2",
    "babel-plugin-transform-async-to-generator": "^6.24.1",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-runtime": "^6.12.0",
    "babel-polyfill": "^6.26.0",
    "babel-preset-es2015": "^6.13.2",
    "babel-preset-es2016": "^6.24.1",
    "babel-preset-es2017": "^6.24.1",
    "babel-preset-react": "^6.11.1",
    "babel-preset-stage-0": "^6.24.1",
    "coveralls": "^2.11.12",
    "eslint": "^3.2.2",
    "eslint-config-airbnb": "^10.0.0",
    "eslint-plugin-react": "^6.0.0",
    "ignore-styles": "^4.0.0",
    "istanbul": "^1.0.0-alpha.2",
    "mocha": "^3.0.2",
    "nock": "^8.0.0",
    "react-addons-test-utils": "^15.3.0",
    "react-scripts": "0.2.1",
    "redux-mock-store": "^1.1.2",
    "redux-saga-devtools": "^0.1.2"
},
"dependencies": {
    "babel-polyfill": "^6.26.0",
    "enzyme": "^2.4.1",
    "eslint-plugin-flowtype": "^2.39.1",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "expect": "latest",
    "isomorphic-fetch": "^2.2.1",
    "jsdom": "^9.9.1",
    "lodash": "^4.17.4",
    "nuka-carousel": "^2.3.0",
    "pushstate-server": "latest",
    "react": "^15.2.1",
    "react-dom": "^15.2.1",
    "react-redux": "^4.4.5",
    "react-router": "^2.6.0",
    "react-router-redux": "^4.0.8",
    "react-sidebar": "^2.3.2",
    "redux": "^3.6.0",
    "redux-logger": "3.0.1",
    "redux-saga": "^0.14.3"
},

Был бы признателен за любую подсказку, что может быть не так?


person Kirill Stiopin    schedule 28.11.2017    source источник
comment
Я считаю, что вам нужны transform-class-properties Плагин Babel   -  person Wing    schedule 28.11.2017
comment
добавил его в зависимости от разработчиков и в плагины babelrc, но, к сожалению, это не помогло   -  person Kirill Stiopin    schedule 28.11.2017
comment
Какова точная ошибка с async initialGetProduct()? Точно такой же ошибки быть не может, так как стрелки нет.   -  person ReyHaynes    schedule 28.11.2017
comment
ошибка такая же, хотя она указывает на другое место строки (потому что стрелки больше нет) prntscr.com/hgge4i   -  person Kirill Stiopin    schedule 28.11.2017
comment
добавили его в зависимости для разработчиков и в плагины babelrc, но, к сожалению, это не помогло — вы уверены, что правильно настроили .babelrc? В вашем списке плагинов есть "babel-plugin-transform-class-properties", однако это должно быть "transform-class-properties".   -  person Wing    schedule 29.11.2017
comment
› Похоже, что async/await доступен только в babel-preset-stage-3 stackoverflow.com/a/35758396/213550, и у вас есть stage-2 в зависимости   -  person VMAtm    schedule 29.11.2017
comment
@VMAtm: использование stage-2 будет включать пресеты для stage-3 и stage-4 (ссылка) - пресет этапа будет включать все этапы больше, чем он сам. Также у OP есть предустановка ES2017, которая включает в себя необходимые им функции, поскольку включает плагин transform-async-to-generator Babel (ссылка ). Однако ваш комментарий привел к этому важному примечанию для OP: stage-0 настроен как предустановка, однако зависимости разработчиков имеют stage-2 — это несоответствие зависимостей необходимо устранить.   -  person Wing    schedule 29.11.2017
comment
Также можно попробовать const initialGetProduct = async (productId) => { ...   -  person VMAtm    schedule 29.11.2017
comment
@wing: исправлено имя плагина в .babelrc на "transform-class-properties" и установлено stage-0 вместо stage-2, но все равно возникает та же ошибка; @VMAtm: пытался использовать const, но это тоже не сработало   -  person Kirill Stiopin    schedule 29.11.2017
comment
Забыл добавить к своему предыдущему комментарию. Включение предустановки react-app означает, что вы можете удалить предустановки esXXXX, поскольку они покрываются предустановкой env; вы также можете удалить transform-class-properties, так как он входит в пресет react-app (а также transform-async-to-generator и transform-runtime); вы можете удалить предустановку stage-0, если вы используете предустановку stage-X только для transform-class-properties, поскольку она уже включена, как упоминалось ранее.   -  person Wing    schedule 29.11.2017


Ответы (2)


Я не запускал код, но вы неправильно объявляете функцию initialGetProduct. Должно быть

async initialGetProduct() {...
person xavdid    schedule 28.11.2017
comment
а что, если мне нужна функция асинхронной стрелки? И ошибка остается прежней. - person Kirill Stiopin; 28.11.2017

Так что проблема была немного в другой области, чем я думал. Я использую реагирующие сценарии для запуска своего приложения, и моя ошибка заключалась в том, что я думал, что конфигурация, которая у меня есть в моем проекте (я не тот, кто начал ее изначально), как-то использовалась. Но это не так. Поэтому все, что мне нужно было сделать, чтобы это заработало, — это обновить версию реактивных скриптов. Была 0.2.1, а теперь ^1.0.17, неудивительно, что она не могла работать с ES8... Извините за неудобства всем, кто пытался помочь, всем спасибо, ваши советы меня многому научили. В конфигурации реактивных скриптов у них есть только это для Babel:

          // Process JS with Babel.
          {
            test: /\.(js|jsx|mjs)$/,
            include: paths.appSrc,
            loader: require.resolve('babel-loader'),
            options: {
              // @remove-on-eject-begin
              babelrc: false,
              presets: [require.resolve('babel-preset-react-app')],
              // @remove-on-eject-end
              // This is a feature of `babel-loader` for webpack (not Babel itself).
              // It enables caching results in ./node_modules/.cache/babel-loader/
              // directory for faster rebuilds.
              cacheDirectory: true,
            },
          },
person Kirill Stiopin    schedule 29.11.2017