babel-loader搭配Webpack能否同时使用@babel/preset-env与@babel/preset-react?
配置合理性说明
在Webpack同一条rule规则中,给处理含JSX语法文件的babel-loader同时配置@babel/preset-env和@babel/preset-react是完全合理的官方推荐常规用法,不存在可行性问题。
两个预设的职责完全独立、互不冲突:
@babel/preset-env:负责根据配置的目标运行环境(browserslist规则),将高版本ECMAScript语法转译为目标环境兼容的低版本JS语法,同时可按需引入对应polyfill,本身不识别、不处理JSX语法。@babel/preset-react:负责将JSX/TSX语法转译为标准JS函数调用(React 17之前转译为React.createElement,新版自动运行时下转译为_jsx调用),本身不处理高版本ES语法的兼容转译。
如果只配其中一个预设,会出现对应功能缺失:只配@babel/preset-env会因为识别不了JSX抛语法错误;只配@babel/preset-react则转译后的代码可能存在目标环境不兼容的高版本语法,导致线上运行报错。
最新版本(Babel 7.x 全系列)正确配置方式
首先要明确Babel预设的固定执行规则:presets数组内的预设按从后往前的顺序执行,顺序写反会直接导致编译失败。
正确配置示例(webpack.config.js 对应rule片段):
module.exports = { module: { rules: [ { test: /\.jsx?$/, // 匹配.js、.jsx后缀文件,使用TSX可追加ts|tsx匹配规则 exclude: /node_modules/, // 排除依赖目录,提升构建速度 use: { loader: 'babel-loader', options: { // 注意顺序:@babel/preset-env在前,@babel/preset-react在后,保证执行时先转JSX再做语法兼容 presets: [ [ '@babel/preset-env', { useBuiltIns: 'usage', // 按需引入polyfill,避免全量引入增加包体积 corejs: 3 // 和本地安装的core-js版本保持一致即可 // 目标兼容环境默认读取项目根目录.browserslistrc配置,无需重复声明 } ], [ '@babel/preset-react', { runtime: 'automatic' // React 17+推荐配置,无需每个文件手动import React } ] ] } } } ] } }
常见注意事项
- 不要把两个预设拆分到不同rule中处理同一批JSX文件,会重复执行babel-loader增加构建耗时,还可能因为配置不一致出现编译问题。
- 如果顺序写反(@babel/preset-react在前、@babel/preset-env在后),会先执行env预设转译,此时JSX语法还没被转成标准JS,env预设无法识别会直接抛出语法解析错误。
内容的提问来源于stack exchange,提问作者rubixibuc
相关产品推荐
相关产品推荐

