欢迎光临
我们一直在努力

Vite插件v0.2.6:架构优化与自动化升级

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


写在前面

v0.2.6 的主题是:消除重复代码,让架构更干净,让版本号管理更自动化。

本次更新是一次内部架构优化版本,将散落在各插件内部的重复工具函数统一提取到 common 目录,新增 6 个通用子模块(code、compress、env、hash、object、string),并重构了版本号注入机制——从手动同步脚本升级为构建时自动注入。同时统一了插件内部目录命名(common → helpers),提升了整体可维护性。

本版重点:

能力一句话说明你需要做什么
6 个新增 Common 子模块 code/compress/env/hash/object/string 统一管理工具函数 按需从新子路径导入
parsePluginTemplate 插件专用模板解析函数,统一注释头模板处理 无需操作,内部已自动使用
__PLUGIN_VERSION__ 注入 构建时自动从 package.json 注入版本号,无需手动同步 无需操作
helpers 目录统一 插件内部 common 目录重命名为 helpers 无需操作(内部结构变更)
versionUpdateChecker 优化 自定义模板解析改用通用 parseTemplateWithDelimiter 无需操作

升级方式:修改 devDependencies 中版本号为 ^0.2.6。无 Breaking Change,可直接平滑升级。


一、5 分钟快速上手

1.1 安装与升级

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

1.2 使用新增的 Common 子模块

v0.2.6 将原本散落在各插件内部的工具函数提取为 6 个通用子模块,现在你可以直接按需导入:

// 深度合并对象
import { deepMerge } from '@meng-xi/vite-plugin/common/object'

const merged = deepMerge(
{ a: 1, b: { c: 2 } },
{ b: { d: 3 }, e: 4 }
)
// { a: 1, b: { c: 2, d: 3 }, e: 4 }

// 生成随机哈希
import { generateRandomHash } from '@meng-xi/vite-plugin/common/hash'

const hash = generateRandomHash(16) // 'a3f2b9c1d4e5f6a7'

// 路径转驼峰命名
import { toCamelCase } from '@meng-xi/vite-plugin/common/string'

const name = toCamelCase('/pages/user/profile') // 'pagesUserProfile'

1.3 一览新增子模块

子路径核心导出典型场景
@meng-xi/vite-plugin/common/code JS_KEYWORDS、stripCommentsAndStrings 静态分析时移除注释与字符串
@meng-xi/vite-plugin/common/compress calculateGzipSize 计算产物 gzip 压缩大小
@meng-xi/vite-plugin/common/env parseEnvContent 解析 .env 文件内容
@meng-xi/vite-plugin/common/hash generateRandomHash 生成缓存破坏哈希、版本标识
@meng-xi/vite-plugin/common/object deepMerge 深度合并配置对象
@meng-xi/vite-plugin/common/string toCamelCase、toPascalCase、stripJsonComments、escapeRegex 命名转换、JSON 解析、正则转义

二、Common 工具模块扩展

2.1 common/code —— 代码处理

从 autoImport 插件提取,用于静态分析时预处理代码:

import { JS_KEYWORDS, stripCommentsAndStrings } from '@meng-xi/vite-plugin/common/code'

// JS 关键字集合:自动导入时跳过这些标识符
JS_KEYWORDS.has('class') // true
JS_KEYWORDS.has('myVar') // false

// 移除注释和字符串内容(保留换行符以维持行号)
const cleaned = stripCommentsAndStrings(`
const a = 1 // 注释
const b = "字符串"
`
)
// 注释和字符串内容被替换为空白,结构保留

2.2 common/compress —— 压缩计算

从 bundleAnalyzer 插件提取,用于产物体积分析:

import { calculateGzipSize } from '@meng-xi/vite-plugin/common/compress'

const originalSize = 1024
const gzipSize = await calculateGzipSize('console.log("hello world")')
// 35(字节数)

// 计算压缩率
const ratio = ((1 gzipSize / originalSize) * 100).toFixed(1) + '%'

2.3 common/env —— 环境变量解析

从 envGuard 插件提取,支持前缀过滤和引号去除:

import { parseEnvContent } from '@meng-xi/vite-plugin/common/env'

const content = `
# Database config
DB_HOST=localhost
DB_PORT="5432"
VITE_API_URL='https://api.example.com'
VITE_APP_TITLE="My App"
`

// 解析全部变量
const allVars = parseEnvContent(content)
// { DB_HOST: 'localhost', DB_PORT: '5432', VITE_API_URL: 'https://api.example.com', VITE_APP_TITLE: 'My App' }

// 仅解析 VITE_ 前缀变量
const viteVars = parseEnvContent(content, { prefix: 'VITE_' })
// { VITE_API_URL: 'https://api.example.com', VITE_APP_TITLE: 'My App' }

2.4 common/hash —— 哈希生成

从 generateVersion 插件提取,使用加密级随机数:

import { generateRandomHash } from '@meng-xi/vite-plugin/common/hash'

generateRandomHash() // 'a3f2b9c1'(默认 8 位)
generateRandomHash(16) // 'a3f2b9c1d4e5f6a7'
generateRandomHash(32) // 'a3f2b9c1d4e5f6a7b8c9d0e1f2a3b4c5'

// 长度自动限制在 1-64 范围
generateRandomHash(100) // 截断为 64 位
generateRandomHash(0) // 修正为 1 位

2.5 common/object —— 对象合并

从 factory 模块提取,递归合并普通对象:

import { deepMerge } from '@meng-xi/vite-plugin/common/object'

// 递归合并嵌套对象
deepMerge(
{ a: 1, b: { c: 2, e: 5 } },
{ b: { d: 3 }, f: 6 }
)
// { a: 1, b: { c: 2, d: 3, e: 5 }, f: 6 }

// undefined 值不会覆盖已有属性
deepMerge(
{ a: 1, b: 2 },
{ a: undefined, c: 3 }
)
// { a: 1, b: 2, c: 3 }

// 非对象值直接覆盖
deepMerge(
{ a: { x: 1 } },
{ a: null }
)
// { a: null }

2.6 common/string —— 字符串处理

从 autoImport 插件提取,提供命名转换和 JSON 处理:

import { toCamelCase, toPascalCase, stripJsonComments, escapeRegex } from '@meng-xi/vite-plugin/common/string'

// 驼峰命名(路由名称生成)
toCamelCase('/pages/index/index') // 'pagesIndexIndex'
toCamelCase('user-name') // 'userName'

// 帕斯卡命名(组件名称生成)
toPascalCase('/pages/index/index') // 'PagesIndexIndex'
toPascalCase('user-name') // 'UserName'

// 移除 JSON 注释(解析带注释的配置文件)
const json = `{
// 页面配置
"pages": ["index"] /* 主页面 */
}
`

const clean = stripJsonComments(json)
// { "pages": ["index"] }

// 转义正则特殊字符(安全构建正则表达式)
const userPattern = new RegExp(escapeRegex('user.name') + '\\\\d+')
// 匹配字面量 'user.name' 后跟数字,而非 'user' + 任意字符 + 'name'

2.7 common/format —— 新增 parsePluginTemplate

common/format 模块新增 parsePluginTemplate 函数,统一插件注释头模板解析逻辑。该函数支持 {name}、{date}、{date:FORMAT}、{version}、{custom:KEY} 占位符:

import { parsePluginTemplate } from '@meng-xi/vite-plugin/common/format'

// 基础用法
parsePluginTemplate('{name} {date} {version}', {
name: 'generate-router',
version: '0.2.6'
})
// 'generate-router 2026-06-25 14:30:00 0.2.6'

// 自定义日期格式
parsePluginTemplate('{name} {date:YYYY-MM-DD} {version}', {
name: 'generate-router',
version: '0.2.6'
})
// 'generate-router 2026-06-25 0.2.6'

// 自定义字段
parsePluginTemplate('{name} {custom:author} {date:YYYY-MM-DD} {version}', {
name: 'generate-router',
version: '0.2.6',
customFields: { author: 'MengXi Studio' }
})
// 'generate-router MengXi Studio 2026-06-25 0.2.6'

该函数主要供 generateRouter 插件内部使用,用于解析 headerTemplate 配置。你也可以在自定义插件中直接调用。


三、版本号注入机制重构

3.1 问题背景

在 v0.2.5 及之前,插件版本号通过 generate-exports.ts 脚本手动同步到各插件源码中。每次发版需要:

  • 修改 package.json 的 version 字段
  • 运行 generate-exports.ts 脚本扫描并替换源码中的版本号
  • 手动确认所有插件版本号已更新
  • 这种方式容易遗漏,且脚本逻辑复杂。

    3.2 新机制:构建时自动注入

    v0.2.6 引入 __PLUGIN_VERSION__ 全局变量,通过 unbuild 的 replace 配置在构建时自动注入:

    // build.config.ts(自动生成)
    export default defineBuildConfig({
    // …其他配置
    replace: {
    __PLUGIN_VERSION__: "\\"0.2.6\\"" // 从 package.json 自动读取
    }
    })

    插件源码中直接使用全局变量:

    // generateRouter/helpers/generator.ts
    /** 插件版本号,由 unbuild 在构建时通过 replace 配置注入 */
    const PLUGIN_VERSION = __PLUGIN_VERSION__

    // 在注释头模板中使用
    parsePluginTemplate(headerTemplate, {
    name: 'generate-router',
    version: PLUGIN_VERSION, // 自动获取,无需手动维护
    customFields
    })

    3.3 类型声明支持

    新增 src/types/global.d.ts 提供 TypeScript 类型声明:

    // src/types/global.d.ts
    declare const __PLUGIN_VERSION__: string

    这意味着在插件源码中直接使用 __PLUGIN_VERSION__ 即可获得完整类型提示,无需重复声明。

    3.4 对比

    维度v0.2.5v0.2.6
    版本号来源 generate-exports.ts 手动同步 unbuild replace 自动注入
    维护方式 每次发版运行脚本扫描替换源码 构建时自动从 package.json 读取
    类型支持 global.d.ts 全局类型声明
    出错风险 可能遗漏某些插件 全局统一,不可能遗漏

    四、versionUpdateChecker 优化

    4.1 自定义模板解析统一

    v0.2.6 将 versionUpdateChecker 插件的自定义提示模板解析逻辑从多次链式 .replace() 改用通用的 parseTemplateWithDelimiter 函数:

    // v0.2.5:多次链式 replace
    return options.customPromptTemplate
    .replace(/\\{\\{message\\}\\}/g, message)
    .replace(/\\{\\{currentVersion\\}\\}/g, '<span id="__vuc-current__"></span>')
    .replace(/\\{\\{newVersion\\}\\}/g, '<span id="__vuc-new__"></span>')
    .replace(/\\{\\{refreshButton\\}\\}/g, `<button>…</button>`)
    .replace(/\\{\\{dismissButton\\}\\}/g, `<button>…</button>`)

    // v0.2.6:使用通用工具函数一次解析
    const values = {
    message,
    currentVersion: '<span id="__vuc-current__"></span>',
    newVersion: '<span id="__vuc-new__"></span>',
    refreshButton: `<button>…</button>`,
    dismissButton: `<button>…</button>`
    }
    return parseTemplateWithDelimiter(options.customPromptTemplate, values, '{{', '}}')

    4.2 收益

    维度v0.2.5v0.2.6
    代码量 5 次链式 replace 1 次函数调用
    可维护性 新增占位符需追加 replace 只需在 values 对象中添加键值对
    安全性 手动拼接正则 键名自动转义正则特殊字符

    对用户无影响,customPromptTemplate 的 {{message}}、{{currentVersion}} 等占位符用法保持不变。


    五、插件目录结构统一

    5.1 common → helpers 重命名

    v0.2.6 将所有插件内部的 common 目录统一重命名为 helpers,避免与顶层 common 工具模块混淆:

    packages/core/src/plugins/generateRouter/
    ├── common/ ← v0.2.5(已移除)
    │ ├── generator.ts
    │ ├── merger.ts
    │ └── …
    └── helpers/ ← v0.2.6(新增)
    ├── generator.ts
    ├── merger.ts
    └── …

    涉及的 15 个插件全部完成迁移:

    插件目录变更
    assetManifest common/ → helpers/
    autoImport common/ → helpers/
    buildProgress common/ → helpers/
    bundleAnalyzer common/ → helpers/
    compressAssets common/ → helpers/
    envGuard common/ → helpers/
    faviconManager common/ → helpers/,类型文件统一
    generateRouter common/ → helpers/
    generateVersion common/ → helpers/
    htmlInject common/ → helpers/
    imageOptimizer common/ → helpers/
    loadingManager common/ → helpers/
    proxyManager common/ → helpers/
    versionUpdateChecker common/ → helpers/

    5.2 faviconManager 类型文件统一

    faviconManager 的类型文件从 common/type.ts 移动到插件根目录 types.ts,与其他插件保持一致:

    packages/core/src/plugins/faviconManager/
    ├── common/type.ts ← v0.2.5(已移除)
    └── types.ts ← v0.2.6(统一位置)

    重要:此变更仅影响插件内部结构,对用户导入路径无任何影响。所有 @meng-xi/vite-plugin/plugins/* 子路径导出保持不变。


    六、实战场景

    6.1 使用 deepMerge 合并多份配置

    import { deepMerge } from '@meng-xi/vite-plugin/common/object'

    // 合并默认配置、环境配置和用户自定义配置
    const defaultConfig = {
    timeout: 5000,
    headers: { 'Content-Type': 'application/json' },
    retry: { count: 3, delay: 1000 }
    }

    const envConfig = {
    timeout: 10000,
    retry: { delay: 2000 }
    }

    const userConfig = {
    headers: { Authorization: 'Bearer token' },
    customField: 'value'
    }

    const finalConfig = deepMerge(defaultConfig, envConfig, userConfig)
    // {
    // timeout: 10000,
    // headers: { 'Content-Type': 'application/json', Authorization: 'Bearer token' },
    // retry: { count: 3, delay: 2000 },
    // customField: 'value'
    // }

    6.2 使用 parseEnvContent 读取自定义 .env 文件

    import { readFileSync } from 'node:fs'
    import { parseEnvContent } from '@meng-xi/vite-plugin/common/env'

    // 读取自定义配置文件
    const content = readFileSync('.env.deploy', 'utf-8')
    const deployConfig = parseEnvContent(content, { prefix: 'DEPLOY_' })

    // .env.deploy 内容:
    // DEPLOY_HOST=192.168.1.100
    // DEPLOY_PORT="22"
    // DB_PASSWORD=secret

    // deployConfig: { DEPLOY_HOST: '192.168.1.100', DEPLOY_PORT: '22' }

    6.3 使用 generateRandomHash 生成缓存破坏标识

    import { generateRandomHash } from '@meng-xi/vite-plugin/common/hash'

    // 为静态资源生成缓存破坏参数
    const assetHash = generateRandomHash(8)
    const imageUrl = `/banner.png?v=${assetHash}`
    // '/banner.png?v=a3f2b9c1'

    // 生成唯一的构建标识
    const buildId = generateRandomHash(16)
    console.log(`Build ID: ${buildId}`)
    // Build ID: a3f2b9c1d4e5f6a7

    6.4 使用 toCamelCase 生成路由名称

    import { toCamelCase } from '@meng-xi/vite-plugin/common/string'

    // 根据文件路径自动生成路由名称
    const pages = [
    '/pages/index/index',
    '/pages/user/profile',
    '/pages-sub/settings/index'
    ]

    const routeNames = pages.map(path => ({
    path,
    name: toCamelCase(path)
    }))
    // [
    // { path: '/pages/index/index', name: 'pagesIndexIndex' },
    // { path: '/pages/user/profile', name: 'pagesUserProfile' },
    // { path: '/pages-sub/settings/index', name: 'pagesSubSettingsIndex' }
    // ]


    七、内置插件全景

    v0.2.6 共包含 15 个实用插件,覆盖构建优化的各个方面:

    插件enforce描述
    assetManifest post 构建后生成资源映射清单,支持 Vite/Webpack/自定义格式、按入口分组和运行时注入
    autoImport pre 自动导入,支持预设映射、通配符('*')、目录扫描、Vue 模板自动导入和类型声明生成
    buildProgress 终端实时构建进度条,支持 bar / spinner / minimal
    bundleAnalyzer post 构建产物体积分析,支持 JSON/HTML 报告、gzip 计算和阈值告警
    compressAssets post 构建产物压缩,支持 gzip / brotli / both,并发压缩和统计报告
    copyFile post 构建完成后复制文件或目录,支持增量复制
    envGuard post 环境变量校验,支持类型检查、范围验证、自定义规则和运行时守卫
    faviconManager post 管理网站图标链接注入和文件复制
    generateRouter post 根据 pages.json 自动生成路由配置与类型声明(uni-app)
    generateVersion post 自动生成版本号,支持文件输出和全局变量注入
    htmlInject post HTML 内容注入,支持多种位置、选择器定位、条件注入和安全过滤
    imageOptimizer post 图片优化压缩与格式转换,支持 WebP/AVIF 转换、SVG 优化、并发处理
    loadingManager post 全局 Loading 状态管理,支持请求拦截、防抖、过渡动画
    proxyManager 开发代理管理,支持环境切换、规则文件、请求日志、延迟模拟和响应修改
    versionUpdateChecker post 运行时版本更新检查,支持多种提示样式和自定义回调

    八、Common 工具模块全景

    v0.2.6 共包含 14 个 Common 工具子模块:

    子路径核心能力
    common/code JS 关键字集合、代码注释与字符串移除(静态分析预处理)
    common/compress gzip 压缩大小计算
    common/concurrency 带并发限制的批量异步执行
    common/env .env 文件内容解析(支持引号去除和前缀过滤)
    common/format 日期参数提取、模板变量替换、日期格式化、文件大小格式化、压缩率计算、插件模板解析
    common/fs 源文件检查、文件/目录复制、目录扫描、批量删除、文件写入、JSON 报告、文件变更检测
    common/hash 随机哈希生成(加密级随机数,用于版本标识、缓存破坏)
    common/html HTML 标签注入、双区域注入、内容安全消毒、HTML 属性值转义
    common/object 深度合并对象(递归合并普通对象,跳过 undefined)
    common/path 路径规范化、扩展名过滤、路径排除匹配、预压缩格式检测
    common/script 回调函数体包装为安全的函数表达式(含 try-catch)
    common/string 大小写转换(camelCase/PascalCase)、JSON 注释移除、正则特殊字符转义
    common/ui 终端 ANSI 颜色码常量
    common/validation 链式配置验证器、全局名称校验、脚本检测、回调字段校验

    九、子路径导出变更

    新增

    • 新增 @meng-xi/vite-plugin/common/code 子路径导出
    • 新增 @meng-xi/vite-plugin/common/compress 子路径导出
    • 新增 @meng-xi/vite-plugin/common/env 子路径导出
    • 新增 @meng-xi/vite-plugin/common/hash 子路径导出
    • 新增 @meng-xi/vite-plugin/common/object 子路径导出
    • 新增 @meng-xi/vite-plugin/common/string 子路径导出

    新增导出函数

    • @meng-xi/vite-plugin/common/code 新增导出:JS_KEYWORDS、stripCommentsAndStrings
    • @meng-xi/vite-plugin/common/compress 新增导出:calculateGzipSize
    • @meng-xi/vite-plugin/common/env 新增导出:parseEnvContent
    • @meng-xi/vite-plugin/common/format 新增导出:parsePluginTemplate
    • @meng-xi/vite-plugin/common/hash 新增导出:generateRandomHash
    • @meng-xi/vite-plugin/common/object 新增导出:deepMerge
    • @meng-xi/vite-plugin/common/string 新增导出:toCamelCase、toPascalCase、stripJsonComments、escapeRegex

    移除

    无移除项,本次版本完全向后兼容。


    十、升级指南

    10.1 平滑升级

    v0.2.6 无 Breaking Change,直接升级即可:

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

    10.2 可选:使用新增的 Common 子模块

    如果你有自定义插件或脚本需要用到深度合并、哈希生成等工具,现在可以直接从 common 子路径导入,无需自行实现:

    // 之前:自行实现或从插件内部导入(不推荐)
    // 现在:直接从 common 子路径导入
    import { deepMerge } from '@meng-xi/vite-plugin/common/object'
    import { generateRandomHash } from '@meng-xi/vite-plugin/common/hash'
    import { toCamelCase } from '@meng-xi/vite-plugin/common/string'


    写在最后

    v0.2.6 是一次"内部健康度"优化版本。虽然对用户可见的 API 变化不多,但这次重构为后续版本的功能扩展打下了更干净的基础:

    • Common 模块扩展让通用工具可以独立复用,减少未来新插件的开发成本
    • 版本号注入自动化消除了发版时的人工操作风险
    • 目录结构统一让代码库更易维护和贡献

    下一个版本我们将继续聚焦于功能增强和开发者体验优化。如果你有任何建议或问题,欢迎在 GitHub Issues 反馈。

    赞(0)
    未经允许不得转载:171主机测评 » Vite插件v0.2.6:架构优化与自动化升级
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址