vue-cli@4.x 浏览器兼容问题处理

vue-cli@4.x 浏览器兼容问题处理

在开发项目时由于项目中使用到的监控插件不能兼容高版本的谷歌火狐等,只能使用 ie,项目使用vue-cli 4.5.8 版本构建

vue-cli4.x 默认情况下不需要自己手动安装 babel-polyfill,官网对此也有介绍

浏览器兼容性

#browserslist

你会发现有 package.json 文件里的 browserslist 字段 (或一个单独的 .browserslistrc 文件),指定了项目的目标浏览器的范围。这个值会被 @babel/preset-envAutoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀。

现在查阅这里了解如何指定浏览器范围。

1、browserslist 是什么?

browserslist 是用来配置项目的目标浏览器和 nodejs 版本范围,也就是通常说的兼容哪些浏览器的版本。

2、browserslist 配置存在何处?

如果所有配置信息都放到了 package.json 中的话就在配置信息中有这样一段配置,没有的话手动配置;

1
2
3
4
5
6
7
8
9
10
11
12
1. 1
{
2. 2
"browserslist": ["> 1%",
3. 3
"last 2 versions",
4. 4
"not dead"
5. 5
]
6. 6
}

如果每个配置都被放到单独的一个文件中的话,创建完成的项目根目录下就会有这样一个文件.browserslistrc,其初始内容是这样的:

1
2
3
4
5
6
1. 1
> 1%
2. 2
last 2 versions
3. 3
not dead

3、 browserslist 的配置语句表达了什么?

>1%

基于全球使用率统计而选择的浏览器版本范围。>=,<,<=同样适用。

last 2 versions

最新的两个发行版本。

not dead

通过 last 2 versions 筛选的浏览器版本中,全球使用率低于 0.5%并且官方申明不再维护或者事实上已经两年没有在更新的版本,不再兼容这些版本。

4、browserslist 条件语句示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
1. 1
> 5%: 基于全球使用率统计而选择的浏览器版本范围。>=,<,<=同样适用。
2. 2
> 5% in US : 同上,只是使用地区变为美国。支持两个字母的国家码来指定地区。
3. 3
> 5% in alt-AS : 同上,只是使用地区变为亚洲所有国家。这里列举了所有的地区码。
4. 4
> 5% in my stats : 使用定制的浏览器统计数据。
5. 5
cover 99.5% : 使用率总和为99.5%的浏览器版本,前提是浏览器提供了使用覆盖率。
6. 6
cover 99.5% in US : 同上,只是限制了地域,支持两个字母的国家码。
7. 7
cover 99.5% in my stats :使用定制的浏览器统计数据。
8. 8
maintained node versions :所有还被 node 基金会维护的 node 版本。
9. 9
node 10 and node 10.4 : 最新的 node 10.x.x 或者10.4.x 版本。
10. 10
current node :当前被 browserslist 使用的 node 版本。
11. 11
extends browserslist-config-mycompany :来自browserslist-config-mycompany包的查询设置
12. 12
ie 6-8 : 选择一个浏览器的版本范围。
13. 13
Firefox > 20 : 版本高于20的所有火狐浏览器版本。>=,<,<=同样适用。
14. 14
ios 7 :ios 7自带的浏览器。
15. 15
Firefox ESR :最新的火狐 ESR(长期支持版) 版本的浏览器。
16. 16
unreleased versions or unreleased Chrome versions : alpha 和 beta 版本。
17. 17
last 2 major versions or last 2 ios major versions :最近的两个发行版,包括所有的次版本号和补丁版本号变更的浏览器版本。
18. 18
since 2015 or last 2 years :自某个时间以来更新的版本(也可以写的更具体since 2015-03或者since 2015-03-10)
19. 19
dead :通过last 2 versions筛选的浏览器版本中,全球使用率低于0.5%并且官方声明不在维护或者事实上已经两年没有再更新的版本。目前符合条件的有 IE10,IE_Mob 10,BlackBerry 10,BlackBerry 7,OperaMobile 12.1。
20. 20
last 2 versions :每个浏览器最近的两个版本。
21. 21
last 2 Chrome versions :chrome 浏览器最近的两个版本。
22. 22
defaults :默认配置> 0.5%, last 2 versions, Firefox ESR, not dead。
23. 23
not ie <= 8 : 浏览器范围的取反。
24. 24
可以添加not在任和查询条件前面,表示取反

5、环境差异化配置:

package.json 中配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1. 1
"browserslist": {
2. 2
"production": [
3. 3
"> 1%",
4. 4
"ie 10"
5. 5
],
6. 6
"development": [
7. 7
"last 1 chrome version",
8. 8
"last 1 firefox version"
9. 9
]
10. 10
}

.browserslistrc 中配置

1
2
3
4
5
6
7
8
9
10
11
12
13
1. 1
[production staging]
2. 2
> 1%
3. 3
ie 10
4. 4
5. 5
[development]
6. 6
last 1 chrome version
7. 7
last 1 firefox version

6、查看 browserslist 配置兼容的浏览器和 node 版本:

在项目的根目录下执行该命令 npx browserslist 来查看配置筛选后的浏览器和 node 版本列表。

1
npx browserslist

browserslist 是在不同的前端工具之间共用目标浏览器和 node 版本的配置工具,它本身之提供兼容的浏览器和 node 配置数据,这些配置还需要基于其他的实际功能插件产生作用,比如为 JS 转码的 babel 等。

1
2
3
4
5
6
7
8
9
10
11
12
1. 1
Autoprefixer
2. 2
Babel
3. 3
post-preset-env
4. 4
eslint-plugin-compat
5. 5
stylelint-unsupported-browser-features
6. 6
postcss-normalize

browerslist 衍生工具

  • browserslit-ga: 该工具能生成访问你运营的网站的浏览器的版本分布数据,以便用于类似> 0.5% in my stats查询条件, 前提是你运营的网站部署有 Google Analytics。
  • browserslist-useragent : 检验 某浏览器的 user-agent 字符串是否匹配 browserslist 给出的浏览器范围。
  • browserslist-useragent-ruby : 功能同上,ruby 库。
  • caniuse-api: 返回支持指定特性的浏览器版本范围
  • npx browserslist :在前端工程目录下运行上面命令,输出当前工程的目标浏览器列表。

虽然正常情况下这样就可以直接兼容,但是官方也做过说明

下面就是如何兼容 ie 的操作

Polyfill

#useBuiltIns: ‘usage’

一个默认的 Vue CLI 项目会使用 @vue/babel-preset-app,它通过 @babel/preset-envbrowserslist 配置来决定项目需要的 polyfill。

默认情况下,它会把 [useBuiltIns: 'usage'](https://new.babeljs.io/docs/en/next/babel-preset-env.html#usebuiltins-usage) 传递给 @babel/preset-env,这样它会根据源代码中出现的语言特性自动检测需要的 polyfill。这确保了最终包里 polyfill 数量的最小化。然而,这也意味着如果其中一个依赖需要特殊的 polyfill,默认情况下 Babel 无法将其检测出来。

有很多开发人员会遇到安装了 babel-polyfill 或者像上述一样做过之后依旧会报错

如果有依赖需要 polyfill,你有几种选择:

  1. 如果该依赖基于一个目标环境不支持的 ES 版本撰写: 将其添加到 vue.config.js 中的 [transpileDependencies](https://cli.vuejs.org/zh/config/#transpiledependencies) 选项。这会为该依赖同时开启语法转换和根据使用情况检测 polyfill。
  2. 如果该依赖交付了 ES5 代码并显式地列出了需要的 polyfill: 你可以使用 @vue/babel-preset-apppolyfills 选项预包含所需要的 polyfill。注意 **es.promise** 将被默认包含,因为现在的库依赖 Promise 是非常普遍的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1. 1
// babel.config.js
2. 2
module.exports = {
3. 3
presets: [
4. 4
['@vue/app', {
5. 5
polyfills: [
6. 6
'es.promise',
7. 7
'es.symbol'
8. 8
]
9. 9
}]
10. 10
]
11. 11
}

我们先直接打开项目在 IE 浏览器中运行看看能不能找到错误

我这个项目是使用 vue-cli4.x 版本创建的项目

在 ie 中运行报错

这个时候不要慌,点开错误看一下

找到错误的最后一行,我们可以看到错误的依赖包,因为项目中我安装了 base64 的插件

这个时候需要做下面这个操作   transpileDependencies

如果该依赖基于一个目标环境不支持的 ES 版本撰写: 将其添加到 vue.config.js 中的 [transpileDependencies](https://cli.vuejs.org/zh/config/#transpiledependencies) 选项。这会为该依赖同时开启语法转换和根据使用情况检测 polyfill。

在 vue.config.js 中配置,如果项目中没有 就在根目录中新建 vue.config.js 文件

1
transpileDependencies:['js-base64']

配置后重新运行

还是有错,继续点开继续看,重复上面的步骤

继续上面步骤

1
transpileDependencies:['js-base64','engine.io-client']

配置后再次重新运行

如果还有报错,重复上述步骤

大功告成,基本解决了兼容

vue-cli4.x 之后不需要手动安装babel/polyfill,vue-cli已经自带了

官网说明:https://cli.vuejs.org/zh/guide/browser-compatibility.html#usebuiltins-usage

browserslist里的东西不能省略,并不是说自己配置就不用在里面写需要兼容的浏览器,哪怕像官网所说的引入所有的polyfill一样,也是需要配置的

  1. **如果该依赖交付 ES5 代码,但使用了 ES6+ 特性且没有显式地列出需要的 polyfill (例如 Vuetify):****请使用 **useBuiltIns: 'entry'** 然后在入口文件添加 **import 'core-js/stable'; import 'regenerator-runtime/runtime';**。这会根据 **browserslist** 目标导入**所有 polyfill,这样你就不用再担心依赖的 polyfill 问题了,但是因为包含了一些没有用到的 polyfill 所以最终的包大小可能会增加。

更多细节可查阅 @babel/preset-env 文档

这只是一种兼容方案,还有很多种,需求探索,开发之路漫漫,踩坑需记录,沃日恁大姨。