Vite 0.1.8:图片优化神器,构建更轻量
版本:0.1.8 | 协议:MIT | 依赖:Vite >=5.0.0 <8.0.0
写在前面
v0.1.8 的主题是:让图片更轻量,让工具链更完整。
随着 Web 应用对图片资源的需求日益增长,构建产物中的图片体积往往占据了整体资源的大头。v0.1.8 新增的 imageOptimizer 插件,在构建完成后自动扫描并优化图片文件,支持 7 种格式的压缩和位图格式间的相互转换,配合并发处理和压缩报告,实现从构建到部署的图片优化闭环。
同时,Common 工具模块也迎来了重要更新:新增 concurrency 并发控制模块,恢复 path 路径工具模块,format 和 fs 模块也各自新增了实用函数。这些增强不仅服务于 imageOptimizer,也为未来更多插件的开发提供了基础设施。
本版重点:
| 能力 | 一句话说明 | 你需要做什么 |
|---|---|---|
imageOptimizer 图片优化 |
构建后自动压缩和转换图片,支持 7 种格式、WebP/AVIF 转换、并发处理 | 新增配置 |
common/concurrency 并发控制 |
带并发限制的批量异步执行,工作池模式 | 可直接使用 |
common/path 路径工具 |
跨平台路径规范化、扩展名过滤、路径排除匹配 | 恢复可用 |
common/format 增强 |
新增 calcRatio 压缩率计算 |
可直接使用 |
common/fs 增强 |
新增 resolveReportPath 报告路径解析 |
可直接使用 |
升级方式:修改 devDependencies 中版本号为 ^0.1.8。无 Breaking Changes,完全向后兼容。
一、5 分钟快速上手
1.1 安装与最小配置
{
"devDependencies": {
"@meng-xi/vite-plugin": "^0.1.8"
}
}
import { imageOptimizer } from '@meng-xi/vite-plugin'
export default defineConfig({
plugins: [
imageOptimizer({
quality: { jpeg: 80, webp: 75 },
convertToWebp: { png: true, jpeg: true }
})
]
})
1.2 立刻看到效果
构建完成后,终端输出优化统计:
✅ [@meng-xi/vite-plugin:image-optimizer] 图片优化完成: 23 个文件已优化
原始体积: 2.35MB → 优化后: 1.12MB,压缩率: 52.3%,格式转换: 15 个,耗时: 3420ms
ℹ️ [@meng-xi/vite-plugin:image-optimizer] JPEG 8 个文件,1.20MB → 680.00KB,压缩率: 43.3%
ℹ️ [@meng-xi/vite-plugin:image-optimizer] PNG 10 个文件,800.00KB → 320.00KB,压缩率: 60.0%
ℹ️ [@meng-xi/vite-plugin:image-optimizer] WebP 5 个文件,360.00KB → 120.00KB,压缩率: 66.7%
ℹ️ [@meng-xi/vite-plugin:image-optimizer] 压缩率 Top 5:
ℹ️ [@meng-xi/vite-plugin:image-optimizer] 72.5% 450.00KB → 123.75KB (png→webp) assets/hero.png
ℹ️ [@meng-xi/vite-plugin:image-optimizer] 68.1% 320.00KB → 102.08KB (png→webp) assets/banner.png
同时生成 image-optimize-report.json 压缩报告。
1.3 运行时访问优化数据
const plugin = imageOptimizer({ reportOutput: 'image-report.json' })
// 构建完成后...
const stats = plugin.pluginInstance?.getStats?.() // 每个文件的优化统计
const summary = plugin.pluginInstance?.getSummary?.() // 汇总统计
二、核心能力:imageOptimizer 图片优化
2.1 多格式压缩
支持 7 种图片格式的压缩优化,每种格式使用业界最优算法:
| 格式 | 引擎 | 算法/参数 | 默认质量 |
|---|---|---|---|
| JPEG | sharp | mozjpeg | 80 |
| PNG | sharp | palette | 6 |
| WebP | sharp | 有损压缩 | 75 |
| AVIF | sharp | 有损压缩 | 50 |
| GIF | sharp | 调色板优化 | true |
| TIFF | sharp | deflate 压缩 | 'deflate' |
| SVG | svgo | 插件体系 | - |
imageOptimizer({
quality: {
jpeg: 80, // JPEG 质量 1-100
png: 6, // PNG 压缩级别 1-9
webp: 75, // WebP 质量 1-100
avif: 50, // AVIF 质量 1-100
gif: true, // GIF 调色板优化
tiff: 'deflate' // TIFF 压缩算法
}
})
2.2 格式转换
支持位图格式之间的相互转换,提供三种配置方式:
简写配置:convertToWebp / convertToAvif
imageOptimizer({
// 将 PNG 和 JPEG 转换为 WebP
convertToWebp: { png: true, jpeg: true },
// 将 GIF 转换为 AVIF
convertToAvif: { gif: true }
})
自定义映射:convertMapping
imageOptimizer({
// 优先级高于 convertToWebp/convertToAvif
convertMapping: {
png: 'avif', // PNG → AVIF
jpeg: 'webp', // JPEG → WebP
gif: 'webp' // GIF → WebP
}
})
保留原始文件
imageOptimizer({
convertToWebp: { png: true },
keepOriginal: true // 保留原始 PNG 文件,同时生成 WebP 版本
})
2.3 SVG 优化
通过 svgo 插件体系优化 SVG 文件,支持自定义插件列表和多进程优化:
imageOptimizer({
svgo: {
plugins: [
{ name: 'removeViewBox', active: false }, // 保留 viewBox
{ name: 'removeEmptyContainers', active: true }, // 移除空容器
{ name: 'collapseGroups', active: true } // 折叠分组
],
multipass: true // 多进程优化,SVG 文件较多时建议开启
}
})
2.4 并发处理
使用工作池模式并发执行优化操作,充分利用多核 CPU:
imageOptimizer({
parallelLimit: 5 // 最大并发数,默认 5,范围 1-50
})
内部使用 common/concurrency 模块的 runWithConcurrency 函数实现,确保结果顺序与输入项对应。
2.5 内存控制与原子写入
- 流式处理:使用流式读取和临时文件,避免大图片导致内存溢出
- 原子写入:先写临时文件再重命名,确保异常时原文件不损坏
- 体积守恒:仅当优化后体积更小时才替换原文件
2.6 优雅降级
sharp 和 svgo 均为可选依赖,不可用时提供清晰的错误提示:
⚠️ [@meng-xi/vite-plugin:image-optimizer] sharp 模块不可用,位图格式优化将跳过。请安装: npm install sharp
⚠️ [@meng-xi/vite-plugin:image-optimizer] svgo 模块不可用,SVG 优化将跳过。请安装: npm install svgo
2.7 压缩报告
构建完成后自动生成 JSON 格式的优化统计报告:
imageOptimizer({
reportOutput: 'image-optimize-report.json' // 输出路径,设为 false 不生成
})
报告内容示例:
{
"totalFiles": 23,
"skippedFiles": 2,
"failedFiles": 0,
"totalOriginalSize": 2461726,
"totalOptimizedSize": 1173120,
"totalRatio": 52.3,
"byFormat": {
"jpeg": { "count": 8, "originalSize": 1228800, "optimizedSize": 696320, "ratio": 43.3 },
"png": { "count": 10, "originalSize": 819200, "optimizedSize": 327680, "ratio": 60.0 },
"webp": { "count": 5, "originalSize": 368640, "optimizedSize": 122880, "ratio": 66.7 }
},
"convertedFiles": 15,
"executionTime": 3420,
"stats": [
{
"file": "/dist/assets/hero-abc123.png",
"relativePath": "assets/hero-abc123.png",
"originalSize": 460800,
"optimizedSize": 126720,
"ratio": 72.5,
"sourceFormat": "png",
"outputFormat": "webp",
"converted": true,
"duration": 120
}
]
}
2.8 实例方法
插件实例提供两个方法供外部访问优化数据:
const plugin = imageOptimizer({ quality: { jpeg: 80 } })
// 构建完成后...
const stats = plugin.pluginInstance?.getStats?.() // ImageOptimizeStats[]
const summary = plugin.pluginInstance?.getSummary?.() // ImageOptimizeSummary | null
三、Common 工具模块增强
3.1 common/concurrency(新增)
带并发限制的批量异步执行模块,使用工作池模式:
import { runWithConcurrency } from '@meng-xi/vite-plugin/common/concurrency'
// 最多 3 个任务同时执行
const results = await runWithConcurrency(
[1, 2, 3, 4, 5],
async (n) => {
await delay(100)
return n * 2
},
3
)
// [2, 4, 6, 8, 10] — 结果顺序与输入项对应
核心特性:
- 工作池模式:创建 N 个 worker 并发消费任务队列
- 顺序保证:结果数组顺序与输入项一一对应
- 自适应:并发数大于等于项数时,所有项同时执行
3.2 common/path(恢复)
0.1.5 版本中移除的 common/path 模块重新添加,提供更完善的路径工具函数:
import {
normalizePath,
isExtensionIncluded,
isPathExcluded,
isPreCompressed
} from '@meng-xi/vite-plugin/common/path'
| 函数 | 描述 |
|---|---|
normalizePath(filePath) |
将反斜杠转换为正斜杠,确保跨平台一致性 |
isExtensionIncluded(ext, options) |
检查扩展名是否通过包含/排除过滤 |
isPathExcluded(path, excludePaths, options) |
检查路径是否匹配排除列表,支持 simple/segment 两种匹配模式 |
isPreCompressed(ext) |
检查是否为已压缩格式(.gz / .br) |
segment 匹配模式:基于路径段边界精确匹配,避免 excludePaths: ['test'] 误排除 testdata/ 目录:
isPathExcluded('testdata/file.js', ['test'], { matchMode: 'segment' }) // false
isPathExcluded('assets/test/file.js', ['test'], { matchMode: 'segment' }) // true
3.3 common/format(增强)
新增 calcRatio 压缩率计算函数:
import { calcRatio } from '@meng-xi/vite-plugin/common/format'
calcRatio(10000, 6000) // 40.0 — 体积减少 40%
calcRatio(10000, 10000) // 0 — 无压缩
calcRatio(0, 0) // 0 — 避免除零
完整导出清单:
| 函数 | 描述 |
|---|---|
getDateFormatParams(date) |
提取日期格式化参数 |
parseTemplate(template, values) |
替换 {{key}} 模板占位符 |
formatDate(date, format) |
使用 {YYYY} 等占位符格式化日期 |
formatFileSize(bytes) |
字节数格式化为可读文件大小 |
calcRatio(originalSize, compressedSize) |
新增 计算压缩率百分比 |
3.4 common/fs(增强)
新增 resolveReportPath 报告路径解析函数:
import { resolveReportPath } from '@meng-xi/vite-plugin/common/fs'
resolveReportPath('dist', 'report.json') // 'dist/report.json'
resolveReportPath('dist', '/tmp/r.json') // '/tmp/r.json'
resolveReportPath('dist', false) // null
完整导出清单:
| 函数 | 描述 |
|---|---|
checkSourceExists(sourcePath) |
检查源文件是否存在 |
copySourceToTarget(source, target, options) |
复制文件/目录,支持增量、并发 |
writeFileContent(filePath, content) |
异步写入文件内容 |
scanDirectory(dirPath, options) |
递归扫描目录,收集文件信息 |
writeJsonReport(filePath, data) |
将数据写入 JSON 文件 |
writeFileSyncSafely(filePath, content) |
同步写入文件,自动创建目录 |
shouldUpdateFileContent(filePath, newContent) |
检查文件内容是否需要更新 |
resolveReportPath(outDir, reportPath) |
新增 解析报告输出路径 |
四、插件开发框架
本包导出完整的插件开发框架,帮助快速构建符合规范的自定义 Vite 插件。
4.1 BasePlugin 插件基类
所有内置插件的基类,提供配置管理、日志记录、错误处理和生命周期管理:
import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin'
import type { Plugin } from 'vite'
interface MyPluginOptions {
prefix?: string
}
class MyPlugin extends BasePlugin<MyPluginOptions> {
protected getPluginName() {
return 'my-plugin'
}
protected getDefaultOptions() {
return { prefix: '[app]' }
}
protected validateOptions() {
this.validator.field('prefix').string().notEmpty().validate()
}
protected addPluginHooks(plugin: Plugin) {
plugin.writeBundle = {
order: 'post',
handler: async () => {
await this.safeExecute(async () => {
this.logger.info('插件执行中...')
}, '执行自定义逻辑')
}
}
}
}
export const myPlugin = createPluginFactory(MyPlugin)
核心能力:
| 方法 | 描述 |
|---|---|
getDefaultOptions() |
提供插件默认配置 |
validateOptions() |
使用 Validator 校验配置 |
getPluginName() |
定义插件名称 |
getEnforce() |
定义执行时机(pre/post) |
addPluginHooks(plugin) |
注册 Vite 钩子 |
safeExecute(fn, context) |
安全执行异步函数,自动错误处理 |
safeExecuteSync(fn, context) |
安全执行同步函数 |
handleError(error, context) |
根据 errorStrategy 处理错误 |
onConfigResolved(config) |
配置解析完成回调 |
destroy() |
插件销毁回调 |
通用配置(所有插件继承):
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
enabled |
boolean |
true |
是否启用插件 |
verbose |
boolean |
true |
是否启用日志 |
errorStrategy |
'throw' | 'log' | 'ignore' |
'throw' |
错误处理策略 |
4.2 createPluginFactory 插件工厂
将 BasePlugin 子类转换为 Vite 插件函数,支持选项标准化器:
// 基本使用
const myPlugin = createPluginFactory(MyPlugin)
// 带标准化器(支持字符串简写配置)
const myPlugin = createPluginFactory(MyPlugin, (opt) =>
typeof opt === 'string' ? { path: opt } : opt
)
工厂函数返回的插件对象包含 pluginInstance 属性,可访问插件内部状态:
const plugin = myPlugin({ prefix: '[app]' })
plugin.pluginInstance // MyPlugin 实例
4.3 Validator 链式验证器
流畅的 API 用于验证插件配置:
this.validator
.field('sourceDir').required().string()
.field('targetDir').required().string()
.field('overwrite').boolean().default(true)
.field('concurrency').number().minValue(1).maxValue(50)
.field('format').enum(['json', 'html', 'text'])
.field('customOption').custom(v => v > 0, '必须大于 0')
.validate()
| 方法 | 描述 |
|---|---|
field(name) |
指定要验证的字段 |
required() |
标记为必填 |
string() / number() / boolean() / array() / object() |
类型验证 |
enum(values) |
枚举值验证 |
minValue(min) / maxValue(max) |
数值范围验证 |
default(value) |
设置默认值 |
custom(fn, message) |
自定义验证 |
validate() |
执行验证,失败时抛出错误 |
4.4 Logger 日志管理器
全局单例日志管理器,为每个插件提供独立日志代理:
import { Logger } from '@meng-xi/vite-plugin'
// 创建日志记录器
const logger = Logger.create({ name: 'my-plugin', enabled: true })
// 获取插件日志代理
const pluginLogger = logger.createPluginLogger('my-plugin')
pluginLogger.success('操作成功')
pluginLogger.info('信息提示')
pluginLogger.warn('警告信息')
pluginLogger.error('错误信息')
输出格式:icon [@meng-xi/vite-plugin:plugin-name] message
五、内置插件全景
v0.1.8 共包含 14 个实用插件,覆盖构建优化的各个方面:
| 插件 | 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 状态管理,支持请求拦截、防抖、过渡动画 |
versionUpdateChecker |
post | 运行时版本更新检查,支持多种提示样式和自定义回调 |
六、Common 工具模块全景
8 个工具模块,支持子路径按需导入:
| 子路径 | 导出内容 | 描述 |
|---|---|---|
common/concurrency |
runWithConcurrency |
新增 并发控制,工作池模式 |
common/format |
getDateFormatParams, parseTemplate, formatDate, formatFileSize, calcRatio |
日期格式化、模板替换、文件大小格式化、压缩率计算 |
common/fs |
checkSourceExists, copySourceToTarget, writeFileContent, scanDirectory, writeJsonReport, writeFileSyncSafely, shouldUpdateFileContent, resolveReportPath |
文件系统操作、目录扫描、报告生成 |
common/html |
injectBeforeTag, injectHeadAndBody, sanitizeContent, escapeHtmlAttr |
HTML 注入、安全消毒、属性转义 |
common/path |
normalizePath, isExtensionIncluded, isPathExcluded, isPreCompressed |
恢复 路径规范化、扩展名过滤、路径排除匹配 |
common/script |
makeCallback |
回调函数体包装为安全函数表达式 |
common/ui |
ANSI |
终端 ANSI 颜色码常量 |
common/validation |
Validator, validateGlobalName, validateNoScriptInTemplate, validateCallbackFields |
链式验证器、全局名称校验、脚本检测 |
七、配置选项
imageOptimizer 完整配置
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| quality | FormatQualityOptions |
{ jpeg: 80, png: 6, webp: 75, avif: 50, gif: true, tiff: 'deflate' } |
各格式的压缩质量参数 |
| convertToWebp | Partial<Record<'jpeg' | 'png' | 'gif' | 'tiff', boolean>> |
{} |
需要转换为 WebP 的源格式映射 |
| convertToAvif | Partial<Record<'jpeg' | 'png' | 'gif' | 'tiff', boolean>> |
{} |
需要转换为 AVIF 的源格式映射 |
| convertMapping | ConvertMapping |
{} |
自定义格式转换映射,优先级高于简写配置 |
| svgo | SvgoOptions |
{ plugins: [], multipass: false } |
SVG 优化配置 |
| includeExtensions | string[] |
['.jpg', '.jpeg', '.png', '.webp', '.avif', '.gif', '.tiff', '.tif', '.svg'] |
需要优化的文件扩展名 |
| excludePaths | string[] |
[] |
需要排除的路径前缀列表 |
| threshold | number |
0 |
最小优化阈值(字节) |
| keepOriginal | boolean |
true |
格式转换时是否保留原始文件 |
| reportOutput | string | false |
'image-optimize-report.json' |
压缩报告输出路径 |
| parallelLimit | number |
5 |
并发优化的最大文件数 |
| maxPixels | number |
0 |
单个图片最大像素数,超过则缩放 |
继承
BasePluginOptions通用配置:enabled、verbose、errorStrategy。
八、类型导出
imageOptimizer 新增类型
| 类型 | 描述 |
|---|---|
ImageOptimizerOptions |
插件配置选项 |
ImageFormat |
支持的图片格式类型 |
ConvertMapping |
格式转换映射配置 |
FormatQualityOptions |
各格式压缩质量参数 |
SvgoOptions |
SVG 优化配置 |
SvgoPlugin |
SVGO 单个插件配置 |
ImageOptimizeStats |
单个文件的优化统计 |
ImageOptimizeSummary |
优化操作的汇总统计 |
common/concurrency 新增类型
无独立类型导出,runWithConcurrency 为泛型函数。
common/path 恢复类型
无独立类型导出,所有函数参数均为基础类型。
九、实战场景
9.1 WebP 格式转换 + CDN 部署
import { defineConfig } from 'vite'
import { imageOptimizer, assetManifest } from '@meng-xi/vite-plugin'
export default defineConfig({
plugins: [
imageOptimizer({
convertToWebp: { png: true, jpeg: true },
keepOriginal: true,
quality: { webp: 75 },
reportOutput: 'image-report.json'
}),
assetManifest({
publicPath: 'https://cdn.example.com/',
injectRuntime: true
})
]
})
运行时根据浏览器支持情况选择图片格式:
const manifest = window.__ASSET_MANIFEST__
const supportsWebp = document.createElement('canvas').toDataURL('image/webp').startsWith('data:image/webp')
function getImageUrl(originalPath: string) {
if (supportsWebp) {
const webpPath = originalPath.replace(/\.(png|jpeg|jpg)$/, '.webp')
return manifest.assets[webpPath] || manifest.assets[originalPath]
}
return manifest.assets[originalPath]
}
9.2 AVIF 高压缩率方案
imageOptimizer({
convertMapping: {
png: 'avif',
jpeg: 'avif'
},
quality: { avif: 50 },
keepOriginal: true,
parallelLimit: 3, // AVIF 编码较慢,降低并发
maxPixels: 4000000 // 限制最大 4K 分辨率
})
9.3 SVG 精细化优化
imageOptimizer({
svgo: {
plugins: [
{ name: 'removeViewBox', active: false },
{ name: 'removeEmptyContainers', active: true },
{ name: 'collapseGroups', active: true },
{ name: 'mergePaths', active: true },
{ name: 'removeUnusedNS', active: true }
],
multipass: true
},
includeExtensions: ['.svg'],
reportOutput: 'svg-optimize-report.json'
})
9.4 uni-app 项目完整配置
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import {
imageOptimizer,
assetManifest,
autoImport,
compressAssets,
generateVersion,
htmlInject,
loadingManager,
versionUpdateChecker
} from './uni_modules/vite-plugin/js_sdk/index.mjs'
const isH5 = process.env.UNI_PLATFORM === 'h5'
const isProd = process.env.NODE_ENV === 'production'
export default defineConfig({
plugins: [
uni(),
// 图片优化(仅 H5 生产环境)
imageOptimizer({
quality: { jpeg: 80, png: 6, webp: 75, avif: 50 },
convertToWebp: { png: true, jpeg: true },
keepOriginal: true,
parallelLimit: 5,
reportOutput: 'image-optimize-report.json',
enabled: isH5 && isProd
}),
// 其他插件...
compressAssets({ algorithm: 'both', enabled: isProd }),
generateVersion({ format: 'datetime', outputType: 'both' }),
autoImport({ imports: { vue: ['*'] }, dts: true, vueTemplate: true })
]
})
9.5 自定义插件中使用 Common 工具
import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin'
import { scanDirectory, resolveReportPath, formatFileSize, calcRatio } from '@meng-xi/vite-plugin'
import { runWithConcurrency } from '@meng-xi/vite-plugin/common/concurrency'
import { isExtensionIncluded, isPathExcluded } from '@meng-xi/vite-plugin/common/path'
import type { Plugin } from 'vite'
class CustomAnalyzerPlugin extends BasePlugin<CustomAnalyzerOptions> {
protected getPluginName() { return 'custom-analyzer' }
protected addPluginHooks(plugin: Plugin) {
plugin.writeBundle = async () => {
await this.safeExecute(async () => {
const outDir = this.viteConfig!.build.outDir
// 使用 scanDirectory 扫描文件
const files = await scanDirectory(outDir, {
includeExtensions: ['.js', '.css'],
filter: (filePath, ext, size) => size > 1024 // 仅大于 1KB 的文件
})
// 使用 calcRatio 计算压缩率
const stats = files.map(f => ({
path: f.filePath,
size: formatFileSize(f.size)
}))
// 使用 resolveReportPath 解析报告路径
const reportPath = resolveReportPath(outDir, this.options.reportFile)
if (reportPath) {
// 写入报告...
}
}, '分析构建产物')
}
}
}
十、子路径导出变更
| 子路径 | 变更 | 内容 |
|---|---|---|
@meng-xi/vite-plugin/plugins/image-optimizer |
新增 | imageOptimizer 函数及所有类型导出 |
@meng-xi/vite-plugin/common/concurrency |
新增 | runWithConcurrency 函数 |
@meng-xi/vite-plugin/common/path |
恢复 | normalizePath、isExtensionIncluded、isPathExcluded、isPreCompressed |
@meng-xi/vite-plugin/common/format |
增强 | 新增 calcRatio |
@meng-xi/vite-plugin/common/fs |
增强 | 新增 resolveReportPath |
十一、迁移指南
从 v0.1.7 升级到 v0.1.8
1. 启用图片优化(可选)
import { imageOptimizer } from '@meng-xi/vite-plugin'
export default defineConfig({
plugins: [
imageOptimizer({
quality: { jpeg: 80, webp: 75 },
convertToWebp: { png: true, jpeg: true }
})
]
})
2. 安装可选依赖
# 位图格式优化(JPEG/PNG/WebP/AVIF/GIF/TIFF)
pnpm add sharp -D
# SVG 优化
pnpm add svgo -D
两者均为可选依赖,不安装时插件会优雅降级,跳过对应格式的优化。
3. 使用恢复的 path 模块
0.1.5 中移除的 common/path 已恢复,且功能更完善:
import { normalizePath, isPathExcluded } from '@meng-xi/vite-plugin/common/path'
// 新增 segment 匹配模式
isPathExcluded('testdata/file.js', ['test'], { matchMode: 'segment' }) // false
4. 子路径独立导入
import { imageOptimizer } from '@meng-xi/vite-plugin/plugins/image-optimizer'
import type { ImageOptimizerOptions, ImageOptimizeStats } from '@meng-xi/vite-plugin/plugins/image-optimizer'
import { runWithConcurrency } from '@meng-xi/vite-plugin/common/concurrency'
import { normalizePath } from '@meng-xi/vite-plugin/common/path'
import { calcRatio } from '@meng-xi/vite-plugin/common/format'
import { resolveReportPath } from '@meng-xi/vite-plugin/common/fs'
本文基于 @meng-xi/vite-plugin@0.1.8 版本撰写,所有代码示例均来自实际源码。

浙公网安备 33010602011771号