虚拟模块的使用(vite插件开发)

228 阅读2分钟

背景

今天又重新看了 科比哥 写的一篇文章《点击页面元素,这个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 这个数据了。