Vite插件体系1.0.0:API稳定,生产就绪

0 阅读10分钟

版本:1.0.0 | 协议:MIT | 依赖:Vite >=5.0.0 <8.0.0


写在前面

v1.0.0 的主题是:API 稳定性承诺与生产就绪标志

经过 0.x 系列(0.0.1 - 0.2.7)共 27 个版本的迭代,插件体系从最初的 2 个插件(copyFile、injectIco)发展到 15 个插件覆盖构建全生命周期;common 工具模块从零散函数发展为 14 个规范化子模块;插件开发框架(BasePlugin、Logger、Validator、createPluginFactory)趋于成熟。1.0.0 版本标记 API 稳定性,后续变更将严格遵循语义化版本规范。

这不是一个包含大量新功能的版本,而是一个里程碑——宣告插件体系已具备生产可用性,并承诺 API 稳定性。

本版重点

能力一句话说明你需要做什么
API 稳定性承诺后续破坏性变更需升主版本号,遵循 semver放心在生产环境使用
15 个插件完整就绪覆盖生成、压缩、复制、分析、注入、守卫、代理 7 大类按需选用
7 个分组子路径导出按功能分组导出,利于 Tree-shaking可从分组子路径导入
14 个 Common 子模块通用工具规范化抽离,可独立复用按需从 common 子路径导入
插件开发框架成熟BasePlugin + Logger + Validator + createPluginFactory可基于框架开发自定义插件
零配置可用所有插件参数可选化,提供合理默认值无需配置即可上手

升级方式:修改 devDependencies 中版本号为 ^1.0.0无 Breaking Change,可从 0.2.7 平滑升级。


一、5 分钟快速上手

1.1 安装与升级

{
	"devDependencies": {
		"@meng-xi/vite-plugin": "^1.0.0"
	}
}

1.2 从 0.2.7 平滑升级

1.0.0 无 Breaking Change,直接升级即可:

pnpm update @meng-xi/vite-plugin@^1.0.0

所有 0.2.7 的用法在 1.0.0 中保持不变:

// vite.config.ts
import { defineConfig } from 'vite'
import { compressAssets, generateRouter, generateVersion } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [
		generateRouter({ dts: true }),
		generateVersion(),
		compressAssets({ algorithm: 'both' })
	]
})

1.3 推荐用法:按分组导入

1.0.0 推荐使用分组子路径导入,利于 Tree-shaking:

// 按分组导入(推荐)
import { compressAssets } from '@meng-xi/vite-plugin/plugins/compress'
import { generateRouter, generateVersion } from '@meng-xi/vite-plugin/plugins/generate'
import { loadingManager } from '@meng-xi/vite-plugin/plugins/inject'
import { envGuard } from '@meng-xi/vite-plugin/plugins/guard'
import { proxyManager } from '@meng-xi/vite-plugin/plugins/proxy'
import { bundleAnalyzer, buildProgress } from '@meng-xi/vite-plugin/plugins/analyze'
import { assetManifest, copyFile } from '@meng-xi/vite-plugin/plugins/copy'

// 主入口导入(向后兼容,仍可用)
import { compressAssets, generateRouter } from '@meng-xi/vite-plugin'

二、从 0.x 到 1.0.0 的演进历程

2.1 三个阶段回顾

阶段版本范围主题插件数量
萌芽期0.0.1 - 0.0.5基础插件雏形(copyFile、injectIco)2 → 4
框架成熟期0.0.6 - 0.1.0BasePlugin、Logger、Validator、插件重命名4 → 10
功能完善期0.1.1 - 0.2.7htmlInject、compressAssets、bundleAnalyzer…10 → 15

2.2 关键里程碑事件

版本里程碑事件
0.0.1首发,copyFile + injectIco 两个插件
0.0.2引入插件工厂(createPluginFactory)与参数校验(Validator)
0.0.6BasePlugin 新增 destroy 生命周期,Logger 单例化
0.0.8injectLoading(后改名 loadingManager)登场
0.1.0插件规范化重命名:injectIco → faviconManager 等
0.1.2所有插件参数可选化,零配置可用
0.1.5autoImport 引入通配符 '*',common 模块精简
0.2.0proxyManager 登场,common 工具进一步抽离
0.2.5generateRouter 注释头模板化(headerTemplate)
0.2.6common 工具抽离 6 个子模块,版本号自动注入
0.2.7插件按功能分组导出(7 个分组子路径)
1.0.0API 稳定性承诺,生产就绪

2.3 数量增长曲线

插件数量
15 |                                                    ●
14 |                                                ●
13 |                                            ●
12 |                                        ●
11 |                                    ●
10 |                                ●
 9 |                            ●
 8 |                        ●
 7 |                    ●
 6 |                ●
 5 |            ●
 4 |        ●
 3 |    ●
 2 |●
 1 |●
   +----+----+----+----+----+----+----+----+----+----→
   0.0  0.2  0.4  0.6  0.8  1.0  1.2  1.4  1.6  1.8  2.0
                       版本

三、插件体系完整清单

v1.0.0 共包含 15 个插件,按功能划分为 7 个分组

3.1 analyze 分组 —— 构建分析

插件enforce功能描述
buildProgress-终端构建进度条,支持 bar / spinner / minimal 三种格式
bundleAnalyzerpost构建产物体积分析,生成 JSON/HTML 报告,支持阈值告警与历史对比

3.2 compress 分组 —— 产物压缩

插件enforce功能描述
compressAssetspostgzip / brotli 压缩,生成 .gz / .br 文件,支持并发与统计报告
imageOptimizerpost图片压缩与格式转换(sharp + svgo),支持 WebP/AVIF 转换

3.3 copy 分组 —— 文件复制与清单

插件enforce功能描述
assetManifestpost资源清单生成,支持 vite/webpack/custom 三种格式与运行时注入
copyFilepost文件/目录复制,支持增量复制、并发控制与错误策略

3.4 generate 分组 —— 代码与配置生成

插件enforce功能描述
autoImportpre自动导入,支持通配符 '*'、目录扫描、Vue 模板与类型声明生成
generateRouter-根据 pages.json 生成路由配置与类型声明(uni-app 专用)
generateVersion-版本号生成,支持多种格式、占位符与全局变量注入

3.5 guard 分组 —— 环境守卫

插件enforce功能描述
envGuardpost环境变量校验,支持 8 种类型、运行时守卫与 .env 模板生成

3.6 inject 分组 —— HTML 与运行时注入

插件enforce功能描述
faviconManager-网站图标管理,支持字符串简写配置与自定义 link 标签
htmlInject-HTML 内容注入,7 种位置、条件注入、模板变量与安全过滤
loadingManager-全局 Loading 状态管理,请求自动拦截、防抖、过渡动画
versionUpdateChecker-运行时版本更新检查,三种提示 UI 与自定义模板

3.7 proxy 分组 —— 开发代理

插件enforce功能描述
proxyManager-开发代理管理,路径匹配、请求重写、延迟模拟、环境变量覆盖

四、Common 工具模块体系

v1.0.0 共包含 14 个 Common 工具子模块,从各插件内部抽离的通用函数,可独立复用:

子模块核心导出典型场景
common/codeJS_KEYWORDSstripCommentsAndStrings静态分析时移除注释与字符串
common/compresscalculateGzipSize计算产物 gzip 压缩大小
common/concurrencyrunWithConcurrency带并发限制的批量异步执行
common/envparseEnvContent解析 .env 文件内容
common/formatparseTemplateparseTemplateWithDelimiterparsePluginTemplateformatDateformatFileSizecalcRatio模板解析、日期格式化、文件大小
common/fswriteFileSyncSafelyshouldUpdateFileContentscanAndMapFilesdeleteFilesresolveReportPath文件读写、目录扫描、报告输出
common/hashgenerateRandomHash生成缓存破坏哈希、版本标识
common/htmlinjectBeforeTaginjectHeadAndBodyescapeHtmlAttrHTML 标签注入、属性转义
common/objectdeepMerge深度合并配置对象
common/pathnormalizePathisExtensionIncludedisPathExcludedisPreCompressed路径规范化、扩展名过滤
common/scriptmakeCallback回调函数体包装为安全函数表达式
common/stringtoCamelCasetoPascalCasestripJsonCommentsescapeRegex命名转换、JSON 解析、正则转义
common/uiANSISPINNER_FRAMESstripAnsi终端 ANSI 颜色码、Spinner 动画
common/validationValidatorvalidateGlobalNamevalidateNoScriptInTemplatevalidateCallbackFields链式配置验证、XSS 防护
// 示例:从 common 子路径导入工具
import { deepMerge } from '@meng-xi/vite-plugin/common/object'
import { generateRandomHash } from '@meng-xi/vite-plugin/common/hash'
import { parsePluginTemplate } from '@meng-xi/vite-plugin/common/format'
import { toCamelCase } from '@meng-xi/vite-plugin/common/string'

五、插件开发框架

v1.0.0 提供完整的插件开发框架,支持基于 BasePlugin 开发自定义插件:

5.1 BasePlugin 抽象类

所有插件的基类,提供完整的生命周期管理:

能力方法/属性说明
配置合并mergeOptions深度合并基础默认值、插件默认值与用户配置
日志记录logger每个实例独立的 PluginLogger 代理
配置验证validator + validateOptions泛型 Validator 流式验证
生命周期onConfigResolved / destroy配置解析完成回调 + 销毁清理
错误处理safeExecute / safeExecuteSync / handleErrorerrorStrategy 统一处理错误
钩子注册registerHook / registerOrderedHook / registerTransformIndexHtml自动包裹 enabled 检查与错误处理
插件转换toPlugin转换为 Vite 插件对象,自动注册 configResolved 与 closeBundle

5.2 createPluginFactory 工厂函数

支持选项标准化器(OptionsNormalizer),允许插件接受非对象类型的简写配置:

import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin/factory'

class MyPlugin extends BasePlugin<MyPluginOptions> {
	protected getPluginName() {
		return 'my-plugin'
	}

	protected getDefaultOptions() {
		return { enabled: true, message: 'hello' }
	}

	protected addPluginHooks(plugin: any) {
		this.registerHook(plugin, 'transform', (code: string, id: string) => {
			if (!this.options.enabled) return code
			return code + `\nconsole.log("${this.options.message}")`
		}, '代码转换')
	}
}

// 支持字符串简写:myPlugin('hello') 等同于 myPlugin({ message: 'hello' })
export const myPlugin = createPluginFactory(MyPlugin, (opt) =>
	typeof opt === 'string' ? { message: opt } : opt
)

5.3 Logger 单例日志系统

以实例 ID 为 key 管理每个插件实例的日志配置,避免同类型多实例冲突:

import { Logger } from '@meng-xi/vite-plugin/logger'

// 注册插件日志配置
Logger.register({
	name: 'my-plugin',
	enabled: true,
	instanceId: 'my-plugin#1' // 唯一标识,避免多实例冲突
})

// 注销插件日志配置(插件销毁时)
Logger.unregister('my-plugin#1')

// 销毁所有日志配置(测试场景)
Logger.destroy()

5.4 Validator 泛型验证器

链式 API,编译时类型安全保障:

import { Validator } from '@meng-xi/vite-plugin/common/validation'

const validator = new Validator({ timeout: 5000, retries: 3 })

validator
	.field('timeout')
	.required()
	.minValue(100)
	.maxValue(60000)

validator
	.field('retries')
	.required()
	.minValue(0)
	.maxValue(10)

const errors = validator.validate()
// 无错误时返回空数组

六、子路径导出体系

6.1 完整子路径清单

类别子路径说明
主入口.导出全部(向后兼容)
Common 工具./common + 14 个子模块code/compress/concurrency/env/format/fs/hash/html/object/path/script/string/ui/validation
框架能力./factoryBasePlugin、createPluginFactory、类型定义
日志系统./loggerLogger 单例、PluginLogger
插件主入口./plugins导出全部 15 个插件(向后兼容)
分组导出./plugins/analyze./plugins/compress./plugins/copy./plugins/generate./plugins/guard./plugins/inject./plugins/proxy7 个分组子路径,利于 Tree-shaking
单插件导出./plugins/analyze/build-progress 等 15 个每个插件单独子路径

6.2 导入方式对比

// 方式一:主入口导入(简单,但不利于 Tree-shaking)
import { compressAssets, generateRouter, loadingManager } from '@meng-xi/vite-plugin'

// 方式二:分组导入(推荐,平衡便利与 Tree-shaking)
import { compressAssets } from '@meng-xi/vite-plugin/plugins/compress'
import { generateRouter } from '@meng-xi/vite-plugin/plugins/generate'
import { loadingManager } from '@meng-xi/vite-plugin/plugins/inject'

// 方式三:单插件导入(最优 Tree-shaking)
import { generateRouter } from '@meng-xi/vite-plugin/plugins/generate/generate-router'

七、实战场景

7.1 uni-app 项目完整配置

// vite.config.ts
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import {
	generateRouter,
	generateVersion,
	autoImport,
	compressAssets,
	imageOptimizer,
	assetManifest,
	bundleAnalyzer,
	envGuard,
	htmlInject,
	loadingManager,
	faviconManager,
	versionUpdateChecker,
	buildProgress,
	copyFile,
	proxyManager
} from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [
		uni(),
		// 生成类
		generateRouter({ dts: true, headerTemplate: true }),
		generateVersion({ outputType: 'define' }),
		autoImport({ imports: { vue: ['*'] } }),

		// 守卫类
		envGuard({
			required: {
				VITE_API_URL: { type: 'url', required: true },
				VITE_APP_TITLE: { type: 'string', required: true }
			}
		}),

		// 注入类
		htmlInject({
			rules: [
				{ id: 'description', content: '<meta name="description" content="My App">', position: 'head-end' }
			]
		}),
		loadingManager({ autoBind: 'all', defaultVisible: true }),
		faviconManager('/static/'),
		versionUpdateChecker({ promptStyle: 'banner' }),

		// 分析类
		buildProgress({ format: 'bar' }),
		bundleAnalyzer({ outputFormat: 'json' }),

		// 复制类
		copyFile({ sourceDir: 'public', targetDir: 'dist' }),
		assetManifest({ injectRuntime: true }),

		// 压缩类(生产构建生效)
		compressAssets({ algorithm: 'both' }),
		imageOptimizer({ convertToWebp: { png: true } }),

		// 代理类(开发模式生效)
		proxyManager({
			rules: [{ context: '/api', target: 'http://localhost:3000' }]
		})
	]
})

7.2 基于 BasePlugin 开发自定义插件

import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin/factory'

interface CopyrightOptions {
	enabled?: boolean
	author: string
	year?: number
}

class CopyrightPlugin extends BasePlugin<CopyrightOptions> {
	protected getPluginName() {
		return 'copyright-injector'
	}

	protected getDefaultOptions() {
		return {
			author: 'Unknown',
			year: new Date().getFullYear()
		}
	}

	protected validateOptions() {
		this.validator.field('author').required()
	}

	protected addPluginHooks(plugin: any) {
		this.registerTransformIndexHtml(
			plugin,
			(html: string) => {
				const copyright = `<!-- © ${this.options.year} ${this.options.author} -->`
				return html.replace('</head>', `${copyright}\n</head>`)
			},
			'注入版权信息'
		)
	}
}

export const copyrightInjector = createPluginFactory(CopyrightPlugin)

// 使用
copyrightInjector({ author: 'MengXi Studio' })

7.3 复用 Common 工具模块

import { deepMerge } from '@meng-xi/vite-plugin/common/object'
import { generateRandomHash } from '@meng-xi/vite-plugin/common/hash'
import { parsePluginTemplate } from '@meng-xi/vite-plugin/common/format'

// 合并多份配置
const finalConfig = deepMerge(defaultConfig, envConfig, userConfig)

// 生成缓存破坏标识
const assetHash = generateRandomHash(8)

// 解析插件注释头模板
const header = parsePluginTemplate('{name} v{version} ({date:YYYY-MM-DD})', {
	name: 'my-plugin',
	version: '1.0.0'
})
// 'my-plugin v1.0.0 (2026-06-27)'

八、与 0.x 的差异对比

8.1 API 稳定性承诺

维度0.x(演进期)1.0.0(稳定期)
破坏性变更允许在 minor 版本引入仅在 major 版本引入,minor/patch 严格向后兼容
版本号语义语义化版本(宽松)严格遵循 semver
升级风险每个版本可能需要迁移minor/patch 升级零迁移成本

8.2 功能完整度

维度0.0.1(首发)0.2.7(最后一个 0.x)1.0.0(稳定版)
插件数量21515
Common 模块01414
分组导出无(单入口)7 个分组子路径7 个分组子路径
零配置可用否(部分必填)
版本号注入手动同步自动注入自动注入

8.3 架构成熟度

维度0.x 早期1.0.0
错误处理各插件自行处理统一 errorStrategy 策略
钩子注册手动包裹 enabled 检查registerHook 自动包裹 enabled 与错误处理
日志系统简单工具类单例 Logger,实例 ID 隔离
配置验证运行时 if 判断泛型 Validator 链式验证
类型安全逐步补全完整 TypeScript + global.d.ts
目录结构common/helpers/ 混用统一为 helpers/

九、生产就绪声明

9.1 兼容性

  • Vite 兼容性:支持 Vite 5.x - 7.x(peerDependencies: vite >=5.0.0 <8.0.0
  • Node.js 兼容性:支持 Node.js 18.x+(遵循 Vite 5 的引擎要求)
  • TypeScript 支持:完整类型定义,types 字段指向 .d.ts 文件
  • 双格式输出:同时提供 ESM(.mjs)与 CJS(.cjs)构建产物

9.2 可选依赖

以下依赖为可选,不可用时优雅降级:

依赖用途降级行为
sharpimageOptimizer 位图压缩与转换跳过位图处理,仅保留 SVG 优化
svgoimageOptimizer SVG 优化跳过 SVG 优化,保留位图处理

9.3 质量保障

  • 零配置可用:所有插件参数可选化,提供合理默认值
  • 错误隔离:单个插件异常不影响其他插件与整体构建(errorStrategy: 'log'
  • 资源清理closeBundle 钩子自动调用 destroy(),释放定时器、监听器等资源
  • SSR 安全:注入类插件包含 typeof window === 'undefined' 检测

9.4 稳定性承诺

自 1.0.0 起,严格遵循语义化版本规范:

  • PATCH 版本(1.0.x):仅修复 Bug,完全向后兼容
  • MINOR 版本(1.x.0):新增功能,向后兼容,可能有新增导出
  • MAJOR 版本(x.0.0):破坏性变更,需要迁移

十、升级指南

10.1 从 0.2.7 升级(推荐路径)

1.0.0 无 Breaking Change,直接升级即可:

# pnpm
pnpm update @meng-xi/vite-plugin@^1.0.0

# npm
npm install @meng-xi/vite-plugin@^1.0.0

# yarn
yarn add @meng-xi/vite-plugin@^1.0.0

升级后无需修改任何代码,所有 0.2.7 的用法在 1.0.0 中保持不变。

10.2 从更早的 0.x 版本升级

如果从 0.2.x 之前的版本升级,需注意以下历史 Breaking Change:

历史版本Breaking Change迁移方式
0.1.0injectIcofaviconManager重命名导入
0.1.0injectLoadingloadingManager重命名导入
0.2.1移除 UniAnimationTypeNavigationAnimation 类型@meng-xi/uni-router 导入
0.2.5fileHeaderheaderTemplate替换参数名

10.3 可选:迁移到分组导入

虽然主入口导入仍可用,但推荐迁移到分组导入以获得更好的 Tree-shaking 效果:

// 之前:主入口导入
import { compressAssets, generateRouter, loadingManager } from '@meng-xi/vite-plugin'

// 推荐:分组导入
import { compressAssets } from '@meng-xi/vite-plugin/plugins/compress'
import { generateRouter } from '@meng-xi/vite-plugin/plugins/generate'
import { loadingManager } from '@meng-xi/vite-plugin/plugins/inject'

10.4 升级后验证

升级后建议运行完整构建验证:

# 开发模式验证
vite dev

# 生产构建验证
vite build

# 检查生成的报告文件
ls dist/compress-report.json dist/bundle-analysis.json dist/manifest.json

写在最后

v1.0.0 是一个里程碑,而不是终点。

经过 27 个 0.x 版本的迭代,插件体系已具备生产可用性:

  • 15 个插件覆盖了 Vite 构建的全生命周期,从代码生成到产物压缩,从开发代理到运行时守卫
  • 14 个 Common 子模块让通用工具可以独立复用,降低新插件开发成本
  • 插件开发框架(BasePlugin + Logger + Validator + createPluginFactory)为自定义插件提供完整基础设施
  • 7 个分组子路径让 Tree-shaking 更高效,按需引入更轻量

自 1.0.0 起,我们将严格遵循语义化版本规范,让你可以放心地在生产环境使用并跟随版本升级。

下一个 major 版本(2.0.0)将聚焦于:Vite 8 适配、插件间依赖编排、更丰富的可视化报告。如果你有任何建议或问题,欢迎在 GitHub Issues 反馈。