背景
今天又重新看了 科比哥 写的一篇文章《点击页面元素,这个Vite插件帮我打开了Vue组件》。 其实这是我第二次接触虚拟模块,使用 UnoCSS 是我第一次虚拟模块(需要在程序主入口函数做下面的导入)
// main.ts
import 'virtual:uno.css'
怎么做
其实我们只要知道 vite 插件的两个阶段就行。
- resolveId
- load
resolveId 阶段 用于解析模块的导入请求(import requests)。当 Vite 在编译过程中遇到模块导入时,会调用插件的 resolveId 方法来处理这些导入请求。
async resolveId(source) {
if (source === 'my-module') {
// 返回 my-module.js 的绝对路径,告诉 Vite 如何定位这个模块
return path.resolve(__dirname, 'src/my-module.js');
}
}
source !== 'my-module' 的话,对其他模块路径进行默认处理,交由 Vite 处理。
load 阶段 用于加载模块的源代码。当 Vite 在编译过程中需要获取模块的源代码时,会调用插件的 load 方法来获取模块的内容。
上面的 resolveId 并没有处理虚拟模块,下面举一个处理虚拟模块的例子
来自 vite 官网的案例
export default function myPlugin() {
const virtualModuleId = 'virtual:my-module'
const resolvedVirtualModuleId = '\0' + virtualModuleId
return {
name: 'my-plugin', // 必须的,将会在 warning 和 error 中显示
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `export const msg = "from virtual module"`
}
},
}
}
在 resolveId 阶段的过程,我认为是下面这样
import "virtual:my-module" -> vite 插件捕捉到,进行处理获得处理结果,告诉 vite 你要导入的资源的位置是处理结果
这样的话避免了,在
load阶段其他插件处理这个 id
然后 load 阶段,捕捉到了这个虚拟模块,返回了这个虚拟模块的内容。这样的话,我们就能导入了虚拟模块的文件中使用 msg 这个数据了。