不使用Node.js引入React组件时遇exports未定义错误求助
不依赖Node.js在PHP项目中引入独立React组件的问题
需求背景
在PHP项目中仅需用React实现简单功能,不想引入Node.js,希望通过HTML文件直接引入独立.js文件中的React组件。
现有代码
HTML文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>React Local</title> <script src="https://unpkg.com/react@15.3.2/dist/react.js"></script> <script src="https://unpkg.com/react-dom@15.3.2/dist/react-dom.js"></script> <script type="application/javascript" src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script> <script type="text/babel" data-type="module" src="./TestComponent.js"></script> </head> <body> <script type="text/babel"> // Obtain the root const rootElement = document.getElementById('root') ReactDOM.render( <TestComponent />, rootElement ) </script> <div id="root"></div> </body> </html>
TestComponent.js文件
// Create a ES6 class component class TestComponent extends React.Component { render() { return ( <span>HELLO</span> ); } } export default TestComponent;
报错信息
VM99:3 Uncaught ReferenceError: exports is not defined at <anonymous>:3:23 at run (babel.js:61531:11) at check (babel.js:61597:10) at result.<computed>._extends.content (babel.js:61624:10) at xhr.onreadystatechange (babel.js:61549:10)
解决思路
1. 调整组件暴露方式,移除模块标识
babel-standalone对ES模块的支持存在兼容性问题,无需使用export导出,直接将组件挂载到全局window对象:
修改TestComponent.js:
class TestComponent extends React.Component { render() { return ( <span>HELLO</span> ); } } // 将组件挂载到全局,供HTML中的代码访问 window.TestComponent = TestComponent;
同时修改HTML中引入组件的script标签,移除data-type="module":
<script type="text/babel" src="./TestComponent.js"></script>
2. 修复DOM元素获取时机问题
原代码中执行document.getElementById('root')时,<div id="root">还未被渲染到DOM中,会导致rootElement为null。有两种修复方式:
- 将React渲染代码放到
<div id="root"></div>之后:
<div id="root"></div> <script type="text/babel"> const rootElement = document.getElementById('root') ReactDOM.render( <TestComponent />, rootElement ) </script>
- 用
DOMContentLoaded事件包裹渲染逻辑,确保DOM加载完成后再执行:
<script type="text/babel"> document.addEventListener('DOMContentLoaded', () => { const rootElement = document.getElementById('root') ReactDOM.render( <TestComponent />, rootElement ) }) </script> <div id="root"></div>
3. (可选)升级依赖版本
当前使用的React 15和babel-standalone 6版本较旧,可升级到更稳定的新版本以提升兼容性,比如使用React 18的UMD版本:
<script src="https://unpkg.com/react@18/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
若升级到React 18,渲染逻辑需调整为使用createRoot:
document.addEventListener('DOMContentLoaded', () => { const rootElement = document.getElementById('root') const root = ReactDOM.createRoot(rootElement); root.render(<TestComponent />); })
内容的提问来源于stack exchange,提问作者Jean François Manatane
相关产品推荐
相关产品推荐

