从rsbuild的unplugin-element-plugin的问题来看plugin-入门

284 阅读2分钟

入门插件分享

问题背景

当我把 rsbuild 升级到 1.3.20 之后,发现 unplugin-element-plus 的样式自动导入失效了。我马上切换到了 1.1.1(这个版本是我乱猜的),结果真没错,这个插件生效了。至于是从哪个版本开始改的,我没有试。

升级工具

在升级 rsbuild 时可以用这个工具:

taze - 升级 Rsbuild

调试过程

配置调试环境

我开始调试插件,如果是 rsbuild,直接修改 npm_modules 的代码就行了。

我使用的是 VSCode,在项目根目录建一个 .vscode 文件夹,新建一个 launch.json 文件:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "启动程序",
      "skipFiles": ["<node_internals>/**"],
      "program": "${workspaceFolder}/node_modules/@rsbuild/core/bin/rsbuild.js",
      "args": ["dev"],
      "env": {
        "NODE_OPTIONS": "DEBUG=rsbuild"
      },
      "outFiles": ["${workspaceFolder}/**/*.js"]
    }
  ]
}

然后按 F5(此时要 .vscode 在工作的根目录)就可以开始调试。

调试界面

经过一番研究,我把目光转移到这里。

Unplugin 介绍

这里要提一句 Unplugin 这个东西。我的理解就是将各个打包工具的方法抽象成一个方法,统一调用然后适配成 webpack、vite、rollup、rspack、esbuild 各家插件。

问题定位

核心方法是 createUnplugin => transform => transformStyle

核心方法

你会发现一个断点没进。这里逻辑很简单,就是在 import { Elxxx } from 'element-plus' 下面去引入它的样式。把断点移上去:

可以通过左边点击红点打断点(我比较喜欢写 debugger):

设置断点

然后你就会发现我要加样式的地方:

代码转换

它居然长这样,不应该是我的源码吗?

源码示例

<template>
  <ElDialog v-model="visible" title="标题" width="80%" :destroy-on-close="true" append-to-body>
    <div class="flex flex-col w-500px h-500px bg-red"></div>
    <ElButton @click="hide">关闭</ElButton>
  </ElDialog>
</template>

<script setup lang="ts">
import { ElDialog, ElButton } from 'element-plus'

const visible = ref<boolean>(false)

const show = () => {
  visible.value = true
}

const hide = () => {
  visible.value = false
}

defineExpose({
  show,
  hide,
})
</script>

<style lang="scss" scoped></style>

这里就找到 unplugin-element-plus 没有生效的原因了,这似乎是 vue-loader 处理后的结果。 好像是为了编译速度,拆分后可以按需加载

解决方案

经过两小时的研究,我想到:在它转换之前处理不就行了吗?

这个插件有个 enforce 参数。我去查了官网,vite 的插件执行顺序是这样的:

插件执行顺序

实施方案

最后,我把 unplugin-element-plus 拉下来,跑起来,引入它打包结果的包:

源码调试

这样就能通过源码调试:

pnpm dev  # "dev": "tsdown --watch"

enforce: 'post' 改成 pre,再去调试 source 看看是什么东西:

成功解决

太好啦,我们有救啦!

这样就变成了玩字符串,应该比较简单。然后就是去兼容 unplugin-element-plus 的参数,剩下的交给 AI 写,哈哈哈哈哈哈哈哈!

仓库地址

bubbles-show/rsbuild-unplugin-element at main · 435012357/bubbles-show