如何用Webpack将ES6+代码编译为ES6?Babel配置为何失效?
首先明确一点:Webpack本身不会自动把ES6+代码编译成ES5——它只是个模块打包工具,代码转译的工作完全交给你配置的loader(比如babel-loader)来处理。你遇到的矛盾(babel-cli能输出正确ES6,但Webpack不行),大概率是Webpack在production模式下默认启用的压缩插件偷偷转译了代码,或是webpack配置覆盖了你的Babel设置。
问题根源分析
- Production模式的Terser插件自动转译:Webpack在production模式下会默认启用
terser-webpack-plugin做代码压缩,这个插件默认会把代码转成ES5语法,哪怕Babel已经输出了ES6,它也会再转一遍。 - Webpack配置覆盖Babel规则:如果你的webpack配置里给babel-loader加了
options字段,可能会覆盖掉.babelrc里的preset配置,导致转译规则偏离预期。
具体解决步骤
第一步:确保babel-loader正确读取你的.babelrc
在webpack的module规则里,不要给babel-loader额外加preset或plugin配置,让它自动读取项目根目录的.babelrc:
module.exports = { // ...其他webpack配置 module: { rules: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader' // 这里不要写options,避免覆盖.babelrc的配置 } ] } };
你的.babelrc配置本身是没问题的:targets: { browsers: ["Chrome >= 60"] }指定了支持ES6的浏览器,@babel/preset-env会根据这个目标只转译Chrome 60不支持的ES6+语法,保留大部分原生ES6代码。
第二步:配置Terser插件输出ES6代码(针对Production模式)
如果是用production模式打包,必须修改terser的配置,让它输出ES6而不是ES5:
先确保你安装了terser-webpack-plugin(Webpack 4+默认已包含,自定义配置需手动引入),然后在webpack配置里添加:
const TerserPlugin = require('terser-webpack-plugin'); module.exports = { // ...其他配置 optimization: { minimizer: [ new TerserPlugin({ terserOptions: { // 指定输出的ECMAScript版本为6 ecma: 6, compress: { ecma: 6 }, output: { ecma: 6, comments: false } } }) ] } };
第三步:用开发模式验证输出
你可以先切换到mode: 'development'打包,开发模式下Webpack默认不会启用压缩插件,这样就能直接看到babel-loader输出的代码是否为ES6。如果开发模式下输出正确,那问题肯定出在production模式的压缩插件上。
另外补充个小建议:你用的stage-2 preset已经被废弃了,长期来看建议换成对应的@babel/plugin-proposal-*插件(比如@babel/plugin-proposal-class-properties、@babel/plugin-proposal-object-rest-spread),不过这和当前的转译版本问题无关。
内容的提问来源于stack exchange,提问作者Zhendong

