Vite
相对于 Webpack
上手难度小,简单的配置,开箱即用。虽然目前生态不如 Webpack
,不过生态也逐渐的丰富起来。
经过了一些 Vite 插件编写实践,今天来说说虚拟模块(Virtual Modules ),也顺便介绍下 vite-plugin-project-info 插件。
虚拟模块的概念
【Vite 插件编写之虚拟模块】虚拟模块是 Vite
沿用 Rollup
的虚拟模块,虚拟模块类似 alias
别名,但是模块的内容并非直接从磁盘中读取,而是编译时生成。
虚拟模块是一种很实用的模式,使你可以对使用 ESM 语法的源文件传入一些编译时信息。虚拟模块实现例子 首先你可能需要先了解插件编写的 API。
这里直接搬运官网的例子:
export default function myPlugin() {
const virtualModuleId = 'virtual:my-module'
const resolvedVirtualModuleId = '\0' + virtualModuleIdreturn {
name: 'my-plugin',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `export const msg = "from virtual module"`
}
}
}
}
然后代码中引入这些模块:
import { msg } from 'virtual:my-module'console.log(msg)
实践分析:
vite-plugin-project-info
文章图片
vite-plugin-project-info
是 Vite 项目信息插件,使用后会在 Conole 面板输出版本、构建时间等信息。配合虚拟模块实现插件
- resolveId 钩子函数:真实虚拟模块 ID 转换为内部虚拟模块 ID。
- load 钩子函数:匹配内部虚拟模块 ID,并返回编译时的代码,最终实现了
virtual:project-info
模块。 - transform 钩子函数:实现自动
import
功能
截止第二步其实已经实现了虚拟模块的功能,但是我们
export default function projectInfoPlugin(opts: ProjectInfoPluginOptions = {}): PluginOption {
const { entry = path.resolve('src/main'), locale } = opts;
const lastEntry = entry.split('.')[0];
const virtualModuleId = 'virtual:project-info';
const resolvedVirtualModuleId = '\0' + virtualModuleId;
return {
name: 'vite:project-info',
enforce: 'pre',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId;
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return createCode({
locale,
});
}
},
transform(code, id) {
if (id.includes(path.resolve(lastEntry).replace(/\\/g, '/'))) {
return {
code: `import '${virtualModuleId}';
\n${code}`,
map: this.getCombinedSourcemap(),
};
}
},
};
}
功能使用
支持直接在浏览器 Console 中输出相关项目信息,同时支持如下代码使用:
import projectInfo from 'virtual:project-info';
console.log(projectInfo.version);
// 版本信息
console.log(projectInfo.buildTime);
// 构建时间
console.log(projectInfo.name);
// 项目名称
console.log(projectInfo.description);
// 项目描述
console.log(projectInfo.repository);
// 仓库链接
console.log(projectInfo.author);
// 项目负责人或者作者