谈到 Vite,可能很多人都觉得这是一个现代前端构建工具,应该在现代浏览器中使用,放到各种语法特性都缺失的低版本浏览器(如 ie 11)就不适用了。这种观念对不对呢?首先跟大家抛出结论:
通过 Vite 构建我们完全可以兼容各种低版本浏览器,打包出既支持现代(
Modern)浏览器又支持旧版(Legacy)浏览器的产物。
接下里的课程中,我就来与你分析一下为什么在 Vite 中能够彻底解决低版本浏览器的兼容性问题,以及通过什么手段解决,需要借助哪些 JS 的工具和生态。你会领略到诸多前端编译工具链底层的风光,比如@babel/preset-env、core-js、regenerator-runtime等等工具和基础库是如何强强联合的,当然,我也会以官方的 Vite 插件@vitejs/plugin-legacy为例告诉你如何将这些底层的工具链接入到 Vite 中,并实现开箱即用的解决方案。
# 场景复现
首先我们来复现一下问题场景,下面两张图代表了之前我在线上环境真实遇到的报错案例:


某些低版本浏览器并没有提供 Promise 语法环境以及对象和数组的各种 API,甚至不支持箭头函数语法,代码直接报错,从而导致线上白屏事故的发生,尤其是需要兼容到IE 11、iOS 9以及Android 4.4的场景中很容易会遇到。
旧版浏览器的语法兼容问题主要分两类: 语法降级问题和 Polyfill 缺失问题。前者比较好理解,比如某些浏览器不支持箭头函数,我们就需要将其转换为function(){}语法;而对后者来说,Polyfill本身可以翻译为垫片,也就是为浏览器提前注入一些 API 的实现代码,如Object.entries方法的实现,这样可以保证产物可以正常使用这些 API,防止报错。
这两类问题本质上是通过前端的编译工具链(如Babel)及 JS 的基础 Polyfill 库(如corejs)来解决的,不会跟具体的构建工具所绑定。也就是说,对于这些本质的解决方案,在其它的构建工具(如 Webpack)能使用,在 Vite 当中也完全可以使用。
构建工具考虑的仅仅是如何将这些底层基础设施接入到构建过程的问题,自己并不需要提供底层的解决方案,正所谓术业有专攻,把专业的事情交给专业的工具去做。接下来的部分,我就来带你熟悉一下所谓专业的工具到底有哪些,以及如何使用这些工具。
# 底层工具链
# 1. 工具概览
解决上述提到的两类语法兼容问题,主要需要用到两方面的工具,分别包括:
- 编译时工具。代表工具有
@babel/preset-env和@babel/plugin-transform-runtime。 - 运行时基础库。代表库包括
core-js和regenerator-runtime。
编译时工具的作用是在代码编译阶段进行语法降级及添加 polyfill 代码的引用语句,如:
import "core-js/modules/es6.set.js"
由于这些工具只是编译阶段用到,运行时并不需要,我们需要将其将其放入package.json中的devDependencies中。
而运行时基础库是根据 ESMAScript官方语言规范提供各种Polyfill实现代码,主要包括core-js和regenerator-runtime两个基础库,不过在 babel 中也会有一些上层的封装,包括:
