CDN引入React时ES6模块导入组件报require未定义如何解决
报错根本原因
- 你使用的
babel-standaloneCDN转译方案默认不支持ES Module的import/export语法,babel会将import语句转译为CommonJS规范的require()调用,但浏览器原生没有require方法的实现,直接抛出require is not defined错误。 - 你当前的HTML只引入了
index.js,其余App.js、Navbar.js没有被引入,浏览器不会自动顺着import路径拉取依赖文件,模块加载链路本身就是断的。 - 你的
Navbar.js存在隐藏bug:组件内部渲染了自身<Navbar/>,会触发无限递归渲染,就算模块问题修复了也会报栈溢出错误。
解决方案(纯CDN无Node/NPM环境适配,零构建)
推荐用全局挂载方案,稳定性最高,不需要额外配置模块规则:
- 调整
index.html的脚本引入逻辑,按依赖顺序加载所有组件文件,所有自写JSX脚本都要标记为text/babel供babel转译,修改后代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Buynow Project</title> <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <!-- 按依赖顺序引入:先基础子组件,再父组件,最后入口文件 --> <script type="text/babel" src="buynow/components/Navbar.js"></script> <script type="text/babel" src="buynow/App.js"></script> <script type="text/babel" src="buynow/index.js"></script> </head> <body> <div id="root"></div> </body> </html>
- 修改所有组件文件,移除
import/export语法,将组件挂载到全局window对象,同时修复递归bug:
Navbar.js修改后:
function NavBar(props) { return ( <div> Hi NavBar </div> ); } window.Navbar = NavBar;
App.js修改后:
function App(props){ return ( <div> <Navbar/> Hello App </div> ); } window.App = App;
index.js修改后:
ReactDOM.render(<App />, document.getElementById('root'));
注意:本地调试不要直接双击打开HTML文件,用静态服务启动(比如VSCode的Live Server插件,无需Node环境),否则浏览器跨域策略会拦截本地文件加载。
如果你一定要保留import/export写法,可以给所有自写脚本标签加上data-type="module"属性,同时必须在HTTP静态服务环境下访问,但这种方式对babel-standalone版本有要求,兼容性不如全局挂载方案,不推荐在无构建场景使用。
内容的提问来源于stack exchange,提问作者ferdinand
相关产品推荐
相关产品推荐

