配置Vue项目兼容IE11详解
Vue
不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但对于 IE9+,Vue 底层是支持。
由于开发过程中,我们经常会使用一些第三方插件或组件,对于这些组件,有时我们需要做一些处理。下述主要阐述如何使用 vue-cli5 脚手架搭建的工程支持 IE11。
IE11 打开 Vue 工程(Vue CLI)构建而来出现空白页,控制台告警、报错。
如:
- DOM7011: 此页上的代码禁用了反向和正向缓存
- HTML1300:进行了导航
- app.js 各种语法错误
browserslist
在项目中 package.json
文件里新加一个 browserslist
字段 (或新建一个单独的 .browserslistrc 文件),指定了项目的目标浏览器的范围。这个值会被vue自带的@babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀。
- @babel/preset-env:将你使用最新 JavaScript 语法,灵活的转化为目标浏览器所支持的 polyfill。
- Autoprefixer:PostCSS 插件,为浏览器增加前缀。
我这里使用的是自己创建的.browserslistrc
文件
last 2 versions
> 1%
not ie <= 8
-
"1%":
- 表示全球超过1%人使用的浏览器。这是一个动态的标准,随着浏览器使用情况的变化而变化。通过使用这个查询条件,可以确保项目兼容那些使用人数较多的主流浏览器。
-
"last 2 versions":
- 表示所有浏览器兼容到最后两个版本。这意味着无论是什么浏览器,项目都会兼容其最新的两个版本。这有助于确保项目能够利用浏览器的最新功能和性能改进,同时仍然兼容较新的旧版本。
-
"not ie < 11":
- 表示排除IE浏览器版本小于11的所有版本。由于IE8及以下版本不支持Vue等现代前端框架所使用的ECMAScript 5特性,因此这个查询条件通常用于确保项目不兼容这些过时的浏览器版本。同时,它也表明项目将兼容IE11及更高版本的IE浏览器(尽管IE11本身也存在一些兼容性问题,但相对于更旧的版本,它支持更多的现代Web标准)。
Polyfill
Polyfill 可以让旧版本的浏览器通过模拟或提供替代实现的方式,来使用那些它们原本不支持的新功能。例如,如果某个旧版本的浏览器不支持
sessionStorage
API,那么就可以使用 Polyfill 来为这个浏览器提供sessionStorage
的支持。同样地,如果旧版本的浏览器不支持 HTML5 的<canvas>
元素,那么 Polyfill 也可以通过其他技术(如 Silverlight 或 VML)来模拟<canvas>
元素的功能。
默认的 Vue CLI 项目会使用 @vue/babel-preset-app,它通过 @babel/preset-env
和 browserslist
配置来决定项目需要的 polyfill。
默认情况下,它会把 useBuiltIns: 'usage'
传递给 @babel/preset-env,这样它会根据源代码中出现的语言特性自动检测需要的 polyfill。这确保了最终包里 polyfill 数量的最小化。然而,这也意味着如果其中一个依赖需要特殊的 polyfill,默认情况下 Babel 无法将其检测出来。
Vue CLI 文档 中,提供了三种方式:
1.如果该依赖基于一个目标环境不支持的 ES 版本撰写: 将其添加到 vue.config.js 中的 transpileDependencies 选项。这会为该依赖同时开启语法转换和根据使用情况检测 polyfill。
2.如果该依赖交付了 ES5 代码并显式地列出了需要的 polyfill: 你可以使用 @vue/babel-preset-app 的 polyfills 选项预包含所需要的 polyfill。注意 es6.promise 将被默认包含,因为现在的库依赖 Promise 是非常普遍的。// babel.config.js module.exports = { presets: [ ['@vue/app', { polyfills: [ 'es6.promise', 'es6.symbol' ] }] ] }
如果该依赖交付 ES5 代码,但使用了 ES6+ 特性且没有显式地列出需要的 polyfill (例如 Vuetify):请使用 useBuiltIns: 'entry' 然后在入口文件添加 import '@babel/polyfill'。这会根据 browserslist 目标导入所有 polyfill,这样你就不用再担心依赖的 polyfill 问题了,但是因为包含了一些没有用到的 polyfill 所以最终的包大小可能会增加。
开始教程
1.在.browserslist文件配置版本
last 2 versions
> 1%
not ie <= 8
2.安装兼容的包
npm i babel-polyfill
npm i core-js
安装完成之后在main.js中导入
import '@babel/polyfill'
import 'core-js/stable'
3.新建babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
[
'@babel/preset-env',
{
useBuiltIns: 'entry',
corejs: 3
}
]
],
}
4.新建jsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
5.vue.config.js里面配置transpileDependencies
transpileDependencies的意思就相当于转换,比如你下的插件axios,element,他原本是ES6的语法写的 不支持IE11的浏览器,需要转义一下。
在module.exports里新加一条
transpileDependencies: [
/[/\\]node_modules[/\\](.+?)?crypto-js(.*)[/\\]/,
/[/\\]node_modules[/\\](.+?)?element-ui(.*)[/\\]/,
/[/\\]node_modules[/\\](.+?)?axios(.*)[/\\]/,
],
6.css polyfill(可以不用)
如果你的项目里使用了大量使用了 CSS var()
,IE11 不兼容导致,思路相同,寻找相应的 polyfill 即可。这里我们使用了 css-vars-ponyfill
npm install --save css-vars-ponyfill
main.js
import cssVars from 'css-vars-ponyfill'
cssVars({})
安装的插件版本要对应着你的脚手架 很重要!!!
如果你的脚手架为3那么插件也要对应着3,每一搬的脚手架语法都不一样 vue.config.js里面配置也不一样
7.PostCSS
PostCSS 是一个通过 JavaScript 转换样式 的工具,可以帮助我们进行 CSS 转换和适配,比如自动添加浏览器前缀、**CSS 样式重置。**但是要想实现上述功能,必须借助于对应的插件
在 webpack 中使用 Postcss,需要先安装 postcss-loader 和 postcss。通过 postcss-loader 使用 postcss,对于特定功能,需要安装特定的插件,vue的话就不需要postcss-loader,我这里按照wenpack来写
module.exports
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
importLoaders: 1,
}
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('autoprefixer'), // 添加浏览器前缀
require('postcss-preset-env') // 该插件可以使用一些未来的CSS特性
]
}
}
}
]
}
]
}
}
创建 postcss.config.js 文件,在给该文件中添加使用的loader。这种方式更加简洁相较于第一种
module.exports
plugins: [
require('autoprefixer'),
require('postcss-preset-env')
]
}
至此,项目终于不是空白页了!!
总之,所有的处理都是围绕转换成 IE11 可以兼容的方式去处理。对于 JavaScript 语法,即是对 babel 的控制;对于 CSS 语法,需要特定分析。
IE 如果报错 strict模式下不允许分配到只读属性 问题解决
报错如上图所示;
解决办法如下:
第一:检测页面内是否有未定义变量,就给变量赋值等操作,也叫隐式声明此时要把所有的隐式声明变量模式改为先声明变量在使用变量的模式;
第二:检测页面内是否有直接给元素添加行内样式的js:比如下方代码:
self.target.style
//此时这种代码也会报错,不能直接使用.style = ,应该使用.style.transfrom = '10px'
正确写法为:
self.target.style.transform = self.initLeft + "px";//兼容IE
第三:查看自己的vue.config.js配置transpileDependencies
transpileDependencies:
/[/\\]node_modules[/\\](.+?)?crypto-js(.*)[/\\]/,
类似于这种 如果没有这个插件 你也配置了 也会报错
正确写法为:
self.target.style.transform = self.initLeft + "px";//兼容IE
第三:查看自己的vue.config.js配置transpileDependencies
```transpileDependencies: [
/[/\\]node_modules[/\\](.+?)?crypto-js(.*)[/\\]/,
类似于这种 如果没有这个插件 你也配置了 也会报错
以上两种方法检测完毕后目前上述报错问题解决