如何在不引入React的场景下使用webpack编译打包JSX代码?
报错原因
你代码中的<h1>Hello, World</h1>属于JSX语法,不属于原生JavaScript标准语法,webpack本身无法直接识别这类非标准语法,需要通过Babel进行转译处理。默认配置下,Babel的JSX转译逻辑会将JSX节点转换为React.createElement的调用语句,因此转译器默认会要求你引入React相关的预设支持,这不是webpack本身依赖React,而是Babel默认的JSX转译规则绑定了React的API。
不引入React的实现方案
你可以通过两种方式实现无React依赖的打包:
方案1:自定义JSX转译规则(保留JSX写法)
Babel 7.9及以上版本的@babel/preset-react支持自定义JSX转译输出,你可以配置使用自己实现的DOM创建函数替代React.createElement,全程不需要引入React。
- 安装必要依赖:
npm install @babel/core @babel/preset-env @babel/preset-react babel-loader --save-dev
- 项目根目录新增Babel配置文件
babel.config.json,内容如下:
{ "presets": [ "@babel/preset-env", [ "@babel/preset-react", { "runtime": "automatic", "importSource": "./custom-jsx-runtime" } ] ] }
- 实现自定义JSX运行时,在
./custom-jsx-runtime/jsx-runtime.js路径下新增如下代码:
export function jsx(tag, props) { const element = document.createElement(tag); const { children, ...attrs } = props || {}; // 处理节点属性 Object.entries(attrs).forEach(([key, val]) => element.setAttribute(key, val)); // 处理子节点 const childList = Array.isArray(children) ? children : [children]; childList.forEach(child => { if (['string', 'number'].includes(typeof child)) { element.appendChild(document.createTextNode(child)); } else if (child instanceof Node) { element.appendChild(child); } }); return element; } export function jsxs(tag, props) { return jsx(tag, props); }
- webpack配置中正常添加babel-loader处理
.js/.jsx后缀文件即可,不需要在业务代码中引入任何React相关依赖。
方案2:替换JSX为原生DOM写法
如果你不想额外配置JSX运行时,直接将JSX语法改写为原生DOM操作代码即可,不需要额外的Babel预设配置:
function Welcome() { const h1 = document.createElement('h1'); h1.textContent = 'Hello, World'; return h1; }
这种方式仅需要配置@babel/preset-env处理ES版本兼容即可完成打包,无任何额外框架依赖。
内容的提问来源于stack exchange,提问作者howard
相关产品推荐
相关产品推荐

