Create React App Eject后Webpack+Babel项目导入外部库const enum出现运行时错误的问题
解决Create React App Eject后外部包Const Enum运行时未定义问题
我完全懂你现在的头疼——eject了Create React App项目,改了一堆Webpack配置,结果卡在外部包.d.ts里的const enum运行时错误上,试了相关Babel插件也没解决,太闹心了。让我们一步步把这个问题捋清楚并修复:
问题到底出在哪?
外部包的const enum定义在声明文件(.d.ts)里,TypeScript默认会把const enum完全内联到使用它的代码里,不会生成对应的JS对象。但你没法修改外部包,加上项目tsconfig里开了noEmit: true(依赖Babel转译),再配上之前Babel插件的顺序和参数不对,导致转译后的代码跑去读取一个根本不存在的枚举对象,最后就抛出了Cannot read properties of undefined的错误。
一步步修复方案
1. 调整Babel插件的顺序和配置
你的Babel插件顺序搞反了,而且缺少关键的TypeScript预设。修改Webpack里babel-loader的options部分:
options: { customize: require.resolve("babel-preset-react-app/webpack-overrides"), plugins: [ // 先让TypeScript插件处理语法,再转换const enum [require.resolve("@babel/plugin-transform-typescript"), { isTSX: true, optimizeConstEnums: false // 关掉TypeScript的内联优化,交给专门的插件处理 }], [require.resolve("babel-plugin-const-enum"), { transform: "constObject", // 把const enum转成可访问的常量对象 preserveConstEnum: true }], // 下面这些插件保持原样就行 [require.resolve("@babel/plugin-transform-react-jsx")], [require.resolve("@babel/plugin-proposal-class-properties"), { loose: true }], [require.resolve("@babel/plugin-proposal-nullish-coalescing-operator")], [require.resolve("@babel/plugin-proposal-optional-chaining"), { isTSX: true }], [require.resolve("@babel/plugin-transform-arrow-functions")], [require.resolve("@babel/plugin-proposal-private-methods"), { loose: true }], [ require.resolve("babel-plugin-named-asset-import"), { loaderMap: { svg: { ReactComponent: "@svgr/webpack?-svgo,+titleProp,+ref![path]", }, }, }, ], ], presets: [ "@babel/preset-env", "@babel/preset-typescript" // 加上这个预设,确保TypeScript语法被正确处理 ], }
几个关键调整:
- 把
@babel/plugin-transform-typescript移到babel-plugin-const-enum前面,关掉optimizeConstEnums,避免TypeScript提前把枚举内联死 - 添加
@babel/preset-typescript到预设列表,eject后的项目如果丢了这个,TypeScript语法转译会出问题 - 确保
babel-plugin-const-enum的transform设为constObject,这样会生成能在运行时访问的常量对象
2. 修改tsconfig.json的配置
在compilerOptions里加个preserveConstEnums: true,告诉TypeScript别把const enum完全内联,保留它的结构,这样Babel插件才能处理:
{ "compilerOptions": { // 其他配置都不动,加下面这行 "preserveConstEnums": true, "noEmit": true, // ... } }
3. 清缓存重新构建
有时候缓存会搞事情,先清干净再试:
rm -rf node_modules rm package-lock.json npm install npm start -- --reset-cache
然后重新启动项目,看看运行时的枚举错误是不是消失了。
为啥之前的配置没用?
- 插件顺序反了:
babel-plugin-const-enum得在TypeScript插件之后跑,不然TypeScript已经把枚举内联了,插件根本抓不到 - 缺了
@babel/preset-typescript:eject后原有的CRA预设被移除,得手动加这个才能正确处理TypeScript optimizeConstEnums: true强制TypeScript把枚举内联死,Babel插件根本没机会处理它
内容的提问来源于stack exchange,提问作者Prabu samvel
相关产品推荐
相关产品推荐

