无Node环境CDN引入React时导入其他文件及报错解决
问题根源
两个报错都是脚本加载顺序错误、在JSX中非法使用script标签导致的:
- 你在App组件的render返回的JSX里写了
<script>标签加载Home.js。JSX本质是React.createElement的语法糖,不会像原生HTML那样解析执行内嵌的script标签;babel-standalone处理到JSX里的外联script时,会尝试调用CommonJS规范的require()方法加载文件,但浏览器原生没有这个全局方法,直接抛出Uncaught ReferenceError: require is not defined错误。 - Home.js的加载逻辑被写在App组件内部,导致代码执行到渲染
<App />时,Home组件类还没被加载注册到全局作用域,React识别不到Home是合法的组件类型,就抛出第二个组件类型无效的警告。
修复步骤
1. 调整index.html的脚本加载顺序
所有React组件文件必须在根组件渲染前,按依赖顺序提前引入:被依赖的子组件要放在父组件前面加载,不要在JSX内部写script标签。
修正后的index.html代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Add React in One Minute</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> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css" > </head> <body> <div id="root"></div> <!-- 按依赖顺序加载:先加载子组件Home,再加载父组件App --> <script type="text/babel" src="./Home.js"></script> <script type="text/babel" src="./App.js"></script> <script type="text/babel"> ReactDOM.render(<App />, document.getElementById("root")); </script> </body> </html>
2. 清理App.js里的非法script标签
删掉JSX里所有script相关代码,直接引用已经全局加载完成的Home组件即可,不需要额外创建DOM容器重复调用ReactDOM.render:
class App extends React.Component { render() { return( <div> <img src="<logoURL>"/> {/* 直接嵌套子组件,不需要额外挂载 */} <Home /> </div> ) } }
Home.js不需要做任何修改,保持原有代码即可正常运行。
注意事项
- 无Node构建、直接通过CDN接入React的场景下,所有通过
type="text/babel"引入的脚本会按页面书写顺序转译执行,所有定义的组件类默认挂载在全局作用域,不需要写import/export语法,只要保证加载顺序正确就能直接引用。 - 禁止在JSX返回的内容中编写
<script>标签,React不会执行插入到JSX中的脚本,还会引发转译、渲染异常。 - 如果确实需要在同一页面挂载多个独立的React根节点,把所有
ReactDOM.render逻辑统一放在index.html的末尾、所有组件脚本加载完成后执行即可,不要把挂载逻辑写在组件的render函数里。
内容的提问来源于stack exchange,提问作者ferdinand
相关产品推荐
相关产品推荐

