React运行报exports is not defined错误 无webpack如何修复


Uncaught ReferenceError: exports is not defined是Babel默认配置的行为导致的:Babel preset-env默认会把代码里的ES Module(import/export)语法转成CommonJS规范的require/exports语法,浏览器原生没有CommonJS运行环境,识别不了全局exports对象就会抛错。
第一步:修改Babel配置,关闭模块语法转换
找到项目下的.babelrc或者babel.config.json配置文件,给preset-env加上modules: false配置,强制Babel保留原生ES Module语法,不要转成CommonJS格式。配置示例:{ "presets": [ ["@babel/preset-env", { "modules": false }], ["@babel/preset-react", { "runtime": "automatic" }] ] }配置完重新执行Babel编译命令,输出的代码里就不会再出现
exports相关的CommonJS代码了。第二步:给HTML的脚本标签添加ES Module标识,配置依赖映射
浏览器默认会把普通script标签当作普通脚本解析,要识别import/export必须给标签加type="module"属性。同时node_modules里的react、react-dom默认是CommonJS版本,浏览器无法直接导入,需要用importmap映射到浏览器可用的ESM版本资源,index.html参考配置:<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>极简React项目</title> <script type="importmap"> { "imports": { "react": "https://esm.sh/react@18.2.0", "react-dom/client": "https://esm.sh/react-dom@18.2.0/client" } } </script> </head> <body> <div id="root"></div> <!-- 必须加type="module" --> <script type="module" src="./dist/index.js"></script> </body> </html>如果不想依赖在线CDN,可以把对应版本的react、react-dom ESM格式文件下载到本地静态目录,把importmap里的路径换成本地相对路径即可。
第三步:修正代码导入规则
浏览器原生ES Module要求本地文件导入必须写全文件后缀,不能省略.js;另外React18的createRootAPI是从react-dom/client路径导出的,要修正导入写法:- 修正index.js代码:
import { createRoot } from 'react-dom/client' // 本地导入必须补全.js后缀 import AppRouter from './routers/AppRouter.js' createRoot(document.getElementById('root')).render(<AppRouter/>);- AppRouter.js里如果开了前面提到的
runtime: "automatic"配置,可以直接删掉冗余的React导入行,Babel会自动注入需要的API,简化后的代码:
import { Component } from 'react' class AppRouter extends Component{ render(){ return( <> adsada </> ); } } export default AppRouter;
改完之后重新编译,再用Live Server打开页面就不会再报exports未定义的错误了。
内容的提问来源于stack exchange,提问作者BTicaret BTicaret

