
babel/preset-react 完全指南JSX 转换配置、automatic/classic 运行时与最佳实践【免费下载链接】babel Babel is a compiler for writing next generation JavaScript.项目地址: https://gitcode.com/gh_mirrors/ba/babelbabel/preset-react是 Babel 官方提供的 React 专用预设负责把 JSX 语法编译为可在浏览器或 Node 中直接运行的 JavaScript 代码。本指南以当前仓库packages/babel-preset-react为实证基础完整讲解其安装方式、全部 8 个可配置选项、automatic与classic两套运行时机制的差异并结合源码与测试夹具给出可直接复制的配置示例帮助你快速上手并在实际项目中正确选型。1. 什么是 babel/preset-reactbabel/preset-react是 Babel 为 React 应用提供的全家桶预设preset它聚合了多个 React 相关的底层转换插件让开发者只需一行配置即可启用完整的 JSX 编译能力。其官方描述为 Babel preset for all React pluginspackages/babel-preset-react/package.json版本号当前为8.0.1与 Babel 8 主线保持一致peer 依赖babel/core ^8.0.0。从源码 packages/babel-preset-react/src/index.ts 可以清楚地看到它内部按条件装配了 4 个插件babel/plugin-transform-react-jsxJSX 核心转换插件生产模式babel/plugin-transform-react-jsx-developmentJSX 开发模式转换插件仅当development: true时启用babel/plugin-transform-react-display-name为匿名 React 组件推断displayName方便 DevTools 调试babel/plugin-transform-react-pure-annotations为 React 调用添加/*#__PURE__*/注释以支持 tree-shaking默认启用pure: false时关闭。预设的装配逻辑为开发模式下使用transformReactJSXDevelopment并透传sourceSelf: developmentSourceSelf否则使用transformReactJSX随后无条件追加transformReactDisplayName并根据pure决定是否追加transformReactPure最后过滤掉空项得到最终的插件列表。这意味着你不需要手动安装这些底层插件babel/preset-react会替你完成组合与排序。2. 安装当前文档给出了 npm 与 yarn 两种安装方式packages/babel-preset-react/README.mdnpm install --save-dev babel/preset-react或使用 yarnyarn add babel/preset-react --dev由于它是编译期工具应作为devDependencies安装。安装完成后在 Babel 配置文件如babel.config.json、babel.config.js或.babelrc中启用即可{ presets: [babel/preset-react] }注意预设的peerDependencies声明了babel/core ^8.0.0因此在 Babel 8 环境下使用该仓库版本时请确保项目中的babel/core版本匹配。3. 选项总览8 个可配置参数从 packages/babel-preset-react/src/normalize-options.ts 的TopLevelOptions定义可以看到本版本预设完整支持以下 8 个顶层选项选项类型默认值作用developmentboolean由api.env()判断development环境为true是否使用开发模式转换启用__source/__self与jsxDEVdevelopmentSourceSelfbooleanfalse开发模式下是否注入sourceSelf对应 classic 的__selfimportSourcestringreactautomatic 时automatic 运行时 JSX 工厂函数的导入来源pragmastringReact.createElementclassic 时classic 运行时 JSX 工厂函数名pragmaFragstringReact.Fragmentclassic 时classic 运行时 Fragment 的工厂函数名purebooleantrue未指定时默认启用是否添加/*#__PURE__*/注释runtimestringautomatic运行时模式可选automatic或classicthrowIfNamespacebooleantrue是否在遇到 XML 命名空间如svg:rect时抛错在 packages/babel-preset-react/src/index.ts 中这些选项被声明为预设的 TypeScriptOptions接口其中development、developmentSourceSelf、pure、throwIfNamespace为布尔型importSource、pragma、pragmaFrag为字符串型runtime限定为automatic | classic字面量联合类型。3.1 选项归一化逻辑normalize-options.ts 是选项校验与默认值注入的核心所有选项通过babel/helper-validator-option的OptionValidator逐一校验布尔用validateBooleanOption、字符串用validateStringOption然后依据runtime分支注入默认值runtime classicpragma默认为React.createElementpragmaFrag默认为React.Fragmentruntime automaticimportSource默认为react传入其它非法值如拼写错误时会抛出错误并使用findSuggestion给出最接近的候选值提示例如runtime must be one of [automatic, classic] but we have automatc。3.2 Babel 8 移除的旧选项useSpread 与 useBuiltIns该版本的normalizeOptions对 Babel 8 中已删除的两个旧选项做了硬性拦截一旦检测到配置中仍在使用会直接抛错并给出迁移指引useSpread自 Babel 8 起JSX 属性中的内联对象始终使用对象展开spread语法输出该选项已无意义直接删除即可useBuiltInsBabel 8 已不再在 JSX 转换中处理内建对象方法。如果你确实需要将对象展开编译为Object.assign等内建实现官方错误信息中给出的替代方案是改用babel/plugin-transform-object-rest-spread并显式配置{ loose: true, useBuiltIns: ... }。这一设计表明从 Babel 7 迁移到 Babel 8 时babel/preset-react的配置需要清理掉这两个历史选项。4. runtimeautomatic 与 classic 运行时runtime是预设中最重要的选项它决定了 JSX 被编译成什么形态。当前版本的默认值为automatic见 normalize-options.ts这也是 React 17 官方推荐的模式。4.1 classic 运行时classic 模式会调用全局React.createElement要求源码中或作用域内存在React变量。对如下输入Foo barbaz /classic 模式编译结果为见 runtime-classic/output.js/*#__PURE__*/React.createElement(Foo, { bar: baz });对应测试夹具 runtime-classic/options.json 仅配置了{ runtime: classic }其余选项全部走默认值。4.2 automatic 运行时automatic 模式不再需要手动引入React编译器会自动从importSource默认react导入 JSX 工厂函数。同一段输入在 automatic 模式非开发下会编译为import { jsx as _jsx } from react/jsx-runtime; /*#__PURE__*/_jsx(Foo, { bar: baz });其对应测试夹具为 development-runtime-automatic 系列。automatic 模式的核心优势是源码无需import React from react减少样板代码由编译器按需导入jsx/jsxs/jsxDEV/Fragment等函数更利于 tree-shaking属性中的对象展开始终以内联对象形式输出对应 Babel 8 移除useSpread的行为。4.3 与 pragma / pragmaFrag 的联动pragma与pragmaFrag仅在 classic 模式下生效runtime为 automatic 时被忽略。它们允许你把 JSX 编译到非 React 的工厂函数上例如使用 Preact 或自定义的h函数{ presets: [[babel/preset-react, { runtime: classic, pragma: h, pragmaFrag: Fragment }]] }在 normalize-options.ts 中只有runtime classic分支才会为pragma/pragmaFrag注入默认值印证了二者的作用范围。5. development开发模式与调试信息development: true会启用babel/plugin-transform-react-jsx-development为编译产物注入用于调试的源码位置信息。值得注意的是该选项在 index.ts 中的默认值并非字面量false而是api.env(env env development)——即只有当 Babel 运行在NODE_ENVdevelopment或BABEL_ENVdevelopment环境时才自动开启与 React 官方开发环境用开发构建、生产环境用生产构建的实践对齐。在 classic 运行时下开启development后输出会附带__self与__source属性见 development/output.jsvar _jsxFileName .../input.js; /*#__PURE__*/React.createElement(Foo, { bar: baz, __self: this, __source: { fileName: _jsxFileName, lineNumber: 1, columnNumber: 1 } });5.1 developmentSourceSelf 的差异developmentSourceSelf默认false控制开发模式下是否注入sourceSelf/__self。对比两个测试夹具可以直观看到差异development/options.json 设置了developmentSourceSelf: true其输出 development/output.js 中出现了__self: thisdevelopment-no-source-self 系列未开启developmentSourceSelf则不会注入__self。automatic 运行时下开启development见 development-runtime-automatic/output.js则使用jsxDEV并携带fileName、lineNumber、columnNumber参数var _reactJsxDevRuntime require(react/jsx-dev-runtime); var _jsxFileName .../input.js; /*#__PURE__*/_reactJsxDevRuntime.jsxDEV(Foo, { bar: baz }, void 0, false, { fileName: _jsxFileName, lineNumber: 1, columnNumber: 1 }, this);这些调试信息是 React 错误边界、组件栈和 HMR热更新依赖的重要数据来源建议在开发构建中开启、生产构建中关闭。6. purePURE 注释与 tree-shakingpure选项控制是否为组件工厂调用添加/*#__PURE__*/注释默认启用未显式指定时为true。该注释是给打包器webpack、Rollup、esbuild 等的提示此调用无副作用在未被使用时可安全删除从而支持 tree-shaking 与 dead code elimination。仓库提供了正反两组测试夹具pure/input.js 系列使用默认配置pure/options.json 仅写presets: [react]输出保留/*#__PURE__*/注释pure-false 系列显式配置pure: false输出中不包含 PURE 注释。在 index.ts 中pure ! false transformReactPure的逻辑表明只有当pure不为false时才会挂载babel/plugin-transform-react-pure-annotations插件。对于追求产物体积的应用建议保持默认开启。7. 其他选项importSource 与 throwIfNamespace7.1 importSourceimportSource仅对 automatic 运行时有效用于指定 JSX 运行时模块的导入来源默认react。例如使用 Preact 时配置{ presets: [[babel/preset-react, { runtime: automatic, importSource: preact }]] }此时编译产物会从preact/jsx-runtime导入工厂函数。若需要在非自动导入场景下自定义入口也可与development组合使用。7.2 throwIfNamespacethrowIfNamespace默认true用于控制是否允许 JSX 中的 XML 命名空间写法如svg:path。默认开启时遇到命名空间会抛出语法错误这符合规范要求因为 JSX 命名空间并非标准语法若你确有兼容旧代码的需求可显式设置为false。8. 完整配置示例结合以上所有选项一个面向实际工程的完整配置如下{ presets: [ [ babel/preset-react, { runtime: automatic, importSource: react, development: true, developmentSourceSelf: false, pure: true, throwIfNamespace: true } ] ] }生产构建建议{ presets: [ [ babel/preset-react, { runtime: automatic, development: false, pure: true } ] ] }需要说明的是development的默认值已经与api.env()联动实践中通常无需手动指定开发环境NODE_ENVdevelopment自动得到带调试信息的产物生产环境自动关闭。若你使用的是 React 17 之前的旧项目且不便升级可将runtime设为classic并保持import React from react的写法。9. 验证与回归测试仓库为babel/preset-react提供了完整的测试体系可用于验证配置行为的正确性测试入口preset-options.js 通过babel/helper-plugin-test-runner批量运行 fixtures选项夹具目录preset-options 覆盖了development、developmentSourceSelf、pure、runtime等各选项组合回归夹具目录regression 覆盖了自定义 JSX 预设、多 preset 叠加sourceSelf等历史 issue 场景如 11294、自定义 emotion 风格 preset 等。每个夹具由input.js输入、options.jsonBabel 配置、output.js/output.mjs期望输出三部分组成。例如development夹具的配置为{ development: true, developmentSourceSelf: true, runtime: classic }其输出精确验证了__self/__source的注入行为。如果你修改了预设行为运行对应测试即可确认没有破坏既有语义。10. 小结babel/preset-react是 Babel 生态中接入 React 的标准入口其设计要点可以归纳为预设即组合一个 preset 内部组合了 JSX 转换、displayName 推断、PURE 注释三个层面的插件development还会切换为专用的 JSX 开发转换插件运行时二选一automatic默认免去手动引入 React自动从importSource导入工厂函数classic兼容旧项目依赖全局React.createElement并可用pragma/pragmaFrag定制环境感知development默认跟随api.env()自动区分开发/生产产物Babel 8 迁移useSpread、useBuiltIns已在 Babel 8 中移除配置中需清理并改用babel/plugin-transform-object-rest-spread等替代方案。按照本文的配置示例与选项对照表你可以在新项目中直接采用 automatic 运行时获得最现代的 JSX 编译产物也可以在旧项目中平滑切换到 classic 模式并通过测试夹具验证每一步配置的产物形态。【免费下载链接】babel Babel is a compiler for writing next generation JavaScript.项目地址: https://gitcode.com/gh_mirrors/ba/babel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考