问题
webpack中ES6代码压缩问题:
在使用webpack插件uglifyjs-webpack-plugin
压缩JS代码时,发现该插件只能压缩ES5-的代码,遇到ES6,就会报错ERROR in xxx.js from UglifyJs
,遂查找解决办法。
原理解决办法
原理
如上所说,uglifyjs-webpack-plugin
该插件仅支持ES5-的JS代码。
解决办法
1. 不使用ES6语法
这个办法理论上可行,但是面对ES6那么多方便快捷的语法,不使用的话会大大降低开发的进度,所以一般不使用该方法。
2. 使用babel-loader将ES6转化为ES5代码
该方法是网上流行最广的解决办法,具体是:
安装es2015插件
npm install --save babel-preset-es2015
安装babel-loader
npm install babel-loader
也许是我环境的问题,网上的教程上都没这一步,但是,如果不安装babel-loader
,就会报错ERROR in Entry module not found: Error: Can't resolve 'babel-loader' in.........
,
这一步需要注意的是:
babel-loader必须与babel-core版本相同,否则会报错Error: Cannot find module '@babel/core'
,这一点需要自己到package.json
中查看babel-loader
,与babel-core
的版本来确定。(比如,babel-core版本是:6.23.3那么你装的babel-loader必须是7.1.5以下的版本,否则loader就与core不匹配了,注意如果直接npm install babel-loader
,默认是安装8.0.0的,所以不兼容)
- 配置webpack.congfig.js
在rules里加入对js代码的过滤
{
test: /\.js$/,
loader: 'babel-loader',
options:{
presets:["es2015"]
},
exclude:[/node_modules/]
}
- 建.babelrc文件
在项目根目录新建一个文件名为.babelrc
的文件,填入以下内容:
{
"presets": ["es2015"]
}
这是网上流传最广的办法,不过步骤繁琐,麻烦,下面介绍最优解决方案
3.使用uglifyes-webpack-plugin插件
其实上面的坑都是我一个一个经历的,网上的解决办法都是不完整,当我踩完所有坑,感觉这个方法太繁琐了。然后我就准备去深入了解一下uglifyjs-webpack-plugin
这个插件,结果无意间发现uglify有一个专门针对ES6的插件uglifyes-webpack-plugin
,哇,一试就知道有多爽,完全没有那么多步骤:
安装:
npm install uglifyes-webpack-plugin
webpack.config.js:
const UglifyEsPlugin = require("uglifyes-webpack-plugin");
plugins:[
new MiniCssExtractPlugin({ //css压缩
filename:’[name][hash].css’,
chunkFilename:’[id].[hash].css’
})
],
optimization:{
minimizer :[
new UglifyEsPlugin({}), //直接引用
new OptimizeCSSAssetsPligin({}) //css压缩
]
其实就一句话:new UglifyEsPlugin({}),
,与uglifyjs-webpack-plugin
的使用一样简单。
需要注意的是uglifyes-webpack-plugin与uglify-es-webpack-plugin并不是同一个插件,前者是官方的,也就是与uglifyjs-webpack-plugin一个维护者的,而后者已被弃用并不再维护
Point
该插件默认就会将ES6代码改成ES5代码,并且有压缩,混淆等功能,与uglifyjs-webpack-plugin
基本一致,下面是他的一些重要的API:
- test:匹配的文件,默认
/.js($|?)/i
,接受正则表达式 - mangle:是否混淆代码,默认为true
- sourceMap:是否启用SourceMap,默认为false
- compress: 自定义压缩选项,内容是一个对象,默认{},该选项下的子选项很重要,提一下
- sequences:是否使用逗号运算符来连接连续的表达式,默认true
- properties:是否优化属性读取方式:a[“foo”] → a.foo,默认true
- dead_code:是否丢弃不可达代码,默认true
- drop_debugger:是否丢弃调试语句,默认true
- unsafe:是否优化危险代码,默认false
- conditionals:是否优化 if-else 条件语句,默认true
- comparisons:是否优化比较代码,默认true
- evaluate:是否直接计算常量的值,默认true
- booleans:优化布尔表达式,默认true
- loops:是否优化循环代码,默认true
- unused:是否丢弃不使用的变量,函数,默认true。这里需要注意,如果你的函数本来就是一个DOM触发事件函数,请关闭此选项,否则,该函数将会被丢弃!!!
- hoist_funs:是否提升函数的申明,默认true
- hoist_vars:是否提升变量的申明,默认false
- if_return:是否优化优化if/return 和 if/continue
- join_vars:是否将加入变量申明,默认true
- cascade:优化连续语句,将 x, x 转成 x,x = something(), x 转成 x = something()——声明变量,默认true
- side_effects:丢弃副作用声明,默认true
- warnings:警告潜在的危险优化/代码,默认true
- global_defs:定义全局变量,默认{}
- extractComments:是否要删除注释,默认false,接受boolean,正则,函数,对象。
- include: 要转化的文件,默认无,接受字符串,正则
- exclude:在test验证通过后不转化的文件,默认空,接受字符串,正则
相较于uglifyjs-webpack-plugin
,uglify-es-webpack-plugin
功能要相对少一些,但基本也能满足要求
附uglifyjs-webpack-plugin常用API:
- test:测试匹配的文件,接受
String|RegExp|Array<String|RegExp>
,默认/.js(?.*)?$/i
- cache: 是否启用文件缓存 ,接受
Boolean|String
,默认false
- parallel:是否启用多进程来提高构建速度,接受
Boolean|Number
,默认false
- sourceMap: 是否启用SourceMap(将错误信息映射值模块源文件),开启可能会降低编译速度,接受
Boolean
,默认false
- uglifyOptions:压缩选项
- extractComments:是否保留注释,接受
Boolen,String,RegEXp,function,Object
,默认false - warningsFilter:允许过滤uglify-js警告。返回true以保持警告,否则为false。接受
Function<(warning, source) -> Boolean> Default: () => true
- extractComments:是否保留注释,接受
最后是UglifyJS的官网。