浏览器兼容性处理方案总结

5,483 阅读4分钟

问题:

安卓4.4操作系统下webviewH5页面访问空白?

原因:

该webview浏览器内核版本太低,JavaScript解析器无法解析es5,es6新语法

解决步骤:

破题

利用babel polyfill对不兼容的语法进行处理

参考文档:babeljs.io/docs/en/bab…

  1. 依赖安装

根据官网文档,我们可以看出@babel/polyfill在7.4版本已经过时,实际上拆分成了core-js和regenerator-runtime

As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features) and regenerator-runtime/runtime (needed to use transpiled generator functions)

package.json文件中增加配置

"core-js": "^3.2.1",
"@babel/preset-env": "^7.5.5",
"regenerator": "^0.14.2",
"regenerator-runtime": "^0.13.3",
  1. 入口引用

入口文件main.js中引入

// babel 7 解决兼容老版ie不支持js高级特性api,本测试在ie 9,10,11三个版本亲测有效
// babel5,6(或者更旧版的) 有对应的 babel/polyfill
import 'core-js/stable'
import 'regenerator-runtime/runtime'
  1. babel配置

.babelrc 或者 babel.config.js,以babel.config.js为例

module.exports = {
    presets: [
        [
            '@babel/preset-env',
            { modules: false, useBuiltIns: 'usage', corejs: 3 }
        ]
    ]
}

这里需要注意,corejs要设置成3,因为默认使用的corejs的版本是2,corejs 2中是没有stable的,如果这里不指定版本就会报错

具体参数说明,见下面的文档

babeljs.io/docs/en/bab…

僵局

设置好babel polyfill之后,在IE11下可以正常访问了,但是在IE10下报语法错误。

弯路1:

点击错误指向的时候,发现指向了use strict,当时就误以为是use strict的问题,想要将use strict去除掉,走了不少弯路。但是实际上不应该犯这种低级错误,当时也没有太多思考。use strict很早就已经出现了,IE10的时候根本不可能出现不兼容问题。翻看上面的代码发现上面有很多use strict,上面不报错,偏偏这个地方报错,就说明不应该是use strict的问题。

弯路2: 怀疑按照官网的配置,是不是还是有些语法还是不支持,同时在babel的issue里面也有人问到这个问题,所以一直在配置里面打转。总是怀疑漏掉了什么配置。浪费了很多时间

破局

念念不忘,必有回响。某一个时刻忽然想到是不是某个插件有问题,是不是插件中的代码有问题。最终看编译后的js发现,一直报错的是vue-loadmore-simple这个插件。尝试修改了一下插件的源码,源码如下:

import LoadMoreComponent from './LoadMore.vue'
const LoadMore = {
	install:function(Vue,options){
		Vue.component('loadMore',LoadMoreComponent)
	}
}
export default LoadMore

将const改成var之后,再次编译之后,在IE10下面就可以正常展示了

思考

为什么有那么多插件,只有这个插件是不行的?

  1. webpack配置

vue cli3:

vue cli2:

从上面的图片可以看出,在默认的情况下,node_modules中的插件是不用babel进行处理的。所以插件的入口文件一定是打包之后的文件。

  1. 插件对比

我们来看看两个插件的对比

vue-loadmore-simple

插件的入口文件是index.js,代码如下

vue-lazyload

插件入口文件是vue-lazyload.js,代码如下

这里可以看出来,vue-lazyload的入口代码是被编译过的,而vue-loadmore-simple的入口代码是没有经过任何编译的,所以导致IE10下面一直在报错

JS的最后一步

如果想让vue-loadmore-simple能够被babel正常处理,需要在vue.config.js中配置一下,配置如下

module.exports = {
    transpileDependencies: ['vue-loadmore-simple']
}

样式的问题

问题:金额的前缀不显示,即¥这个标识显示不出来

原因: 低版本浏览器对utf-8字符¥不识别

解决方案:用html实体编号替代羊角,代码如下

<sub lang="en">&#165;</sub> 
问题:边框不显示

原因:为了方便编码,配置了px转义成rem的插件,vue.config.js中配置如下

css: { // 解决项目中自动添加浏览器厂商前缀等 和自动转换项目中px 到 rem单位
    loaderOptions: {
        postcss: {
            plugins: [
                require('autoprefixer'), require('postcss-px2rem')({
                    remUnit: 75
                })
            ]
        }
    }
}

该webpack编译插件致使 边框单位小于1px,浏览器无法渲染小于1px的像素(不同浏览器表现形式不太一样)

解决方案:从原来的2px改到3px,该解决方法还存在弊端,最好的方法是配置一下该插件对1px-2px不进行转换rem

问题: 商品图片不显示

原因:之前使用100vw来撑开banner,vw不兼容低版本浏览器,导致banner高度为0

解决方法:js动态获取屏幕宽度,重新设置banner高度