PS: 不推荐使用这个方式,推荐使用《webpack3 编译兼容 IE8- 的正确姿势》
最近在使用 webpack 和 gulp 的时候发现压缩后的 js 在 IE8- 下各种报错,蛋蛋的忧桑。
于是花了几个小时整理了下问题及解决方案。
PS: webpack 的 es3ify-loader 插件因为所在层面不同 (解析层之后才是优化层,如压缩等),所以问题依旧。
问题的核心点
不论是 webpack 还是 gulp 或者是其他第三方压缩插件,基本上都是基于 uglify-js
来压缩代码的,所以问题的根本原因就是 uglify-js
版本过高,导致不兼容 IE8-。
虽然问题描述起来非常简单,但怎么解决呢?
- 工具版本回退 (将 gulp, webpack 回退到老版本)
- 在 gulp/webpack 处理完后在使用老版本 uglify-js 压缩
- 修改工具源码 (这是找死行为!!!)
- 基于node的模块系统劫持 (感觉不错)
- 暂时没想到…
确定兼容版本
既然知道了问题的关键点,那自然是找兼容的版本了。
经过测试后最终确定 `uglify-js@2.6.4` 版本兼容 IE8-,至于如何测试,最简单的方法用如下代码进行压缩测试。
1 | var obj = {class: 'class'}; |
压缩后如果是 var obj={class:"class"}
那就是不兼容的,如果是 var obj={"class":"class"}
那就是兼容的。
针对性解决疑难杂症
我想到的第一个方法自然是版本回退
,因为这个方法最简单了,而且项目里确实也是这么用的。
比如 gulp-uglify
使用 1.5.4 即可兼容,webpack1
使用 1.12.15 版本即可,至于 webpack2
,,相当麻烦。
以上是 gulp 和 webpack1 的版本回退方法,非常简单易用。
webpack2 稳定版本完全不兼容,我测试了各个版本确定了 2.1.0-beta.22 版本。
但这不是最终发布版本,肯定不会用这个,那怎么破?继续看下文了。
针对 webpack2 进行模块劫持
由于 node 模块是针对模块绝对路径进行缓存的,那就简单了,
我们直接写一个缓存进去,webpack 就会加载我们的缓存,这样就达到兼容目的。
这里就不解释模块加载原理,感兴趣的自己用 devtool 或者是 vscode 跟踪下 require 行为即可。
第一步,安装 webpack 和 uglify-js@2.6:
1 | $ npm i -D webpack uglify-js@2.6 |
第二步,劫持webpack内的uglify-js模块:
1 | var path = require('path'); |
小结
其实我一开始是打算用方案二的,因为这是传统思路嘛,大多数人应该会想到这个。
但我这个人比较懒,能不改就不改,所以花了点时间折腾下,一劳永逸。
如果之后又出什么幺蛾子,,我可能会采取方案二,毕竟传统、稳定嘛。