Vite插件开发框架:14个实用插件与完整工具包

版本:0.1.9 | 一个为 Vite 提供实用插件的工具包,同时也是一个完整的插件开发框架


项目概览

@meng-xi/vite-plugin 是一个功能丰富的 Vite 插件工具包,提供了 14 个开箱即用的构建插件 和一套 完整的插件开发框架。它同时支持 ESM 和 CJS 两种模块格式,兼容 Vite 5.x ~ 7.x。

安装

bash 复制代码
npm install @meng-xi/vite-plugin

快速使用

typescript 复制代码
// vite.config.ts
import { assetManifest, autoImport, buildProgress, compressAssets, envGuard, generateVersion, versionUpdateChecker } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [
		buildProgress(),
		autoImport({ imports: { vue: ['ref', 'reactive'] } }),
		compressAssets({ algorithm: 'both' }),
		generateVersion({ format: 'datetime', outputType: 'both' }),
		versionUpdateChecker(),
		envGuard({
			required: { VITE_API_URL: { type: 'url', required: true } }
		})
	]
})

子路径导入

支持按需导入,减小打包体积:

typescript 复制代码
import { assetManifest } from '@meng-xi/vite-plugin/plugins/asset-manifest'
import { formatFileSize } from '@meng-xi/vite-plugin/common/format'
import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin/factory'

插件开发框架

框架层提供了插件开发的基石------BasePlugin 抽象基类、createPluginFactory 工厂函数和 Logger 日志系统,让开发者可以快速构建规范化的 Vite 插件。

BasePlugin 抽象基类

BasePlugin 是所有插件的基类,封装了插件配置管理、日志记录、生命周期管理、错误处理等核心功能。

核心能力
能力 说明
配置合并 自动将用户配置与默认配置深度合并
参数校验 内置 Validator 链式 API,支持类型、范围、枚举等校验
日志管理 每个插件拥有独立的日志代理,支持按插件开关日志
错误处理 三种错误策略:throw(中断)、log(记录)、ignore(忽略)
生命周期 configResolved → 自定义钩子 → closeBundle(自动销毁)
安全执行 safeExecute / safeExecuteSync 包裹,异常不中断构建
基础配置项(BasePluginOptions)
typescript 复制代码
interface BasePluginOptions {
	enabled?: boolean // 是否启用插件,默认 true
	verbose?: boolean // 是否启用日志,默认 true
	errorStrategy?: 'throw' | 'log' | 'ignore' // 错误处理策略,默认 'throw'
}
继承示例
typescript 复制代码
import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin/factory'

class MyPlugin extends BasePlugin<MyPluginOptions> {
	protected getPluginName() {
		return 'my-plugin'
	}
	protected getDefaultOptions() {
		return { myOption: 'default' }
	}
	protected validateOptions() {
		this.validator.field('myOption').string().validate()
	}
	protected addPluginHooks(plugin: Plugin) {
		plugin.writeBundle = async () => {
			await this.safeExecute(() => this.doWork(), '执行工作')
		}
	}
}

export const myPlugin = createPluginFactory(MyPlugin)

createPluginFactory 工厂函数

将插件类转换为 Vite 插件工厂函数,支持选项标准化器(normalizer),允许用户以简写形式传参。

typescript 复制代码
// 基本用法
const myPlugin = createPluginFactory(MyPlugin)

// 带标准化器(支持字符串或对象配置)
const myPlugin = createPluginFactory(MyPlugin, opt => (typeof opt === 'string' ? { path: opt } : opt))

工厂函数返回的 Vite 插件对象上会挂载 pluginInstance 属性,允许外部访问插件内部状态:

typescript 复制代码
const plugin = myPlugin({ myOption: 'test' })
// 构建完成后访问插件实例
const instance = plugin.pluginInstance

Logger 日志系统

单例模式的日志管理器,统一管理所有插件的日志输出。

特性
  • 单例模式:全局唯一实例,避免日志重复输出
  • 插件隔离:每个插件拥有独立的日志代理,可单独开关
  • 彩色输出 :四种日志类型带不同颜色和图标
    • success --- 绿色 ✅
    • info --- 青色 ℹ️
    • warn --- 黄色 ⚠️
    • error --- 红色 ❌
  • 自动管理:插件销毁时自动注销日志配置
使用方式
typescript 复制代码
import { Logger } from '@meng-xi/vite-plugin/logger'

// 创建日志记录器
const logger = Logger.create({ name: 'my-plugin', enabled: true })

// 创建插件日志代理
const pluginLogger = logger.createPluginLogger('my-plugin')
pluginLogger.success('操作成功')
pluginLogger.info('处理中...')
pluginLogger.warn('注意')
pluginLogger.error('出错了')

// 注销插件日志
Logger.unregister('my-plugin')

// 销毁单例(测试场景)
Logger.destroy()

通用工具模块

@meng-xi/vite-plugin/common 导出了一系列通用工具函数,可供外部直接使用。

子模块 路径 功能说明
concurrency common/concurrency 并发控制工具(runWithConcurrency
format common/format 格式化工具(formatFileSizeformatDate
fs common/fs 文件系统工具(writeFileContentshouldUpdateFileContentcheckSourceExistscopySourceToTarget
html common/html HTML 操作工具(injectBeforeTaginjectHeadAndBody、安全过滤、选择器匹配)
path common/path 路径处理工具(normalizePath
script common/script 脚本处理工具
ui common/ui 终端 UI 工具(ANSI 控制码)
validation common/validation 校验工具(Validator 链式 API、validateGlobalNamevalidateNoScriptInTemplate

Vite 插件集合

assetManifest --- 资源清单生成

在构建完成后自动扫描输出目录,生成资源映射清单文件,支持 Vite 标准、Webpack 兼容和自定义三种格式。

核心功能
  • 三种输出格式:vite(标准映射)、webpack(兼容格式)、custom(自定义格式化器)
  • 按入口分组资源(groupByEntry
  • 运行时注入:将清单注入到 HTML 中作为全局变量
  • 文件过滤:支持按扩展名和路径排除
配置项
typescript 复制代码
interface AssetManifestOptions extends BasePluginOptions {
	outputFormat?: 'vite' | 'webpack' | 'custom' // 清单格式,默认 'vite'
	outputFile?: string // 输出文件名,默认 'manifest.json'
	includeExtensions?: string[] // 包含的扩展名
	publicPath?: string // 公共路径前缀,默认 '/'
	injectRuntime?: boolean // 注入运行时全局变量,默认 false
	runtimeGlobalName?: string // 全局变量名,默认 '__ASSET_MANIFEST__'
	customFormatter?: CustomFormatter | null // 自定义格式化器
	groupByEntry?: boolean // 按入口分组,默认 false
	excludeExtensions?: string[] // 排除的扩展名
	excludePaths?: string[] // 排除的路径
}
使用示例
typescript 复制代码
assetManifest({
	outputFormat: 'vite',
	publicPath: 'https://cdn.example.com/',
	injectRuntime: true,
	groupByEntry: true
})
实例方法
  • getAssetMap() --- 获取资源映射表
  • getManifest() --- 获取清单数据(仅 vite 格式)
  • getGroups() --- 获取按入口分组信息

autoImport --- 自动导入

自动注入 import 语句的 Vite 插件,支持预设映射和目录扫描两种方式,可选生成 TypeScript 类型声明文件。

核心功能
  • 预设映射:配置模块→标识符的映射关系,自动注入 import 语句
  • 目录扫描:递归扫描指定目录,自动发现并注册导出
  • Vue 模板支持:自动导入 Vue SFC 模板中使用的 API
  • 类型声明生成 :自动生成 .d.ts 文件,提供 TypeScript 类型提示
  • 智能去重:跳过已显式导入的标识符
  • 注入位置控制:支持顶部注入或最后一个 import 后注入
配置项
typescript 复制代码
interface AutoImportOptions extends BasePluginOptions {
  imports?: Record<string, string[]> | ImportMapping[] | Array<...>  // 导入映射
  dirs?: string[]                           // 扫描目录列表
  dts?: string | boolean                    // 类型声明文件路径,默认 'src/auto-imports.d.ts'
  vueTemplate?: boolean                     // Vue 模板自动导入,默认 false
  ignore?: string[]                         // 忽略的标识符
  fileFilter?: RegExp                       // 文件过滤正则
  injectAtPosition?: 'top' | 'after-last-import'  // 注入位置,默认 'top'
}
使用示例
typescript 复制代码
autoImport({
	imports: {
		vue: ['ref', 'reactive', 'computed', 'watch', 'onMounted'],
		'vue-router': ['useRouter', 'useRoute']
	},
	dirs: ['src/composables', 'src/stores'],
	dts: 'src/auto-imports.d.ts',
	vueTemplate: true,
	injectAtPosition: 'after-last-import'
})
实例方法
  • getResolvedImports() --- 获取所有解析后的导入映射
  • getNameLookup() --- 获取名称查找映射表

buildProgress --- 构建进度条

在终端实时显示构建进度,支持三种显示格式和自定义颜色主题。

核心功能
  • 三种格式bar(完整进度条)、spinner(旋转动画)、minimal(精简模式)
  • 实时追踪:基于 Vite 生命周期钩子追踪构建各阶段进度
  • 模块名称显示:transform 阶段显示当前处理的模块
  • 自定义主题:可自定义各部分颜色
  • TTY 降级:非 TTY 环境(如 CI/CD)自动降级为日志输出
进度计算
复制代码
config (5%) → resolve (10%) → transform (15%-85%) → bundle (+10%) → write (+5%) → done (100%)
配置项
typescript 复制代码
interface BuildProgressOptions extends BasePluginOptions {
	width?: number // 进度条宽度,默认 30
	format?: 'bar' | 'spinner' | 'minimal' // 显示格式,默认 'bar'
	completeChar?: string // 完成填充字符,默认 '█'
	incompleteChar?: string // 未完成填充字符,默认 '░'
	clearOnComplete?: boolean // 完成后清除,默认 true
	showModuleName?: boolean // 显示模块名,默认 true
	theme?: ProgressTheme // 自定义颜色主题
}
使用示例
typescript 复制代码
// 默认进度条
buildProgress()

// 旋转动画
buildProgress({ format: 'spinner' })

// 自定义外观
buildProgress({
	width: 40,
	completeChar: '■',
	incompleteChar: '□',
	clearOnComplete: false
})

bundleAnalyzer --- 构建产物分析

在构建完成后分析产物体积分布、模块依赖等关键指标,生成 JSON 报告和 HTML 可视化图表。

核心功能
  • 体积分析:统计 chunk 和模块的原始体积及 gzip 体积
  • 模块排行:Top N 大模块排行
  • 文件类型分布:按扩展名分类统计体积占比
  • 体积阈值告警:超过阈值自动告警
  • 构建对比:与上次构建结果对比,显示增减变化
  • HTML 可视化:支持 treemap、sunburst、list 三种图表
配置项
typescript 复制代码
interface BundleAnalyzerOptions extends BasePluginOptions {
	outputFormat?: 'json' | 'html' | 'both' // 报告格式,默认 'json'
	outputFile?: string // 输出文件名,默认 'bundle-analysis'
	openAnalyzer?: boolean // 自动打开报告,默认 false
	sizeThreshold?: number // 体积阈值(KB),默认 100
	topModules?: number // Top N 数量,默认 20
	compareWith?: string | null // 对比报告路径
	gzipSize?: boolean // 计算 gzip 大小,默认 true
	excludeNodeModules?: boolean // 排除 node_modules,默认 false
	excludePatterns?: string[] // 排除的路径模式
	includeExtensions?: string[] // 包含的扩展名
	defaultChartType?: 'treemap' | 'sunburst' | 'list' // 图表类型,默认 'treemap'
}
使用示例
typescript 复制代码
bundleAnalyzer({
	outputFormat: 'both',
	sizeThreshold: 200,
	topModules: 30,
	gzipSize: true,
	compareWith: 'bundle-analysis-prev.json',
	defaultChartType: 'treemap'
})
实例方法
  • getResult() --- 获取分析结果

compressAssets --- 构建产物压缩

在构建完成后自动压缩输出目录中的文件,支持 gzip 和 brotli 两种算法。

核心功能
  • 双算法支持 :gzip(.gz)和 brotli(.br),可同时使用
  • 并发压缩:可配置并发数,充分利用多核 CPU
  • 文件过滤:按扩展名和路径过滤
  • 压缩报告:生成 JSON 格式的压缩统计报告
  • 原始文件删除:可选删除原始文件,仅保留压缩版本
配置项
typescript 复制代码
interface CompressAssetsOptions extends BasePluginOptions {
	algorithm?: 'gzip' | 'brotli' | 'both' // 压缩算法,默认 'gzip'
	threshold?: number // 最小阈值(字节),默认 1024
	deleteOriginalFile?: boolean // 删除原始文件,默认 false
	includeExtensions?: string[] // 包含的扩展名
	excludeExtensions?: string[] // 排除的扩展名
	excludePaths?: string[] // 排除的路径
	compressionLevel?: number // gzip 级别 1-9,默认 9
	brotliQuality?: number // brotli 质量 1-11,默认 11
	reportOutput?: string | false // 报告路径,默认 'compress-report.json'
	parallelLimit?: number // 并发数,默认 10
}
使用示例
typescript 复制代码
compressAssets({
	algorithm: 'both',
	threshold: 2048,
	compressionLevel: 9,
	brotliQuality: 11,
	reportOutput: 'compress-report.json'
})
实例方法
  • getStats() --- 获取所有文件的压缩统计
  • getSummary() --- 获取压缩汇总信息

copyFile --- 文件复制

在构建完成后将指定源目录的文件复制到目标目录,支持增量复制。

核心功能
  • 增量复制:仅复制有变动的文件,跳过未变化的文件
  • 递归复制:支持子目录递归
  • 覆盖控制:可配置是否覆盖同名文件
配置项
typescript 复制代码
interface CopyFileOptions extends BasePluginOptions {
	sourceDir: string // 源目录(必填)
	targetDir: string // 目标目录(必填)
	overwrite?: boolean // 覆盖同名文件,默认 true
	recursive?: boolean // 递归复制,默认 true
	incremental?: boolean // 增量复制,默认 true
}
使用示例
typescript 复制代码
copyFile({
	sourceDir: 'src/assets',
	targetDir: 'dist/assets',
	overwrite: false,
	incremental: true
})

envGuard --- 环境变量守卫

在构建前校验环境变量的存在性和合法性,支持多种值类型校验、正则匹配和自定义校验函数。

核心功能
  • 多种校验类型stringnumberurlbooleanenumjsonsemverpath
  • 范围约束minValue/maxValueminLength/maxLength
  • 正则匹配pattern 正则校验
  • 自定义校验validator 自定义校验函数
  • 失败处理 :三种策略------error(中断)、warn(警告)、ignore(忽略)
  • 模板生成 :自动生成 .env.template 文件
  • 运行时守卫:注入到 HTML 中,在浏览器端校验环境变量
  • 自动加载 :自动加载 .env 文件
配置项
typescript 复制代码
interface EnvGuardOptions extends BasePluginOptions {
	required?: Record<string, EnvFieldRule> // 校验规则映射
	failAction?: 'error' | 'warn' | 'ignore' // 失败处理,默认 'error'
	generateTemplate?: boolean // 生成模板,默认 true
	templateOutput?: string // 模板路径,默认 '.env.template'
	runtimeGuard?: boolean // 运行时守卫,默认 false
	runtimeGlobalName?: string // 全局变量名,默认 '__ENV_GUARD__'
	runtimeGuardMode?: 'console' | 'throw' | 'overlay' // 守卫模式
	envFiles?: string[] // .env 文件列表
	autoLoadEnv?: boolean // 自动加载,默认 true
	reportOutput?: string | false // 报告路径
	validateBeforeBuild?: boolean // 构建前校验,默认 true
	showSummary?: boolean // 显示摘要,默认 true
}
使用示例
typescript 复制代码
envGuard({
	required: {
		VITE_API_BASE_URL: { type: 'url', required: true, message: 'API 地址必须为合法 URL' },
		VITE_APP_TITLE: { type: 'string', required: true, minLength: 1, maxLength: 50 },
		VITE_API_TIMEOUT: { type: 'number', minValue: 1000, maxValue: 60000 },
		VITE_LOG_LEVEL: { type: 'enum', enumValues: ['debug', 'info', 'warn', 'error'] }
	},
	failAction: 'error',
	generateTemplate: true,
	runtimeGuard: true,
	runtimeGuardMode: 'console'
})
实例方法
  • getResult() --- 获取校验结果
  • getValidationResults() --- 获取校验结果详情列表

faviconManager --- 网站图标管理

管理 favicon 及其他图标链接的注入和文件复制,支持多种配置方式。

核心功能
  • 多种配置方式 :自定义 link 标签 > 完整 URL > base 路径 + 默认 favicon
  • 多图标支持 :通过 icons 数组配置多种尺寸和格式的图标
  • 文件复制:可选将图标文件复制到构建输出目录
  • 简写配置:支持字符串形式传入 base 路径
配置项
typescript 复制代码
interface FaviconManagerOptions extends BasePluginOptions {
	base?: string // 基础路径,默认 '/'
	url?: string // 完整图标 URL
	link?: string // 自定义 link 标签 HTML
	icons?: Icon[] // 图标数组
	copyOptions?: {
		// 文件复制配置
		sourceDir: string
		targetDir: string
		overwrite?: boolean
		recursive?: boolean
	}
}
使用示例
typescript 复制代码
// 简写
faviconManager('/assets')

// 完整配置
faviconManager({
	base: '/assets',
	icons: [
		{ rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml' },
		{ rel: 'icon', href: '/favicon-32x32.png', sizes: '32x32', type: 'image/png' }
	],
	copyOptions: {
		sourceDir: 'src/assets/icons',
		targetDir: 'dist/assets/icons'
	}
})

generateRouter --- 路由配置生成

读取 uni-app 项目的 pages.json 文件,自动生成路由配置文件。

核心功能
  • 自动解析 :从 pages.json 解析主包和子包页面
  • tabBar 识别:自动标记 tabBar 页面
  • 多种命名策略pathcamelCasepascalCasecustom
  • 元信息映射:将页面 style 字段映射到路由 meta
  • 变更保留:保留用户对路由配置的手动修改
  • 文件监听 :开发模式下自动监听 pages.json 变化
  • 类型声明 :可选生成 .d.ts 类型声明文件
配置项
typescript 复制代码
interface GenerateRouterOptions extends BasePluginOptions {
	pagesJsonPath?: string // pages.json 路径,默认 'src/pages.json'
	outputPath?: string // 输出路径,默认 'src/router.config.ts'
	outputFormat?: 'ts' | 'js' // 输出格式,默认 'ts'
	nameStrategy?: NameStrategy // 命名策略,默认 'camelCase'
	customNameGenerator?: (path: string) => string // 自定义命名函数
	includeSubPackages?: boolean // 包含子包,默认 true
	watch?: boolean // 监听变化,默认 true
	metaMapping?: Record<string, string> // 元信息映射
	exportTypes?: boolean // 导出类型定义,默认 true
	preserveRouteChanges?: boolean // 保留用户修改,默认 true
	dts?: string | boolean // 类型声明文件路径,默认 false
}
使用示例
typescript 复制代码
generateRouter({
	pagesJsonPath: 'src/pages.json',
	outputPath: 'src/router.config.ts',
	nameStrategy: 'camelCase',
	metaMapping: {
		navigationBarTitleText: 'title',
		requireAuth: 'requireAuth'
	},
	dts: true
})

generateVersion --- 版本号生成

在构建过程中自动生成版本号,支持多种格式和输出方式。

核心功能
  • 六种格式timestampdatedatetimesemverhashcustom
  • 三种输出file(文件)、define(全局变量)、both(两者)
  • 自定义模板 :支持占位符 {YYYY}{MM}{DD}{HH}{mm}{ss}{timestamp}{hash}
  • 前缀后缀:支持添加版本号前缀和后缀
  • 附加信息 :通过 extra 选项添加自定义字段
配置项
typescript 复制代码
interface GenerateVersionOptions extends BasePluginOptions {
	format?: VersionFormat // 版本格式,默认 'timestamp'
	customFormat?: string // 自定义格式模板
	semverBase?: string // semver 基础值,默认 '1.0.0'
	outputType?: 'file' | 'define' | 'both' // 输出类型,默认 'file'
	outputFile?: string // 输出文件名,默认 'version.json'
	defineName?: string // 全局变量名,默认 '__APP_VERSION__'
	hashLength?: number // 哈希长度,默认 8
	prefix?: string // 前缀
	suffix?: string // 后缀
	extra?: Record<string, any> // 附加信息
}
使用示例
typescript 复制代码
// 时间戳格式 + 文件输出
generateVersion({ format: 'timestamp' })

// semver + 全局变量注入
generateVersion({ format: 'semver', semverBase: '2.0.0', prefix: 'v', outputType: 'define' })

// 自定义格式 + 双输出
generateVersion({
	format: 'custom',
	customFormat: '{YYYY}.{MM}.{DD}-{hash}',
	hashLength: 6,
	outputType: 'both',
	extra: { environment: 'production' }
})

htmlInject --- HTML 内容注入

根据配置规则将自定义 HTML 内容注入到目标 HTML 文件中,支持多种注入位置和条件注入。

核心功能
  • 多种注入位置head-starthead-endbody-startbody-end、CSS 选择器前后
  • 条件注入:基于环境变量等条件决定是否注入
  • 模板变量 :支持 {``{varName}} 占位符替换
  • 安全过滤:自动过滤危险标签和属性,防止 XSS 攻击
  • 优先级控制 :通过 priority 控制规则执行顺序
  • 选择器匹配:支持 CSS 选择器精确定位注入位置
配置项
typescript 复制代码
interface HtmlInjectOptions extends BasePluginOptions {
	targetFile?: string // 目标 HTML 文件,默认 'index.html'
	rules: InjectRule[] // 注入规则数组(必填)
	security?: SecurityConfig // 安全过滤配置
	templateVars?: Record<string, string> // 全局模板变量
	logInjection?: boolean // 输出注入日志,默认 true
}

interface InjectRule {
	id?: string // 规则标识
	content: string // 注入内容
	position: InjectPosition // 注入位置
	selector?: string // CSS 选择器
	priority?: number // 优先级
	condition?: InjectCondition // 条件配置
	templateVars?: Record<string, string> // 规则级模板变量
	allowScriptInjection?: boolean // 允许注入 script,默认 false
}
使用示例
typescript 复制代码
htmlInject({
	rules: [
		{
			id: 'meta-description',
			content: '<meta name="description" content="{{appName}}">',
			position: 'head-end',
			templateVars: { appName: 'My Application' }
		},
		{
			id: 'analytics',
			content: '<script src="/analytics.js"></script>',
			position: 'body-end',
			condition: { type: 'env', value: 'PRODUCTION' },
			allowScriptInjection: true
		}
	]
})
实例方法
  • getInjectionLogs() --- 获取注入日志

imageOptimizer --- 图片优化

在构建完成后自动优化输出目录中的图片文件,使用 sharp 和 svgo 进行压缩和格式转换。

核心功能
  • 七种格式压缩:JPEG、PNG、WebP、AVIF、GIF、TIFF、SVG
  • 格式转换:位图格式之间的相互转换(如 PNG → WebP、JPEG → AVIF)
  • 并发处理:可配置并发数
  • 体积守恒:仅当优化后体积更小时才替换原文件
  • 原子写入:先写临时文件再重命名,确保异常安全
  • 优雅降级:sharp/svgo 不可用时提供清晰提示
  • SVG 优化:通过 svgo 插件配置精确控制 SVG 优化
配置项
typescript 复制代码
interface ImageOptimizerOptions extends BasePluginOptions {
	quality?: FormatQualityOptions // 各格式压缩质量
	convertToWebp?: Partial<Record<'jpeg' | 'png' | 'gif' | 'tiff', boolean>> // 转 WebP
	convertToAvif?: Partial<Record<'jpeg' | 'png' | 'gif' | 'tiff', boolean>> // 转 AVIF
	convertMapping?: ConvertMapping // 自定义转换映射(优先级更高)
	svgo?: SvgoOptions // SVG 优化配置
	includeExtensions?: string[] // 包含的扩展名
	excludePaths?: string[] // 排除的路径
	threshold?: number // 最小阈值(字节),默认 0
	keepOriginal?: boolean // 保留原文件,默认 true
	reportOutput?: string | false // 报告路径
	parallelLimit?: number // 并发数,默认 5
	maxPixels?: number // 最大像素数,0 不限制
}
使用示例
typescript 复制代码
// 仅压缩
imageOptimizer({
	quality: { jpeg: 80, png: 6, webp: 75 },
	reportOutput: 'image-optimize-report.json'
})

// PNG/JPEG → WebP 转换
imageOptimizer({
	convertToWebp: { png: true, jpeg: true },
	keepOriginal: true,
	quality: { webp: 75 }
})

// SVG 优化
imageOptimizer({
	svgo: {
		plugins: [
			{ name: 'removeViewBox', active: false },
			{ name: 'removeEmptyContainers', active: true }
		],
		multipass: true
	}
})
实例方法
  • getStats() --- 获取所有文件的优化统计
  • getSummary() --- 获取优化汇总信息

loadingManager --- 全局 Loading 状态管理

在 HTML 中注入全局 Loading 状态管理代码,提供创建、显示、隐藏和销毁 loading 的完整能力。

核心功能
  • 四种内置图标spinnerdotspulsebar
  • 请求自动拦截 :自动拦截 fetch/XHR 请求管理 loading 状态
  • 请求过滤:排除/包含特定 URL、前缀匹配、方法过滤
  • 过渡动画:淡入淡出效果,可配置时长和缓动函数
  • 防闪烁机制 :延迟显示(delayShow)+ 最小显示时间(minDisplayTime)+ 防抖隐藏(debounceHide
  • 白屏 LoadingdefaultVisible + autoHideOn 实现白屏阶段即显示
  • 背景模糊 :支持 backdrop-filter 模糊效果
  • 生命周期回调onBeforeShowonShowonBeforeHideonHideonDestroy
  • 自定义模板:支持完全自定义 loading HTML
  • SSR 安全:自动检测 SSR 环境
配置项
typescript 复制代码
interface LoadingManagerOptions extends BasePluginOptions {
	position?: 'center' | 'top' | 'bottom' // 显示位置,默认 'center'
	defaultText?: string // 默认文本,默认 '加载中...'
	spinnerType?: SpinnerType // 图标类型,默认 'spinner'
	style?: LoadingStyle // 自定义样式
	transition?: TransitionConfig // 过渡动画
	minDisplayTime?: MinDisplayTime // 最小显示时间
	delayShow?: DelayShow // 延迟显示
	debounceHide?: DebounceHide // 防抖隐藏
	autoBind?: AutoBindMode // 自动拦截模式,默认 'none'
	requestFilter?: RequestFilter // 请求过滤
	globalName?: string // 全局变量名,默认 '__LOADING_MANAGER__'
	customTemplate?: string // 自定义模板
	defaultVisible?: boolean // 初始可见,默认 false
	autoHideOn?: AutoHideOn // 自动隐藏时机,默认 'DOMContentLoaded'
	callbacks?: LoadingCallbacks // 生命周期回调
}
使用示例
typescript 复制代码
// 基本使用
loadingManager()

// 自动拦截 fetch
loadingManager({ autoBind: 'fetch' })

// 白屏 Loading(SPA 场景)
loadingManager({
	defaultVisible: true,
	autoHideOn: 'manual'
})
// 在应用入口:window.__LOADING_MANAGER__.hide()

// 自定义样式 + 防抖
loadingManager({
	style: {
		overlayColor: 'rgba(0, 0, 0, 0.5)',
		spinnerColor: '#ff6b6b',
		backdropBlur: true
	},
	debounceHide: { enabled: true, duration: 100 }
})
运行时 API
typescript 复制代码
const lm = window.__LOADING_MANAGER__
lm.show('加载中...') // 显示
lm.hide() // 隐藏
lm.forceHide() // 强制隐藏
lm.updateText('正在处理...') // 更新文本
lm.isVisible() // 检查状态
lm.getPendingCount() // 挂起请求数
lm.destroy() // 销毁

versionUpdateChecker --- 版本更新检查

在运行时定期检查版本号变更,发现新版本时向用户显示刷新提示。通常与 generateVersion 插件配合使用。

核心功能
  • 版本来源 :支持从全局变量(define)、文件(file)或自动检测(auto
  • 三种提示样式modal(弹窗)、banner(横幅)、toast(轻提示)
  • 定时检查:可配置检查间隔
  • 可见性检测:页面从后台切回时立即检查
  • 自定义 UI:支持自定义模板和样式
  • 生命周期回调onUpdateAvailableonRefreshonDismiss
配置项
typescript 复制代码
interface VersionUpdateCheckerOptions extends BasePluginOptions {
	versionSource?: 'define' | 'file' | 'auto' // 版本来源,默认 'auto'
	defineName?: string // 全局变量名,默认 '__APP_VERSION__'
	checkUrl?: string // 检查 URL,默认 '/version.json'
	checkInterval?: number // 检查间隔(ms),默认 300000
	checkOnVisibilityChange?: boolean // 可见性检查,默认 true
	enableInDev?: boolean // 开发模式启用,默认 false
	promptStyle?: 'modal' | 'banner' | 'toast' // 提示样式,默认 'modal'
	promptMessage?: string // 提示消息
	refreshButtonText?: string // 刷新按钮文本
	dismissButtonText?: string // 忽略按钮文本
	customPromptTemplate?: string // 自定义模板
	customStyle?: string // 自定义样式
	onUpdateAvailable?: string // 发现新版本回调
	onRefresh?: string // 刷新回调
	onDismiss?: string // 忽略回调
}
使用示例
typescript 复制代码
// 配合 generateVersion 使用
;(generateVersion({
	format: 'datetime',
	outputType: 'both',
	defineName: '__APP_VERSION__'
}),
	versionUpdateChecker())

// 自定义检查间隔和提示
versionUpdateChecker({
	checkInterval: 60000,
	promptStyle: 'banner',
	onUpdateAvailable: 'console.log("新版本:", newVersion); return true;'
})

插件速查表

插件 工厂函数 执行阶段 核心用途
assetManifest assetManifest() writeBundle (post) 生成资源映射清单
autoImport autoImport() transform (pre) + buildEnd 自动注入 import 语句
buildProgress buildProgress() 全生命周期 终端构建进度条
bundleAnalyzer bundleAnalyzer() writeBundle (post) 构建产物体积分析
compressAssets compressAssets() writeBundle (post) gzip/brotli 压缩
copyFile copyFile() writeBundle (post) 文件复制
envGuard envGuard() configResolved + transformIndexHtml 环境变量校验
faviconManager faviconManager() transformIndexHtml + writeBundle 图标管理
generateRouter generateRouter() configResolved 路由配置生成
generateVersion generateVersion() config + configResolved + writeBundle 版本号生成
htmlInject htmlInject() transformIndexHtml (post) HTML 内容注入
imageOptimizer imageOptimizer() writeBundle (post) 图片压缩和格式转换
loadingManager loadingManager() transformIndexHtml (post) 全局 Loading 管理
versionUpdateChecker versionUpdateChecker() transformIndexHtml (post) 版本更新检查

常见组合方案

生产构建优化

typescript 复制代码
import { compressAssets, imageOptimizer, bundleAnalyzer } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [compressAssets({ algorithm: 'both' }), imageOptimizer({ convertToWebp: { png: true, jpeg: true } }), bundleAnalyzer({ outputFormat: 'html', openAnalyzer: true })]
})

版本管理 + 更新提示

typescript 复制代码
import { generateVersion, versionUpdateChecker } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [generateVersion({ format: 'datetime', outputType: 'both' }), versionUpdateChecker({ checkInterval: 60000 })]
})

开发体验增强

typescript 复制代码
import { autoImport, buildProgress, loadingManager } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [buildProgress({ format: 'spinner' }), autoImport({ imports: { vue: ['ref', 'reactive', 'computed'] }, vueTemplate: true }), loadingManager({ defaultVisible: true, autoHideOn: 'manual' })]
})

环境安全 + 资源管理

typescript 复制代码
import { envGuard, assetManifest, htmlInject } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [
		envGuard({
			required: { VITE_API_URL: { type: 'url', required: true } },
			failAction: 'error'
		}),
		assetManifest({ outputFormat: 'vite', injectRuntime: true }),
		htmlInject({
			rules: [{ content: '<meta name="description" content="My App">', position: 'head-end' }]
		})
	]
})
相关推荐
前端一小卒25 分钟前
我用 TypeScript 从零手写了一个 Claude Code,然后发现它的核心只有 30 行
前端·agent
大圣编程2 小时前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang2 小时前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
之歆3 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜3 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
负责的蛋挞4 小时前
异步HttpModule的实现方式
java·服务器·前端
丹宇码农7 小时前
把 HLS 字幕玩出花:zwPlayer 如何让 M3U8 视频支持全文搜索、翻译与码率自适应
前端·javascript·音视频·hls·视频播放器
2501_943782357 小时前
【共创季稿事节】猜数字游戏:二分法思维与交互式反馈
前端·游戏·microsoft·harmonyos·鸿蒙·鸿蒙系统
GV191rLvq7 小时前
基于Socket实现的最简单的Web服务器【ASP.NET原理分析】
服务器·前端·asp.net