javascript - Node+React+Babel+Webpack,意外 token 错误

标签 javascript reactjs webpack

首先,我真的尝试自己修复它,我在这里发现了几个类似的问题,但没有一个对我有帮助。

收到此错误:

ERROR in ./src/components/App.jsx
Module parse failed: D:\JS projects\habr-app\src\components\App.jsx Unexpected token (54:6)
You may need an appropriate loader to handle this file type.
|   render() {
|     return (
|       <div className='App'>
|         <h1>Hello World!</h1>
|         <div>
 @ ./src/client.js 3:0-42
 @ multi (webpack)-dev-server/client?http://0.0.0.0:8050 webpack/hot/dev-server babel-polyfill ./src/client.js

client.js 文件:

import React      from 'react';
import ReactDOM   from 'react-dom';
import App        from './components/App';

ReactDOM.render ("<App />", document.getElementById('react-view'));

App.jsx 中的渲染函数如下所示:

render() {
    return (
      <div className='App'>
        <h1>Hello World!</h1>
        <div>
          <p>Введите Ваше имя:</p>
          <div><input onChange={this.handleNameChange} /></div>
          {this.renderGreetingWidget()}
        </div>
      </div>
    );
  }

webpack.config.js 文件:

global.Promise         = require('bluebird');

var webpack            = require('webpack');
var path               = require('path');
var ExtractTextPlugin  = require('extract-text-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');

var publicPath         = 'http://localhost:8050/public/assets';
var cssName            = process.env.NODE_ENV === 'production' ? 'styles-[hash].css' : 'styles.css';
var jsName             = process.env.NODE_ENV === 'production' ? 'bundle-[hash].js' : 'bundle.js';

var plugins = [
  new webpack.DefinePlugin({
    'process.env': {
      BROWSER:  JSON.stringify(true),
      NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development')
    }
  }),
  new ExtractTextPlugin(cssName)
];

if (process.env.NODE_ENV === 'production') {
  plugins.push(
    new CleanWebpackPlugin([ 'public/assets/' ], {
      root: __dirname,
      verbose: true,
      dry: false
    })
  );
  plugins.push(new webpack.optimize.DedupePlugin());
  plugins.push(new webpack.optimize.OccurenceOrderPlugin());
}

module.exports = {
  entry: ['babel-polyfill', './src/client.js'],
  resolve: {
    extensions:         ['.js', '.jsx']
  },
  plugins: [
     new ExtractTextPlugin("styles.css"),
     new webpack.LoaderOptionsPlugin({
       debug: true,
       options: {
         eslint: { configFile: '.eslintrc' }
       }
     })
  ],
  output: {
    path: `${__dirname}/public/assets/`,
    filename: jsName,
    publicPath
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ],
    loaders: [
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader'})
      },
      {
        test: /\.less$/,
        loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader!less-loader'})
      },
      { test: /\.gif$/, loader: 'url-loader?limit=10000&mimetype=image/gif' },
      { test: /\.jpg$/, loader: 'url-loader?limit=10000&mimetype=image/jpg' },
      { test: /\.png$/, loader: 'url-loader?limit=10000&mimetype=image/png' },
      { test: /\.svg/, loader: 'url-loader?limit=26000&mimetype=image/svg+xml' },
      { test: /\.(woff|woff2|ttf|eot)/, loader: 'url-loader?limit=1' },
      { test: /\.jsx?$/, loaders: ['react-hot-loader', 'babel-loader?presets[]=react,presets[]=es2015'],
                          exclude: [/node_modules/, /public/] , query: {presets: ['es2015', 'react', 'react-hot']} },
      { test: /\.json$/, loader: 'json-loader' },
    ]
  },
  devtool: process.env.NODE_ENV !== 'production' ? 'source-map' : null,
  devServer: {
    headers: { 'Access-Control-Allow-Origin': '*' }
  }
};

解决这个问题的唯一方法是在渲染中的 html 周围加上引号:

render() {
    return (
      `<div className='App'>
        <h1>Hello World!</h1>
        <div>
          <p>Введите Ваше имя:</p>
          <div><input onChange={this.handleNameChange} /></div>
          {this.renderGreetingWidget()}
        </div>
      </div>`
    );
  }

但之后我在浏览器和 nodemon 中遇到此错误:

Invariant Violation: App.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

我检查并重新检查了所有依赖项、模块和我的文件。 尽管如此,我还是找不到错误。有人可以帮我吗?

附注抱歉我的英语很糟糕。

有趣的事情。当我在 App.jsx 中启动没有这些引号的 nodemon 时,我的页面会加载,但没有 css。之后,我在文件 App.jsx 中添加引号 ,现在 webpack-devserver 构建了一切正确的内容,并且页面在刷新后获取 .css 。 JS 脚本仍然不起作用,但看起来几乎应该......直到我重新启动nodemon......它开始显示相同的错误“Invariant Violation:App.render():有效的React元素(或null)必须返回。您可能返回了未定义的数组或其他无效对象。”

最佳答案

该错误告诉您,您没有定义可以处理 JSX 的加载器,尽管它可能看起来像您在 webpack 配置中所做的那样。问题是您同时定义了 module.rules 和 module.loaders。当 webpack 看到 module.rules 时,它会完全忽略 module.loaders (尽管出于兼容性原因它仍然存在)。修复很简单,只需将所有加载器放在 module.rules 下即可。

您的 .jsx? 规则也存在问题,因为 query (也已弃用并替换为 options )不能用于数组加载器,但应该为数组中的每个加载器定义。由于您将其作为字符串内联完成,因此您根本不需要它。

要获得有效的配置,请将 module 部分替换为:

module: {
  rules: [
    {
      test: /\.css$/,
      loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader'})
    },
    {
      test: /\.less$/,
      loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader!less-loader'})
    },
    { test: /\.gif$/, loader: 'url-loader?limit=10000&mimetype=image/gif' },
    { test: /\.jpg$/, loader: 'url-loader?limit=10000&mimetype=image/jpg' },
    { test: /\.png$/, loader: 'url-loader?limit=10000&mimetype=image/png' },
    { test: /\.svg/, loader: 'url-loader?limit=26000&mimetype=image/svg+xml' },
    { test: /\.(woff|woff2|ttf|eot)/, loader: 'url-loader?limit=1' },
    { test: /\.jsx?$/, use: ['react-hot-loader', 'babel-loader?presets[]=react,presets[]=es2015'],
      exclude: [/node_modules/, /public/] },
    { test: /\.json$/, loader: 'json-loader' },
  ]
},

如果您决定使用 options(这绝对更具可读性),您的 .jsx? 规则将如下所示:

{
  test: /\.jsx?$/,
  use: [
    'react-hot-loader',
    { loader: 'babel-loader', options: { presets: ['react', 'es2015'] } },
  ],
  exclude: [/node_modules/, /public/]
}

use 的文档所示.

关于javascript - Node+React+Babel+Webpack,意外 token 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42545014/

相关文章:

javascript - 使用 jQuery 单击元素时如何找到父表单元素?

javascript - 这个极好的网站是如何构建的?

javascript - 删除上一张幻灯片上的类

javascript - 使用 style-loader 访问 webpack 插件中生成的 css

reactjs - 使用 webpack 和 babel 捆绑和部署 React 应用程序时未显示 Unicode 字符

javascript - 无用的javascript机制?

javascript - 只有内容 div 可滚动的侧边栏布局

reactjs - 如何在 Create-react-app 应用程序中包含自定义脚本文件

reactjs - 在 React 应用程序中提供 `.well-known` 文件夹中的文件

javascript - 我是 webpack 3 的新手,我想将我的 var 共享到其他 js 文件,如何?