错误:未捕获的引用错误:React未定义。

4

概述

我正在尝试使用 Babel 和 Webpack 构建一个 React 应用程序。我知道我可以使用 create-react-app,但是我想亲自了解这些技术如何协同工作。

当我运行 yarn run startyarn run build(请参阅下面的 package.json),Webpack 报告已成功构建捆绑包。当我在浏览器中运行应用程序时,我会收到 未捕获的引用错误:React 未定义 的错误信息。

关于此错误,SO 上有许多问题,但是没有一个解决方案可以解决我的问题。

问题

我缺少哪个环节才能使 React、Babel 和 Webpack 良好地协同工作?

代码

package.json

{
  "private": true,
  "scripts": {
    "build": "webpack",
    "start": "webpack-dev-server"
  },
  "dependencies": {
    "react": "^15.4.1",
    "react-dom": "^15.4.1",
    "react-redux": "^5.0.1",
    "redux": "^3.6.0"
  },
  "devDependencies": {
    "babel-core": "^6.21.0",
    "babel-loader": "^6.2.10",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "redux-devtools": "^3.3.1",
    "webpack": "^1.14.0",
    "webpack-dev-server": "^1.16.2"
  }
}

.babelrc

{
  "presets": ["react", "es2015"]
}

webpack.config.js

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: './dist'
  },
  devtool: 'source-map',
  debug: true,
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  }
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Test</title>
</head>
<body>
  <div id="root"></div>
  <script src="dist/bundle.js"></script>
</body>
</html>

src/index.js

import ReactDom from 'react-dom';
import React from 'react';
import App from './App';

ReactDom.render(
  <App />,
  document.getElementById('root'),
);

src/App.js

import React from 'react';
import { Component } from 'react';

export default class App extends Component {
  render() {
    return (
      <h1>hello</h1>
    );
  }
}

观察

  • 看起来Webpack/Babel期望React在全局范围内可用,或者忽略了我的import React from 'react';语句。
  • 此外,我还没有找到在我的Webpack配置中使用devtoolsdebug属性的正确方法,以便实际上让源映射工作。我还没有在编译输出中看到它们。

编辑

bundle.js文件太大,超出了SO的限制(21,000+行),因此这里提供一个链接:http://chopapp.com/#1a8udqpj — 它需要几秒钟的时间来加载和显示。


我想知道你是否有不使用.jsx扩展名的JSX源代码的充分理由。这可能会导致一些问题吗? - Tomasz Lenarcik
此外,查看您的 bundle.js 文件的内容可能有助于了解错误发生的确切位置。 - Tomasz Lenarcik
你能发布一下你的项目目录结构吗? - Paul Stoner
这看起来很正常。此时有一个最小的损坏包将会有所帮助。 - Filip Dupanović
@PaulStoner,好的,所有文件都位于项目的根目录下,除了index.jsApp.js,它们位于src/目录下。 - mjswensen
显示剩余5条评论
3个回答

5

因为你试图学习webpack等技术的细节... 你最初的问题是需要在webpack.config.js中指定output.publicPath:

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: './dist',
    publicPath: '/dist'  // <- was missing
  },
  devtool: 'source-map',
  debug: true,
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  }
}

"path"是包含你的bundle.js文件的文件夹的物理路径。"publicPath"是指向该文件夹的虚拟路径(URL)。因此,你甚至不需要使用"dist"。例如,如果你使用了...
  output: {
    filename: 'bundle.js',
    path: './dist',
    publicPath: '/assets'
  },

您的HTML文件将指向以下内容:
<script src="assets/bundle.js"></script>

1
我希望提出以下观点。首先是关于devTools和debug的问题。webpack的调试标志(根据他们官方文档)将加载器切换到调试模式。然后,据我所知,在开发环境中运行时,webpack实际上不会将代码编译为硬文件,而是将其保存在内存中。因此,源映射也保存在内存中,并与浏览器链接。当您打开浏览器开发工具并查看源代码时,您会看到它们的效果。
现在假设您已经正确配置了开发服务器,我还假设您的index.html位于源目录中。如果是这种情况,则您的脚本引用应该简单地指向'/bundle.js'而不是'dist/bundle.js',因为可能没有物理“dist”文件夹。
我还建议从webpack.config.js中删除入口点中的“.js”。

感谢您的时间。不幸的是,我想表达的关于源码映射的问题是,它们要么不存在,要么在Chrome的DevTools中没有任何效果。至于index.html,它驻留在项目的根目录中,因此dist/index.js实际上是正确的路径。 - mjswensen
不幸的是,从webpack配置文件的“entry”中删除“.js”并没有起到帮助作用。 - mjswensen
所以我刚刚完全复制了你的代码,并重新创建了你的项目。就像你所拥有的那样,在Chrome中链接到dist/bundle.js时,我收到了404错误。然而,如果我删除“dist”并简单地链接到bundle,应用程序就可以正常工作,我的控制台中也没有任何消息。 - Paul Stoner
很有趣。我并没有遇到关于 bundle.js 的 404 错误,它肯定已被浏览器加载。但是当我像你说的那样删除了“dist/”之后,它就可以工作!我猜测 webpack-dev-server 会自动从 dist 文件夹中提供服务,或者类似的事情?非常感谢你的帮助! - mjswensen
根据我的理解,在开发模式下,webpack实际上并不会编译文件并将其写入磁盘。它会将所有内容保存在内存中。很高兴我能帮到你。 - Paul Stoner
啊,好的。那很有趣。再次感谢。 - mjswensen

0

您需要在webpack.config.js文件中的模块中添加一个查询:

module: {
loaders: [{
  exclude: /node_modules/,
  loader: 'babel',
  query: {
    presets: ['react', 'es2015']
  }
}]
},
 resolve: {
   extensions: ['', '.js', '.jsx']
};

不幸的是,添加“query”属性没有帮助。 - mjswensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接