跳到主要内容

vite-plugin-virtual-module

2023年12月20日
柏拉文
越努力,越幸运

一、认识


vite-plugin-virtual-module 用于加载虚拟模块。

作为构建工具,一般需要处理两种形式的模块,一种存在于真实的磁盘文件系统中,另一种并不在磁盘而在内存当中,也就是虚拟模块。通过虚拟模块,我们既可以把自己手写的一些代码字符串作为单独的模块内容,又可以将内存中某些经过计算得出的变量作为模块内容进行加载,非常灵活和方便。

二、实现


import { Plugin, ResolvedConfig } from 'vite';
// 虚拟模块名称
const virtualFibModuleId = 'virtual:fib';
// Vite 中约定对于虚拟模块,解析后的路径需要加上`\0`前缀
const resolvedFibVirtualModuleId = '\0' + virtualFibModuleId;

const virtualEnvModuleId = 'virtual:env';
const resolvedEnvVirtualModuleId = '\0' + virtualEnvModuleId;

export default function virtualModule(): Plugin {
let config: ResolvedConfig | null = null;

return {
name: 'vite-plugin-virtual-module',
configResolved(_config: ResolvedConfig) {
config = _config;
},
resolveId(importee: string | undefined) {
if (importee === virtualFibModuleId) {
return resolvedFibVirtualModuleId;
}

if (importee === virtualEnvModuleId) {
return resolvedEnvVirtualModuleId;
}
},
load(id: string) {
if (id === resolvedFibVirtualModuleId) {
return 'export default function fib(n) { return n <= 1 ? n : fib(n - 1) + fib(n - 2); }';
}

if (id === resolvedEnvVirtualModuleId) {
return `export default ${JSON.stringify(config!.env)}`;
}
}
};
}

三、配置


// vite.config.ts
import virtual from './plugins/virtual-module.ts'

// 配置插件
{
plugins: [react(), virtual()]
}

四、测试


4.1 类型声明

virtual:env 一般情况下会有类型问题,我们需要增加一个类型声明文件来声明这个模块:

// types/shim.d.ts
declare module 'virtual:*' {
export default any;
}

4.2 引入模块

main.tsx 中加入如下的代码:

import fib from 'virtual:fib';
import env from 'virtual:env';

console.log("env",env);
console.log("fib(10)",fib(10));