入门插件分享
问题背景
当我把 rsbuild 升级到 1.3.20 之后,发现 unplugin-element-plus 的样式自动导入失效了。我马上切换到了 1.1.1(这个版本是我乱猜的),结果真没错,这个插件生效了。至于是从哪个版本开始改的,我没有试。
升级工具
在升级 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