Skyphobia

在 Vite 中使用 babel 插件

Front-Endvitebabelbabel-plugin-importantd

为什么要使用 babel 插件

熟悉 vite 或者 snowpack 这两个打包工具的同学应该知道,这两者都抛弃了开发环境(甚至可以是生产环境)打包代码后运行的思路,利用 JavaScript Module 以及基于现代浏览器对标准的支持,实现了快速构建项目的特性。

因为代码几乎直接运行在浏览器,所以似乎我们就不再那么需要 babel 了……吗?

答案显然是否定的。babel 除了将 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法外,也能做一些意想不到的事,比如常见的 babel-plugin-import,其主要功能是分析 import 的 ES Module,根据配置自动找到对应的 CSS 文件并导入;又如一些非常超前,现代浏览器还未支持的特性,比如 pipeline operator——依然需要 babel 的转译才能在浏览器中运行。

取舍

考虑到 Vite 的实现原理,babel 插手编译一定会大幅破坏 Vite 应有的性能,所以我们要先在这里做一个取舍。如果是上述 pipeline operator 的场景下,我们确实除了 babel 就别无选择了,但是 babel-plugin-import 有那么必要吗?

上述 babel-plugin-import 的例子里,我们其实是可以通过手动导入对应 CSS 文件的方式实现功能的:

entry.js

JavaScript
01import 'antd/lib/button/style/index.css'

component.jsx

JavaScript
01import { Button } from 'antd'

But!这显然不是一个好方法。原本 babel-plugin-import 解决的问题不仅仅是方便地自动引入 CSS 文件这件事,实际上它真正解决的是组件 JS 代码和 CSS 代码分开引入导致难以管理的问题

因此,在非常强烈地需要按需引入样式的时候,babel-plugin-import 还是必不可少的。

@rollup/plugin-babel

Vite 兼容大多数 rollup 插件,不介意性能影响的话可以直接无脑试试 @rollup/plugin-babel:

vite.config.js

JavaScript
01import babel from '@rollup/plugin-babel'
02
03export default defineConfig({
04 plugins: [
05 babel({
06 // 配置 babel-plugin-import 插件
07 plugins: [['import', {
08 libraryName: 'antd',
09 libraryDirectory: 'es',
10 style: 'css'
11 }]]
12 })
13 ]
14})

有些情况下可能还需要把 esbuild 设置为 false,因为 Vite 内部的 esbuild 会预处理一些代码——不过这就有点本末倒置了,真的希望有全功能自定义 babel 的需求,还是应该选择 webpack。