Babel, Webpack и Mobx: TypeError: невозможно прочитать свойство «аутентификация» неопределенного

В процессе интеграции ESLint в MobX с проектом React декораторов я столкнулся с проблемой неопределенности хранилищ.

Я прочитал много сообщений о том, как использовать декораторы с mobx, и есть определенный способ заставить его работать, но в то же время в воздухе витает ощущение, что просто не используйте их, а вместо этого используйте функции-оболочки. декораторы заменить. Я не хотел бы терять удобочитаемость и простоту использования в качестве решения, но в данный момент я не уверен, что еще я могу попробовать, чтобы это работало.

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

Примеры кода, о которых идет речь ниже:

App.jsx

import React, { Component } from 'react';
import { Route, withRouter } from 'react-router-dom';
import { inject, observer } from 'mobx-react';
import LazyRoute from 'lazy-route';
import styles from './styles/app.css';

@withRouter
@inject('store')
@observer
export default class App extends Component {
  constructor(props) {
    super(props);
    this.store = this.props.store; 
  }
  componentDidMount() {
    //here's where the error is triggered, authenticate is a function in the store but it throws undefined
    this.store.appState.authenticate();
  }
  render() {
    return (
      <div className={`container-fluid ${styles.wrapper}`}>
        <Route exact path="/" render={props => <LazyRoute {...props} component={import('./Home')} />} />
        <Route exact path="/profile" render={props => <LazyRoute {...props} component={import('./Profile')} />} />
        <Route exact path="/balance" render={props => <LazyRoute {...props} component={import('./Balance')} />} />
        <Route render={props => <LazyRoute {...props} component={import('./Home')} />} />
      </div>
    );
  }
}

.babelrc

{   "presets": ["react", "es2015", "stage-1"],   "plugins": ["transform-decorators-legacy"] }

зависимости:

"devDependencies": {
"babel": "^6.5.2",
"babel-core": "^6.18.0",
"babel-loader": "^6.2.7",
"babel-plugin-transform-async-to-generator": "^6.16.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-1": "^6.16.0",
"css-loader": "^0.25.0",
"extract-text-webpack-plugin": "^2.0.0-beta.4",
"html-webpack-plugin": "^2.22.0",
"image-webpack-loader": "^2.0.0",
"node-sass": "^3.10.1",
"postcss-loader": "^0.13.0",
"react-hot-loader": "next",
"resolve-url-loader": "^1.6.0",
"rimraf": "^2.5.4",
"sass-loader": "^4.0.2",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"webpack": "^2.4.1",
"webpack-dev-server": "^2.4.5"
  },
  "dependencies": {
    "axios": "^0.15.0",
    "babel-eslint": "^8.0.0",
    "babel-preset-env": "^1.6.0",
    "bootstrap": "^3.3.7",
    "create-react-class": "^15.6.0",
    "eslint": "^3.19.0 || ^4.3.0",
    "eslint-config-airbnb": "^15.1.0",
    "eslint-config-prettier": "^2.5.0",
    "eslint-loader": "^1.9.0",
    "eslint-plugin-import": "^2.7.0",
    "eslint-plugin-jsx-a11y": "^5.1.1",
    "eslint-plugin-prettier": "^2.3.0",
    "eslint-plugin-react": "^7.1.0",
    "faker": "^3.1.0",
    "http-server": "^0.10.0",
    "jquery": "^3.2.1",
    "lazy-route": "^1.0.7",
    "mobx": "^2.5.2",
    "mobx-react": "4.0.0",
    "mobx-react-devtools": "^4.2.6",
    "moment": "^2.18.1",
    "package": "^1.0.1",
    "react": "^15.6.1",
    "react-bootstrap": "latest",
    "react-bootstrap-date-picker": "^5.1.0",
    "react-dom": "^15.6.1",
    "react-loader": "^2.4.2",
    "react-router-dom": "latest",
    "react-stripe-elements": "^0.0.8",
    "rfx-core": "^1.5.3",
    "transform-runtime": "^0.0.0",
    "whatwg-fetch": "^1.0.0"
}

веб-пакет.config.js:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: ['webpack-dev-server/client?http://0.0.0.0:3000', 'babel-polyfill', 'whatwg-fetch', './src/index.jsx'],
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    port: 8000,
    host: 'localhost',
    publicPath: '/',
    historyApiFallback: true,
    disableHostCheck: true,
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
  },
  output: {
    path: path.join(__dirname, 'dist'),
    publicPath: '/',
    filename: 'app.[hash].js',
  },
  devtool: 'eval',
  module: {
    rules: [
      {
        test: /\.js$|jsx?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
      {
        test: /\.scss|css$/,
        use: [
          'style-loader',
          'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
          'postcss-loader',
          'resolve-url-loader',
          'sass-loader?sourceMap',
        ],
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          'file-loader?hash=sha512&digest=hex&name=[hash].[ext]',
          {
            loader: 'image-webpack-loader',
            options: {
              progressive: true,
              optimizationLevel: 7,
              interlaced: false,
              pngquant: {
                quality: '65-90',
                speed: 4,
              },
            },
          },
        ],
      },
      {
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        use: 'url-loader?limit=10000&mimetype=application/font-woff',
      },
      {
        test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        use: 'file-loader',
      },
      {
        enforce: 'pre',
        test: /\.jsx?$/,
        loader: 'eslint-loader',
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new webpack.NamedModulesPlugin(),
    new HtmlWebpackPlugin({ hash: false, template: './index.hbs' }),
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /nb/),
  ],
};

Полное сообщение об ошибке консоли:

Uncaught TypeError: Cannot read property 'authenticate' of undefined
at App.componentDidMount (webpack:///./src/components/App.jsx?:54:26)
at App.target.(anonymous function) (webpack:///./~/mobx-react/index.js?:262:13)
at eval (webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:264:25)
at measureLifeCyclePerf (webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:75:12)
at eval (webpack:///./~/react-dom/lib/ReactCompositeComponent.js?:263:11)
at CallbackQueue.notifyAll (webpack:///./~/react-dom/lib/CallbackQueue.js?:76:22)
at ReactReconcileTransaction.close (webpack:///./~/react-dom/lib/ReactReconcileTransaction.js?:80:26)
at ReactReconcileTransaction.closeAll (webpack:///./~/react-dom/lib/Transaction.js?:209:25)
at ReactReconcileTransaction.perform (webpack:///./~/react-dom/lib/Transaction.js?:156:16)
at batchedMountComponentIntoNode (webpack:///./~/react-dom/lib/ReactMount.js?:126:15)

person Nahuel    schedule 19.09.2017    source источник


Ответы (1)


Я столкнулся с этой проблемой. Это может помочь вам:

1) Создайте файл в корне проекта jsconfig.json, содержащий следующее:

{
  "compilerOptions": {
      "experimentalDecorators": true
  }
}

2) Вы уже установили "babel-plugin-transform-class-properties", но, возможно, не использовали его. Попробуйте добавить 'transform-class-properties' к .babelrc в разделе плагинов сразу после 'transform-decorators-legacy', в моем случае мне помогло. Ваши плагины в .babelrc должны выглядеть так:

plugins: [
       'transform-decorators-legacy',
       'transform-class-properties',
 ]
person Poul Uvarov    schedule 20.09.2017
comment
Я попробовал ваш подход, и, к сожалению, он не решил проблему. Также стоит отметить, что это jsconfig.json, а не jsconfig.js. - person Nahuel; 22.09.2017
comment
все та же ошибка? Да, верно .json, извините, я исправлю свою опечатку. - person Poul Uvarov; 22.09.2017
comment
Если хотите, можете посмотреть мой рабочий пример с mobx и декораторами, сравнить кое-что. Вот ссылка github.com/spiderpoul/react-to-do Или, если у вас есть этот проект на github, вы можете поделиться им, я могу проверить его. - person Poul Uvarov; 22.09.2017
comment
Извините за поздний ответ. Я проверил ваш проект и попытался посмотреть, смогу ли я воспроизвести ваши результаты, но безуспешно. Я вернусь позже и добавлю больше информации, когда у меня будет время, так что это будет полезно по крайней мере для кого-то еще. - person Nahuel; 26.09.2017