轻松玩转Vite/Rollup/webpack/esbuild/Rspack/babel插件开发(一)

大家好,我是VoerkaI18n前端多语言解决方案的作者,以下是我的一波开源项目:

我来给大家分享一下提高自己前端技术段位的一些小技能。

每个前端开发均会使用到Vite/Rollup/webpack/esbuild/Rspack/babel等前端代码编译工具库,前端代码编译工具负责进行源代码的转译、打包、压缩等工作。
现代主流的前端编译工具一般设计为由一个编译核心+若干扩展插件的形式,从而形成一个庞大的生态系统。编译核心主要负责AST生成编译生命周期管理,以及插件子系统。而大部份的功能均尽可能使用扩展插件来实现。

一般情况下,我们只需要使用各编译工作生态内的扩展插件就可以了,但总有一些自动化功能无法满足,或者无法找到合适的插件,此时就需要自已开发一个对应的Vite/Rollup/webpack/esbuild/Rspack/babel插件。

如何开发编译插件

那么如何开发一个Vite/Rollup/webpack/esbuild/Rspack/babel插件呢?一般来讲,我们需要了解以下知识:

Rollup为例:

  • 首先我们得了解编译机制和编译生命周期

下图是Rollup的编译流程以及命令周期钩子事件,我们得搞懂Rollup是如何对源代码进行编译, 每个环节分别负责什么,每个插件钩子的参数是什么等等等,这样我们才能够在合适时机注册钩子进行各种操作。
在这里插入图片描述
从我个人的角度看,要完全掌握Rollup编译流程中的各项细节也是要耗不少精力的。

  • 接着找到合适的插件扩展点

接下来,我们得了解编译生命周期和流程中的各个钩子的声明、参数以及作用机制等,然后选择一个合适的插件扩展点,注册插件进行处理。

  • 操纵源代码
    最后在插件代码里面就可以对源码进行各种骚操作了。要操作源代码一般不可避免地会涉及到正则表达式、AST抽象语法树等知识。

通用构建插件开发神器

对于库开源者而言,要让自己开发的库在不同场景下均可以使用,就要分别开发Vite/Rollup/webpack/esbuild/Rspack/babel插件,想想要花很大的精力去了解各个编译工具的插件开发机制,实在是耗时又耗力。

以笔者开发的VoerkaI18n多语言解决方案为例,就分别开发babelvitewebpack三种插件。为了开发这三种不同的插件,笔者也不得已花了不小的时间来了解相应的知识。

现在好了,知名的开源组织unjs(知名大神Antfu就是该组织成员)为我们贡献了一个通用构建插件系统 -Unplugin
Unplugin提供了一个非常简单的API,适配Vite/Rollup/webpack/esbuild/Rspack/,只需要开发一个unplugin就可以输出Vite/Rollup/webpack/esbuild/Rspack/插件。

unplugin支持以下hook
在这里插入图片描述

最简单用法就是使用transformIncludetransform进行转码,

  • transformInclude(id):用来匹配哪一个文件要进行转码。
  • transform(code): 输入源代码字符串,返回转码后的源代码。

开发unplugin非常简单,如下:

import type { UnpluginFactory } from 'unplugin'
import { createUnplugin } from 'unplugin'

export interface Options {
  // define your plugin options here
}

export const unpluginFactory: UnpluginFactory<Options | undefined> = options => ({
  name: 'unplugin-starter',
  // webpack's id filter is outside of loader logic,
  // an additional hook is needed for better perf on webpack
  transformInclude(id) {
    return id.endsWith('main.ts')
  },
  // just like rollup transform
  transform(code) {
    return code.replace(/<template>/, '<template><div>Injected</div>')
  },
  // more hooks coming
})

export const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)

export default unplugin

export const vitePlugin = unplugin.vite
export const rollupPlugin = unplugin.rollup
export const webpackPlugin = unplugin.webpack
export const rspackPlugin = unplugin.rspack
export const esbuildPlugin = unplugin.esbuild```

小结

使用unplugin通过transformIncludetransform两个API就可以非常容易实现转码功能。

接下插件需要处理的就是如何对transform传入的code进行处理的问题。

本系列接下来将分别介绍几种处理源代码的方法:

  • 正则表达式匹配处理
  • AST抽象语法树
  • ast-grep(sg)
  • EasyAST
  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值