React18与Webpack5.88.1中出现'react is not defined'错误求助
我正在脱离CRA搭建React18+Webpack5项目,尝试了添加Webpack externals、更换插件、调整ReactDom引入顺序等多种方法,仍无法解决'react is not defined'错误。以下是我的相关配置文件:
Webpack配置
const HtmlWebpackPlugin = require('html-webpack-plugin'); const path = require('path'); module.exports = { entry: './src/index.js', mode: 'development', externals: { react: 'react' }, output: { path: path.resolve(__dirname, './dist'), filename: 'index_bundle.js', }, target: 'web', devServer: { port: '3000', static: { directory: path.join(__dirname, 'public') }, open: true, hot: true, liveReload: true, }, resolve: { extensions: ['.js', '.jsx', '.json'], modules: ['bower_components', 'node_modules', path.resolve('./src')], }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react'], }, }, }, { test: /\.css$/i, use: ['style-loader', 'css-loader', 'postcss-loader'], }, { test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/i, use: [ { loader: 'url-loader', options: { limit: 100000, }, }, ], } ], }, plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname, 'public', 'index.html') }), ] };
.babelrc配置
{ "presets": ["@babel/preset-env",["@babel/preset-react", {"runtime": "automatic"}]] }
src/index.js代码
import React from 'react'; import ReactDOM from "react-dom/client"; import App from './App'; import { BrowserRouter } from "react-router-dom"; import { Provider } from "react-redux"; import store from "__globalStore/store"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <React.StrictMode> <Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider> </React.StrictMode> );
当前使用React18.2与Webpack5.88.1版本。
问题根源与解决方案
1. 移除Webpack的externals配置
你在Webpack里配置了externals: { react: 'react' },这会告诉Webpack不把React打包到输出文件中,而是期望浏览器环境中存在全局的react变量。但你是通过npm本地安装的React,浏览器里没有这个全局变量,所以会报错。直接删掉这个externals字段即可。
2. 统一Babel配置,避免冲突
你的.babelrc已经配置了@babel/preset-react的runtime: 'automatic'(开启自动引入React的runtime,不需要手动import React),但Webpack的babel-loader选项里又单独写了presets: ['@babel/preset-react'],这里没有设置runtime参数,会覆盖.babelrc的配置,导致runtime自动引入失效。
解决方法二选一:
- 删掉Webpack中
babel-loader的options.presets配置,让Babel直接读取.babelrc的设置; - 或者在Webpack的
babel-loader里完整配置preset,把.babelrc里的配置移过来:use: { loader: 'babel-loader', options: { presets: [ '@babel/preset-env', ['@babel/preset-react', { "runtime": "automatic" }] ], }, }
3. 修改Webpack规则,支持JSX文件
当前Webpack的JS规则test: /\.js$/只处理.js文件,但React组件通常是.jsx格式(比如你的App.jsx),这会导致JSX文件无法被Babel编译,进而出现React未定义的错误。把test改成/\.jsx?$/,同时确保resolve.extensions里包含.jsx(你已经配置了,没问题):
{ test: /\.jsx?$/, exclude: /node_modules/, // ...其他配置 }
4. 可选:移除代码中不必要的import React
因为开启了runtime: 'automatic',React17+不需要在每个组件文件里手动import React from 'react',你可以删掉src/index.js里的import React from 'react',不过保留也不会报错,根据习惯选择即可。
修改完成后,重新启动开发服务器,react is not defined的错误应该就能解决。
内容的提问来源于stack exchange,提问作者RITIK SINGH

