抛弃legacy,拥抱Babel
背景
公司项目使用Vite
+ Vue3
技术栈,为了兼容低版本浏览器,使用@vitejs/plugin-legacy
做代码转换,关于@vitejs/plugin-legacy
是如何做代码转换的,参考我的这篇文章。
不过@vitejs/plugin-legacy
存在以下几个问题:
- 速度太慢,生成两套代码真的很耗时间
- 动态加载兼容性代码在使用
wujie
等微前端框架时存在问题,无法正确加载兼容代码
基于此,笔者决定试试直接使用Babel转化代码,看看效果怎么样。
拥抱Babel
Babel是什么
如果你不知道Babel是什么,请参考这里
Babel 和 @vitejs/plugin-legacy
对比
@vitejs/plugin-legacy
内部使用Babel做代码转化从而兼容低版本浏览器
@vitejs/plugin-legacy
会向html文件中插入按需加载兼容代码的逻辑,只有在低版本浏览器中才加载兼容代码
如果使用Babel做转化,则没有按需加载兼容代码的能力,每次都是加载兼容代码,在高版本的浏览器中毫无疑问的需要加载更多代码
使用Babel做转换,不会动态加载兼容代码,在微前端框架中稳定性会更好
实操
安装babel插件
首先安装@rollup/plugin-babel
插件,此插件是一个Rollup插件,允许在Rollup中使用babel,因为Vite在打包时使用的就是Roolup,Vite官方也对部分主流Rollup插件做了兼容,所以此插件在Vite中可以放心使用。
pnpm add @rollup/plugin-babel -D
同时需要安装一些babel依赖:
pnpm add @babel/preset-env core-js@3 regenerator-runtime
注意 core-js
需要使用最新的3版本,regenerator-runtime
则用来做async、await语法转化
配置方法
首先需要在项目入口文件处加上如下两句:即引入polyfill
import 'core-js/stable';
import 'regenerator-runtime/runtime';
然后,在vite.config.ts
文件中删除@vitejs/plugin-legacy
插件,并在打包阶段加入@rollup/plugin-babel
插件
import { defineConfig } from 'vite';
import PostCssPresetEnv from 'postcss-preset-env';
import { babel } from '@rollup/plugin-babel';
export default defineConfig(() => {
return {
build: {
cssTarget: 'chrome70', // 注意添加css的低版本兼容,当然也可以配置PostCssPresetEnv
target: 'es2015', // 使用esbuild将代码转换为ES5
rollupOptions: {
plugins: [
// https://www.npmjs.com/package/@rollup/plugin-babel
babel({
babelHelpers: 'bundled',
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'entry', // 注意这里只能使用 entry
corejs: '3',
targets: 'last 2 versions and not dead, > 0.2%, Firefox ESR',
},
],
],
plugins: [],
compact: false,
}),
],
},
},
css: {
preprocessorOptions: {
css: { charset: false },
},
postcss: {
// 注意这里需要对css也做下低版本兼容,否则部分样式无法应用
plugins: [PostCssPresetEnv()],
},
},
};
});
使用以上配置,表示当前我们在构建阶段要使用Babel,其中有如下几点注意事项:
- 入口处必须导入polyfill相关文件
- babel的配置中
useBuiltIns
选项必须设置为entry
,不可使用usage
,使用后者会导致生成的兼容代码出问题,具体原因未知,有兴趣的小伙伴可以研究下。 - corejs版本写自己的安装版本,一般为3即可
build.target
需要配置为esbuild最低可转化版本es2015
,能低就低原则- 注意配置css的兼容方案,可以使用
postcss-preset-env
做降级,这是比较推荐的方式,当然也可以使用build.cssTarget
属性配置,具体配置方法参考这里
目前按照这一套下来是可以跑通,实现使用babel兼容低版本浏览器。
总结
本文介绍了一种在Vite中使用babel做低版本浏览器兼容的方法,亲测可行,但是在整个过程中遇到了很多阻力,比如:
- 不能使用babel中的
useBuiltIns: 'usage'
- css 也需要做兼容
- 入口处需要引入兼容库
- ...
不过最后好在完成了低版本浏览器兼容。
在这个过程中,笔者越来越觉着Vite在带来优秀的开发体验的同时,也同样引入了打包的高复杂度,高度的默认优化使得用户很难自己随心所欲的配置打包方案,开发和打包的差异性也让人很是担忧,不知道打包后的代码是否能正常运行,种种这些问题让我很是怀念webpack的打包时代。
每个新型事物的出现都会伴随着利弊,Vite还很新,它大幅优化了前端的开发体验,但也间接提高了打包复杂度。
市面上的打包器很多Vite、Webpack、Esbuild、Turbopack、Rspack ...,如何抉择还得看屏幕前的你了。
最后,加油吧,前端工程师们!期待有一天一个真正完美的打包器的问世,那将是美妙的一天。
来源:juejin.cn/post/7242220704288964666