解析错误:意外的令牌< Reactjs

时间:2016-11-21 05:13:39

标签: reactjs webpack

error message: 

ERROR in ./src/index.jsx

C:\Users\Steven\Desktop\Social-Wall\src\index.jsx
  26:7  error  Parsing error: Unexpected token <

✖ 1 problem (1 error, 0 warnings)

运行webpack dev服务器时出现此错误。我试图通过plunker运行它,它工作。我只是无法弄清楚这里的问题是什么。我尝试用返回组件包装,但它也没有工作。

so line 26 is the <img> here:

render: function() {
    var img = (this.props.showImage) ? this.props.src : this.props.loader;
    return (

      <img src={img} alt={this.props.alt} />
    );
  }
and this is my index.jsx file:

// Product list item image
var ProductImage = React.createClass({
  getDefaultProps: function() {
    return {
      loader: '../img/loader.gif',
      showImage: false
    };
  },

  componentDidUpdate: function(prevProps) {
    if (! this.props.showImages && prevProps.viewport) {
      this.updatePosition();
    }
  },

  updatePosition: function() {
    var el = this.getDOMNode();
    this.props.updateImagePosition(el.offsetTop, el.offsetHeight);
  },

  render: function() {
    var img = (this.props.showImage) ? this.props.src : this.props.loader;
    return (
      <img src={img} alt={this.props.alt} />
    );
  }
});

// Product list item
var Product = React.createClass({
  getInitialState: function() {
    return {
      showImage: false
    };
  },

  getDefaultProps: function() {
    return {
      showImage: false
    };
  },

  componentWillMount: function() {
    // allow image display override
    if (this.props.showImage) {
      setShowImage(true);
    }
  },

  updateImagePosition: function(top, height) {
    // image is already displayed, no need to check anything
    if (this.state.showImage) {
      return;
    }

    // update showImage state if component element is in the viewport
    var min = this.props.viewport.top;
    var max = this.props.viewport.top + this.props.viewport.height;

    if ((min <= (top + height) && top <= (max - 300))) {
      this.setShowImage(true);
    }
  },

  setShowImage: function(show) {
    this.setState({
      showImage: !!(show)
    });
  },

  render: function() {
    return (
      <div>
        <h2>{this.props.title}</h2>
        <div>
          <ProductImage src={this.props.image} alt={this.props.title} viewport={this.props.viewport} showImage={this.state.showImage}
            updateImagePosition={this.updateImagePosition} />
        </div>
      </div>
    );
  }
});

// Product list
var ProductList = React.createClass({
  getInitialState: function() {
    return {
      viewport: {
        top: 0,
        height: 0
      }
    };
  },

  componentDidMount: function() {
    window.addEventListener('scroll', this.updateViewport, false);
    window.addEventListener('resize', this.updateViewport, false);
    this.updateViewport();
  },

  componentWillUnmount: function() {
    window.removeEventListener('scroll', this.updateViewport);
    window.removeEventListener('resize', this.updateViewport);
  },

  updateViewport: function() {
    // TODO: debounce this call
    this.setState({
      viewport: {
        top: window.pageYOffset,
        height: window.innerHeight
      }
    });
  },

  render: function() {
    var self = this;

    var itemViews = this.props.items.map(function(item) {
      return <Product title={item.title} image={item.image} viewport={self.state.viewport} />
    });

    return (
      <div>
        <h1>Items</h1>
        {itemViews}
      </div>
    );
  }
});

var items = [
  { title: 'Kitten 1', image: 'http://placekitten.com/311/313' },
  { title: 'Kitten 2', image: 'http://placekitten.com/302/302' },
  { title: 'Kitten 3', image: 'http://placekitten.com/303/303' },
  { title: 'Kitten 4', image: 'http://placekitten.com/304/304' },
  { title: 'Kitten 5', image: 'http://placekitten.com/305/305' },
  { title: 'Kitten 6', image: 'http://placekitten.com/306/306' },
  { title: 'Kitten 7', image: 'http://placekitten.com/307/307' },
  { title: 'Kitten 8', image: 'http://placekitten.com/308/308' },
  { title: 'Kitten 9', image: 'http://placekitten.com/310/310' },
  { title: 'Kitten 10', image: 'http://placekitten.com/311/311' }
];

var el = document.getElementById('app');
ReactDOM.render(<ProductList items={items} />, el);

这是我的webpack.config.js

const path = require('path');

const PATHS = {
    dist: path.resolve(__dirname, 'dist'),
    src: path.resolve(__dirname, 'src'),
    css: path.resolve(__dirname, 'dist/css')
};

module.exports = {
    entry: [
        'webpack-dev-server/client?http://0.0.0.0:8080',
        'webpack/hot/only-dev-server',
        PATHS.src
        ],
    output: {
        path: PATHS.dist,
        filename: 'bundle.js'
    },
    module: {
        preLoaders: [
            {
                test: /\.jsx?$/,
                include: PATHS.src,
                loader: 'eslint-loader'
            }
        ],
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loader: 'babel'
            },
            {
                test: /\.css?$/,
                include: PATHS.src,
                loaders: ['style', 'css']
            }
        ]
    },
    resolve: {
        modulesDirectories: [
            'node_modules',
            'src'
        ],
        extensions: ['', '.js', '.jsx']
    },
    devServer: {
        contentBase: PATHS.dist,
        inline: true,
        stats: 'errors-only',
        hot: true
    },
    eslint: {
        configFile: './.eslintrc'
    }
};

这是我的.babelrc

{
  "presets": [
    "react",
    "es2015"
  ],
  "plugins": ["react-hot-loader/babel"]
}
非常感谢!

1 个答案:

答案 0 :(得分:0)

安装babel-latest预设

npm i babel-preset-latest --save-dev

并将其添加到您的.babelrc

{
  "presets": [
    "latest",
    "resct"
  ],
  "plugins": ["react-hot-loader/babel"]
}

希望这有帮助!