一、背景
1.项目主要是vue及其对应的插件搭建的项目框架,主要ui框架是element-ui和部分用到view-design。
2.管理端项目本来主要是公司内部人员使用,开始是没有要求兼容低端浏览器和ie浏览器的,怎奈不过实际公司有很多终端设备。刚好有个模块需要在收银机电脑里使用,收银机是XP系统。那就不得不适配了。
二、过程
1.收银机自带的是ie7系统,试了一下公司生产环境项目自己就访问不了,在打开百度都报脚本错误,真奔溃啊!不过好在还能正常访问。然后试了一下测试环境跑的项目,能访问,但脚本报错了,一片空白。生产环境访问不了估计就是https证书的问题,后面用其它浏览器可以增设证实这个。
2.vue只能支持ie9以上的浏览器,这基本宣布ie是没法适配了。那就试试谷歌chrome,xp自带的ie不管访问啥网页基本都会报脚本错误,而且这xp又卡又难用(是电脑触摸屏,没键盘鼠标),只能在其他电脑上先找到chrome。chrome支持xp系统的最高版本是49,这个在网上可不好找,官网上没找到,其他国内的捆绑软件试了一下安装,都是会变成最新版的。用了几个都不行,在搜索中无意中找到一个国外的旧版链接能用,下载49的版本,不过本机是win10系统,直接安装不了(提示解压)。在xp系统上能用。
3.xp系统因为自带ie7难用,先试了360,搜狗等浏览器,发现也都没支持xp的版本,后面先找到火狐浏览器能用,终于能够开心的使用xp了,然后用2中的链接下载对应chrome版本的浏览器,也安装胜利,接下来就是调试项目。
三、寻找方案
1.首先看到直接在chrome49,打开是空白的,查看报错信息是如下,可以看到有个组件view-design导致的报错,同样的火狐浏览器也是类似的报错。说明是有es6的语法不支持了。
2.原因分析
a.在github iview仓储Issues中提到的(iview 是view-design的前身)
b. 改编译范围请用 transpileDependencies: [‘iview’],不要用 include.add,因为默认配置里用了 exclude,在 webpack 中,多个条件同时存在时需要每个条件都满足才执行 rule。
c.但是加了这个选项后在所有浏览器里都会报错,因为 iView 里这个文件不兼容 ES Module。该文件是用很旧版本的 UMD 格式打包的,新版本 UMD 修复了报错的问题,但没有解决和 ES Module 互操作的问题。在 Webpack 4 中,ES Module 不能和 CommonJS / UMD 混用。
d.所以这里本质上是 iView 对 Webpack 4 支持的问题,让他们把源码全部转成 ES Module 就好了。
e. 在vue.config.js中添加transpileDependencies: [‘iview’]后,可以让bable编译过程中检查iview的代码,自动添加代码中用到的polyfill。但是由于iview中有一个文件使用的UMD打包,所以编译后的代码还是在运行环境中报错,导致项目无法使用。该方案虽然解决了ES6语法问题,但是实际使用会报错,和我们现在的情况一样。
四、解决放案
1.直接给代码添加polyfill,修改文件bable.config.js使用 useBuiltIns: ‘entry’
module.exports = {presets: [['@vue/app', {useBuiltIns:'entry'}]]}
2.在Vue入口文件main中导入bable的polyfill
import 'babel-polyfill'
3.这种方案bable编译时,会自动导入目标浏览器(browserslist中配置)需要用到的polyfill,可以保证全局代码使用都可以新ES代码。但是,也许有些polyfill会一直用不到,额外增加了编译后的文件体积。
4.使用balbe env,预置iview中所需要的polyfill(推荐做法)
a.修改bable.config.js 添加预导入的polyfill。目前我的项目中用到的polyfill有’es6.promise’,‘es6.array.find-index’,‘es7.array.includes’,‘es6.string.includes’
module.exports = { presets: [['@vue/app', { debug:true, polyfills: [ 'es6.promise' , 'es6.array.find-index' , 'es7.array.includes' , 'es6.string.includes' ] }]]}
b.这种方案依然使用Vue项目默认方案,不同的是在项目编译时,会导入polyfills中指定的polyfill,这样既可解决iview在ie中运行报错的问题。上面中是我目前用到的几polyfill,如果需要其它铺垫,可以自行添加。
4.如果用到了用到了按需加载babel-plugin-import,也就.babelrc配置如下,那还是要加上第三条中的第二点方案,看下一条
{ //按需加载配置 "plugins": [["import", { "libraryName": "view-design", "libraryDirectory": "src/components" }]] }
5.在vue.config.js文件的module.exports 中配置
module.exports = { transpileDependencies: ['view-design'], chainWebpack(config) { config.entry('main').add('babel-polyfill') // main是入口js文件 config.entry.app = ['babel-polyfill', './src/main.js'] //config.module .rule("view-design") .test(/view-design.src.*?js$/) .use("babel") .loader("babel-loader") .end(); //第二种写法,同上面两行代码的效果 }}
6.如果报错babel-polyfill只能使用一个,那就把main.js 中引用的babel-polyfill删除即可。原创文章点这