记一次webpack4.x打包兼容ie8 的经历
写在前面
- 打包经历中没有用到Promise等语法,只用到了es6的一些语法书写逻辑
- webpack使用的是4.x ; babel 使用的是7.x
- 不一定适用于所有要兼容ie 8 的场景,请注意
背景:
因为公司功能项目需要,领导我书写了一个javaScript的程序,目的是暴露3个方法,能够调用相关的后台逻辑代码;
经历:
-
要求定下来了,那么接下来让我们开工;
- 打开Vscode;
- 初始化工程(npm init)
- 安装 babel、webpack、prettier 开发必备的三个工具 ,按照官网基础配置一下就好
- 开始撸代码;
-
我使用的包的版本为:
"webpack": "^4.35.2"
"@babel/core": "^7.5.0"
"prettier": "^1.18.2"
就在我代码写完了在自测时候,被告知,需要兼容ie8 ,!!!
ie8 !!! ie 8!!! ie8 !!!………..您的好友已经阵亡;
抱着试试看的心态,我使用ie11 模拟了ie8 环境调用了脚本,结果不出意外报错;
遇到了第一个问题:
- 缺少标识符
default 是ie8 的关键字,不能使用;
default 是ie8 的关键字,不能使用;
default 是ie8 的关键字,不能使用;
然后网上一通百度,找到了很多解决方案,例如:使用es3ify-loader,但是在webpack官网找了,并没有找到这个load,就很尴尬,在仔细看了看,帖子发现帖子中使用的webpack2;
后来........ ,又是一通找,最后在webpack 4版本找到了一个插件uglifyjs-webpack-plugin, 可以解决该问题,故配置起来,然后果然解决了问题【上官网配置图】:
- 对象不支持此操作
既然报错是对象不支持该操作 ,那么就得断点分析,那个对象不支持操作,一顿断点,输出,发现是object.defineProperty,
查了些资料,发现object.defineProperty 在ie8 中存在,但是只用用于操作dom对象,难怪他会报错对象不支持该操作
然后又是开启各种查找解决方案:
方案一、引入 es5-shim.min.js 和es5-sham.min.js 在入口文件的头部
方案二、引入@babel/runtime 或者@babel/ployfil ,在入口文件引入
方案三、检查压缩后的代码,看是否在混码过程中,有混码冲突的
都尝试了一下没有效果,【很是绝望。。。。】
后来,在google上找的时候,找了,一个npm包object-defineproperty-ie8
就抱着试试看的心态,安装并引入了工程,运行一下发现,居然可以了解决了报错
之后顺着npm的github的链接,找到了 写这几个包的作者,居然是大神司徒正美,立刻star 了一波,
感悟
- 明确自己使用的相关包的版本情况;例如我这次有遇到包是否兼容ie8, 在其中我一开始有用到 jquery的3.4版本,查阅资料后,发现jq的1.x才支持ie8
- 注意参考分析,是什么问题导致了ie的兼容报错,学会如何处理代码;例如;uglifyjs-webpack-plugin插件的参数配置,使得源码更加清晰
- 不能只看方案的步骤,而不看方案的起始;我在整个的过程中,有找到很多的方案,都是经历的一烦尝试发现不行,反过来看发现方案中webpack版本和我的根本不一样,
- 借鉴优秀的分析方式;我在尝试了很多方案配置不行之后,就慢慢开始,借鉴方案的分析思路,然后对比我现在所遇到的问题,看他是怎么解决的,然后在我的处境下,看是否有响应的方案,逐个分析解决;
- 百度搜索不到,就搭梯子上google; 大家都懂的
最终配置情况
-
package.json
"dependencies": { "expose-loader": "^0.7.5", "jquery": "^1.12.0", "object-defineproperty-ie8": "^1.0.1", "underscore": "^1.9.1" }, "devDependencies": { "@babel/cli": "^7.5.0", "@babel/core": "^7.5.0", "@babel/plugin-transform-modules-commonjs": "^7.5.0", "@babel/plugin-transform-object-assign": "^7.2.0", "@babel/preset-env": "^7.5.0", "babel-loader": "^8.0.6", "html-webpack-plugin": "^3.2.0", "prettier": "^1.18.2", "uglifyjs-webpack-plugin": "^2.2.0", "webpack": "^4.35.2", "webpack-cli": "^3.3.5", "webpack-dev-server": "^3.7.2" } 复制代码
-
Webpack.config.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); module.exports = { mode: 'production', // "production" | "development" | "none" // Chosen mode tells webpack to use its built-in optimizations accordingly. optimization: { minimizer: [ new UglifyJsPlugin({ sourceMap: true, exclude: /node_modules/, uglifyOptions: { ie8: true // 解决ie下的关键字default的问题 } }) ] }, entry: './index.js', // string | object | array // 这里应用程序开始执行 // webpack 开始打包 output: { // webpack 如何输出结果的相关选项 path: path.resolve(__dirname, 'dist'), // string // 所有输出文件的目标路径 // 必须是绝对路径(使用 Node.js 的 path 模块) filename: 'mockSofaAPI.js' // string // 「入口分块(entry chunk)」的文件名模板(出口分块?) }, module: { // 关于模块配置 rules: [ // 模块规则(配置 loader、解析器等选项) { test: /\.js?$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: [['@babel/preset-env']], plugins: [ ['@babel/plugin-transform-modules-commonjs'], ['@babel/plugin-transform-object-assign'] ] } } } ] }, context: __dirname, // string(绝对路径!) // webpack 的主目录 // entry 和 module.rules.loader 选项 // 相对于此目录解析 target: 'web', // 枚举 // 包(bundle)应该运行的环境 // 更改 块加载行为(chunk loading behavior) 和 可用模块(available module) devServer: { contentBase: path.join(__dirname, 'dist'), // boolean | string | array, static file location port: 9000, host: '0.0.0.0', open: true }, plugins: [new HtmlWebpackPlugin()] }; 复制代码
参考资料:
Webpack4+Babel7+ES6兼容IE8:juejin.im/post/5cabf7…
这篇掘金朋友的文章,也给了我很大的启发,他指引我找到解决 ie 8 下default 关键字的处理方式,而且他的分析思路也很清新,一步一步,很是好,受益颇多,十分感谢
让Webpack+Babel支持IE8:www.maizhiying.me/posts/2017/…
这篇文章,然我知道了,关于webpack的插件uglifyjs-webpack-plugin的使用, 并懂的了,在茫茫的压缩代码中,可以通过配置插件的 美化和混码方式,来提升压缩后的代码的思路,另外,这个文章中的分析思路也很好,一步一步很是详细,受益颇多,十分感谢
uglifyjs-webpack-plugin插件:github.com/mishoo/Ugli…
其中有不少的参数配置和功能说明,很是详细,而且其中有不少关于代码压缩混码等的配置参数控制,可以通过配置,提升查找定位的问题的代码的方式,使得压缩后的代码可以调理更加清晰
object-defineproperty-ie8:github.com/RubyLouvre/…
这个是最后解决为ie8下的bject.defineProperty 问题的github地址,验证有效后,膜拜了一波作者,然后star
webpack:www.webpackjs.com/concepts/
很详细的官网
babel:babeljs.io/
很详细的官网