加载依赖React的CDN组件时出现'React is not defined'错误,咨询Webpack正确配置方案
看起来你遇到的核心问题是CDN组件期望全局环境中存在React/ReactDOM,但你的项目要么没有正确暴露全局React变量,要么同时引入了多个React实例,导致要么报错找不到React,要么出现UI异常。下面是针对这个问题的标准Webpack配置方案,以及相关的注意事项:
1. 配置Webpack的externals,避免重复打包并关联全局依赖
Webpack的externals选项可以指定哪些依赖不需要被打包进你的bundle,而是直接从全局环境中获取。这正好解决你的问题:让项目中的import React from 'react'自动指向全局的React变量,同时CDN组件也能访问到这个全局变量,还能彻底避免重复打包React的问题。
在你的Webpack配置文件(通常是webpack.config.js)中添加以下配置:
module.exports = { // ... 其他已有的配置(entry、output、module等) externals: { // 告诉Webpack:当代码中import 'react'时,直接使用全局变量`React` react: 'React', // 同理,import 'react-dom'对应全局变量`ReactDOM` 'react-dom': 'ReactDOM' } };
2. 确保React/ReactDOM只引入一次,且版本完全一致
这是解决"多个React版本"错误的关键:
- 保持
package.json中react、react-dom的版本和你HTML中CDN引入的版本完全一致(比如都是17.0.2) - 只在HTML中通过CDN引入一次React/ReactDOM,不要让项目依赖中的React被打包(这正是
externals帮你实现的)
你的HTML应该保持这样的引入(注意不要重复引入):
<script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
3. 移除临时的window.React = React代码
你之前添加的window.React = React之所以会导致UI异常,本质是因为项目中可能同时存在两个React实例:一个是CDN引入的全局实例,另一个是Webpack打包进bundle的项目依赖实例。当组件由其中一个React实例创建,而由另一个ReactDOM实例渲染时,就会出现更新异常、UI错乱的问题。externals配置后,项目代码会直接使用全局的React实例,不需要再手动挂载到window上。
4. 关于Babel配置的补充
你尝试的["@babel/preset-react", {"runtime": "automatic"}]是启用React的自动运行时,它会让你不需要在每个组件顶部手动写import React from 'react',但这个配置本身和你的问题无关。只要Webpack的externals配置正确,自动运行时也会正常使用全局的React变量,不会有冲突。
验证配置是否生效
配置完成后,重新打包你的项目:
- 检查bundle文件大小,应该会明显减小(因为没有打包React/ReactDOM)
- 运行项目,确认
React is not defined错误消失,同时UI不再出现异常行为
备注:内容来源于stack exchange,提问作者Coyote

