@meng-xi/vite-plugin 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README-en.md +39 -17
  2. package/README.md +52 -30
  3. package/dist/common/concurrency/index.cjs +1 -0
  4. package/dist/common/concurrency/index.d.cts +26 -0
  5. package/dist/common/concurrency/index.d.mts +26 -0
  6. package/dist/common/concurrency/index.d.ts +26 -0
  7. package/dist/common/concurrency/index.mjs +1 -0
  8. package/dist/common/format/index.cjs +1 -1
  9. package/dist/common/format/index.d.cts +19 -1
  10. package/dist/common/format/index.d.mts +19 -1
  11. package/dist/common/format/index.d.ts +19 -1
  12. package/dist/common/format/index.mjs +1 -1
  13. package/dist/common/fs/index.cjs +1 -1
  14. package/dist/common/fs/index.d.cts +19 -1
  15. package/dist/common/fs/index.d.mts +19 -1
  16. package/dist/common/fs/index.d.ts +19 -1
  17. package/dist/common/fs/index.mjs +1 -1
  18. package/dist/common/index.cjs +1 -1
  19. package/dist/common/index.d.cts +3 -2
  20. package/dist/common/index.d.mts +3 -2
  21. package/dist/common/index.d.ts +3 -2
  22. package/dist/common/index.mjs +1 -1
  23. package/dist/index.cjs +1 -1
  24. package/dist/index.d.cts +4 -2
  25. package/dist/index.d.mts +4 -2
  26. package/dist/index.d.ts +4 -2
  27. package/dist/index.mjs +1 -1
  28. package/dist/plugins/assetManifest/index.cjs +1 -1
  29. package/dist/plugins/assetManifest/index.mjs +1 -1
  30. package/dist/plugins/autoImport/index.cjs +13 -13
  31. package/dist/plugins/autoImport/index.mjs +8 -8
  32. package/dist/plugins/bundleAnalyzer/index.cjs +1 -1
  33. package/dist/plugins/bundleAnalyzer/index.mjs +1 -1
  34. package/dist/plugins/compressAssets/index.cjs +1 -1
  35. package/dist/plugins/compressAssets/index.mjs +1 -1
  36. package/dist/plugins/copyFile/index.cjs +1 -1
  37. package/dist/plugins/copyFile/index.mjs +1 -1
  38. package/dist/plugins/envGuard/index.cjs +1 -1
  39. package/dist/plugins/envGuard/index.mjs +1 -1
  40. package/dist/plugins/faviconManager/index.cjs +1 -1
  41. package/dist/plugins/faviconManager/index.mjs +1 -1
  42. package/dist/plugins/generateRouter/index.cjs +3 -3
  43. package/dist/plugins/generateRouter/index.mjs +1 -1
  44. package/dist/plugins/generateVersion/index.cjs +1 -1
  45. package/dist/plugins/generateVersion/index.mjs +1 -1
  46. package/dist/plugins/imageOptimizer/index.cjs +5 -0
  47. package/dist/plugins/imageOptimizer/index.d.cts +242 -0
  48. package/dist/plugins/imageOptimizer/index.d.mts +242 -0
  49. package/dist/plugins/imageOptimizer/index.d.ts +242 -0
  50. package/dist/plugins/imageOptimizer/index.mjs +5 -0
  51. package/dist/plugins/index.cjs +1 -1
  52. package/dist/plugins/index.d.cts +1 -0
  53. package/dist/plugins/index.d.mts +1 -0
  54. package/dist/plugins/index.d.ts +1 -0
  55. package/dist/plugins/index.mjs +1 -1
  56. package/package.json +15 -1
@@ -0,0 +1,242 @@
1
+ import { BasePluginOptions, PluginFactory } from '../../factory/index.mjs';
2
+ import 'vite';
3
+ import '../../shared/vite-plugin.B8FuZce1.mjs';
4
+ import '../../shared/vite-plugin.DRRlWY8P.mjs';
5
+
6
+ /**
7
+ * 支持的图片格式类型
8
+ *
9
+ * @description 插件支持的所有图片格式:
10
+ * - `jpeg`: JPEG/JPG 格式
11
+ * - `png`: PNG 格式
12
+ * - `webp`: WebP 格式
13
+ * - `avif`: AVIF 格式
14
+ * - `gif`: GIF 格式
15
+ * - `tiff`: TIFF 格式
16
+ * - `svg`: SVG 矢量格式
17
+ */
18
+ type ImageFormat = 'jpeg' | 'png' | 'webp' | 'avif' | 'gif' | 'tiff' | 'svg';
19
+ /**
20
+ * 格式转换映射配置
21
+ *
22
+ * @description 定义从源格式到目标格式的转换规则。
23
+ * 键为源格式,值为目标格式。仅配置需要转换的格式。
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const convertMap: ConvertMapping = {
28
+ * png: 'webp', // PNG → WebP
29
+ * jpeg: 'avif' // JPEG → AVIF
30
+ * }
31
+ * ```
32
+ */
33
+ type ConvertMapping = Partial<Record<ImageFormat, ImageFormat>>;
34
+ /**
35
+ * 单个图片格式的优化配置
36
+ *
37
+ * @interface FormatQualityOptions
38
+ * @description 针对特定图片格式的压缩质量参数。
39
+ * 不同格式使用不同的质量衡量标准。
40
+ */
41
+ interface FormatQualityOptions {
42
+ /** JPEG 质量,范围 1-100,默认 80 */
43
+ jpeg?: number;
44
+ /** PNG 压缩级别,范围 1-9(仅 palette-based),默认 6 */
45
+ png?: number;
46
+ /** WebP 质量,范围 1-100,默认 75 */
47
+ webp?: number;
48
+ /** AVIF 质量,范围 1-100,默认 50 */
49
+ avif?: number;
50
+ /** GIF 优化选项:是否尝试调色板优化,默认 true */
51
+ gif?: boolean;
52
+ /** TIFF 压缩选项:压缩算法,默认 'deflate' */
53
+ tiff?: 'none' | 'lzw' | 'deflate' | 'packbits';
54
+ }
55
+ /**
56
+ * SVGO 单个插件配置
57
+ *
58
+ * @interface SvgoPlugin
59
+ * @description SVGO 插件配置项,name 为插件名称,其余为插件参数。
60
+ */
61
+ interface SvgoPlugin {
62
+ /** SVGO 插件名称 */
63
+ name: string;
64
+ /** 插件参数 */
65
+ [key: string]: unknown;
66
+ }
67
+ /**
68
+ * SVG 优化配置
69
+ *
70
+ * @interface SvgoOptions
71
+ * @description 传递给 SVGO 的插件配置,与 SVGO 官方配置格式一致。
72
+ * 每项为 SVGO 插件名称及激活状态。
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const svgo: SvgoOptions = {
77
+ * plugins: [
78
+ * { name: 'removeViewBox', active: false },
79
+ * { name: 'removeEmptyContainers', active: true }
80
+ * ]
81
+ * }
82
+ * ```
83
+ */
84
+ interface SvgoOptions {
85
+ /** SVGO 插件列表 */
86
+ plugins?: SvgoPlugin[];
87
+ /** 是否启用 SVGO 多进程优化(仅当 SVG 文件较多时建议开启) */
88
+ multipass?: boolean;
89
+ }
90
+ /**
91
+ * 单个文件的优化统计信息
92
+ *
93
+ * @interface ImageOptimizeStats
94
+ * @description 记录单个图片文件经过优化后的详细统计数据
95
+ */
96
+ interface ImageOptimizeStats {
97
+ /** 原始文件路径 */
98
+ file: string;
99
+ /** 相对于输出目录的相对路径 */
100
+ relativePath: string;
101
+ /** 原始文件大小(字节) */
102
+ originalSize: number;
103
+ /** 优化后文件大小(字节) */
104
+ optimizedSize: number;
105
+ /** 压缩率百分比(0-100),如 65.2 表示体积减少 65.2% */
106
+ ratio: number;
107
+ /** 源图片格式 */
108
+ sourceFormat: ImageFormat;
109
+ /** 输出图片格式(与 sourceFormat 相同表示仅压缩,不同表示格式转换) */
110
+ outputFormat: ImageFormat;
111
+ /** 是否发生了格式转换 */
112
+ converted: boolean;
113
+ /** 优化耗时(毫秒) */
114
+ duration: number;
115
+ }
116
+ /**
117
+ * 优化操作的汇总统计信息
118
+ *
119
+ * @interface ImageOptimizeSummary
120
+ * @description 包含整个优化操作的总体统计数据,用于报告生成和日志输出
121
+ */
122
+ interface ImageOptimizeSummary {
123
+ /** 优化的文件总数 */
124
+ totalFiles: number;
125
+ /** 跳过的文件数量 */
126
+ skippedFiles: number;
127
+ /** 失败的文件数量 */
128
+ failedFiles: number;
129
+ /** 所有文件的原始大小总和(字节) */
130
+ totalOriginalSize: number;
131
+ /** 所有文件的优化后大小总和(字节) */
132
+ totalOptimizedSize: number;
133
+ /** 总体压缩率百分比 */
134
+ totalRatio: number;
135
+ /** 按格式分组的统计 */
136
+ byFormat: Record<string, {
137
+ count: number;
138
+ originalSize: number;
139
+ optimizedSize: number;
140
+ ratio: number;
141
+ }>;
142
+ /** 格式转换统计:转换的文件数量 */
143
+ convertedFiles: number;
144
+ /** 优化操作总耗时(毫秒) */
145
+ executionTime: number;
146
+ /** 每个文件的详细优化统计 */
147
+ stats: ImageOptimizeStats[];
148
+ }
149
+ /**
150
+ * 图片优化插件的配置选项
151
+ *
152
+ * @interface ImageOptimizerOptions
153
+ * @extends {BasePluginOptions}
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * imageOptimizer({
158
+ * quality: { jpeg: 80, webp: 75, avif: 50 },
159
+ * convertToWebp: { png: true, jpeg: true },
160
+ * convertToAvif: { png: true },
161
+ * svgo: { plugins: [{ name: 'removeViewBox', active: false }] },
162
+ * keepOriginal: true,
163
+ * parallelLimit: 5,
164
+ * reportOutput: 'image-optimize-report.json'
165
+ * })
166
+ * ```
167
+ */
168
+ interface ImageOptimizerOptions extends BasePluginOptions {
169
+ /** 各格式的压缩质量参数 */
170
+ quality?: FormatQualityOptions;
171
+ /** 是否将指定格式转换为 WebP,值为需要转换的源格式映射 */
172
+ convertToWebp?: Partial<Record<'jpeg' | 'png' | 'gif' | 'tiff', boolean>>;
173
+ /** 是否将指定格式转换为 AVIF,值为需要转换的源格式映射 */
174
+ convertToAvif?: Partial<Record<'jpeg' | 'png' | 'gif' | 'tiff', boolean>>;
175
+ /** 自定义格式转换映射,优先级高于 convertToWebp/convertToAvif */
176
+ convertMapping?: ConvertMapping;
177
+ /** SVG 优化配置 */
178
+ svgo?: SvgoOptions;
179
+ /** 需要优化的文件扩展名列表 */
180
+ includeExtensions?: string[];
181
+ /** 需要排除的路径前缀列表 */
182
+ excludePaths?: string[];
183
+ /** 最小优化阈值(字节),小于此大小的文件将被跳过 */
184
+ threshold?: number;
185
+ /** 是否保留原始文件(格式转换时有效,仅压缩时原文件始终被覆盖) */
186
+ keepOriginal?: boolean;
187
+ /** 压缩报告输出路径,设为 false 则不生成报告 */
188
+ reportOutput?: string | false;
189
+ /** 并发优化的最大文件数 */
190
+ parallelLimit?: number;
191
+ /** 单个图片最大像素数,超过此值的图片将被缩放(0 表示不限制) */
192
+ maxPixels?: number;
193
+ }
194
+
195
+ /**
196
+ * 创建图片优化插件
197
+ *
198
+ * @function imageOptimizer
199
+ * @param {Partial<ImageOptimizerOptions>} [options] - 插件配置选项
200
+ * @returns {Plugin} Vite 插件实例
201
+ *
202
+ * @description 在 Vite 构建完成后自动优化输出目录中的图片文件,
203
+ * 支持多格式压缩、格式转换、并发处理、压缩报告生成等功能。
204
+ * 使用 sharp 处理位图格式,svgo 处理 SVG 格式。
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * // 基本使用:仅压缩
209
+ * imageOptimizer({
210
+ * quality: { jpeg: 80, png: 6, webp: 75 },
211
+ * reportOutput: 'image-optimize-report.json'
212
+ * })
213
+ *
214
+ * // 格式转换:PNG/JPEG → WebP
215
+ * imageOptimizer({
216
+ * convertToWebp: { png: true, jpeg: true },
217
+ * keepOriginal: true,
218
+ * quality: { webp: 75 }
219
+ * })
220
+ *
221
+ * // 自定义转换映射
222
+ * imageOptimizer({
223
+ * convertMapping: { png: 'avif', jpeg: 'webp' },
224
+ * quality: { avif: 50, webp: 75 }
225
+ * })
226
+ *
227
+ * // SVG 优化
228
+ * imageOptimizer({
229
+ * svgo: {
230
+ * plugins: [
231
+ * { name: 'removeViewBox', active: false },
232
+ * { name: 'removeEmptyContainers', active: true }
233
+ * ],
234
+ * multipass: true
235
+ * }
236
+ * })
237
+ * ```
238
+ */
239
+ declare const imageOptimizer: PluginFactory<ImageOptimizerOptions, ImageOptimizerOptions>;
240
+
241
+ export { imageOptimizer };
242
+ export type { ConvertMapping, FormatQualityOptions, ImageFormat, ImageOptimizeStats, ImageOptimizeSummary, ImageOptimizerOptions, SvgoOptions, SvgoPlugin };
@@ -0,0 +1,242 @@
1
+ import { BasePluginOptions, PluginFactory } from '../../factory/index.js';
2
+ import 'vite';
3
+ import '../../shared/vite-plugin.B8FuZce1.js';
4
+ import '../../shared/vite-plugin.DRRlWY8P.js';
5
+
6
+ /**
7
+ * 支持的图片格式类型
8
+ *
9
+ * @description 插件支持的所有图片格式:
10
+ * - `jpeg`: JPEG/JPG 格式
11
+ * - `png`: PNG 格式
12
+ * - `webp`: WebP 格式
13
+ * - `avif`: AVIF 格式
14
+ * - `gif`: GIF 格式
15
+ * - `tiff`: TIFF 格式
16
+ * - `svg`: SVG 矢量格式
17
+ */
18
+ type ImageFormat = 'jpeg' | 'png' | 'webp' | 'avif' | 'gif' | 'tiff' | 'svg';
19
+ /**
20
+ * 格式转换映射配置
21
+ *
22
+ * @description 定义从源格式到目标格式的转换规则。
23
+ * 键为源格式,值为目标格式。仅配置需要转换的格式。
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const convertMap: ConvertMapping = {
28
+ * png: 'webp', // PNG → WebP
29
+ * jpeg: 'avif' // JPEG → AVIF
30
+ * }
31
+ * ```
32
+ */
33
+ type ConvertMapping = Partial<Record<ImageFormat, ImageFormat>>;
34
+ /**
35
+ * 单个图片格式的优化配置
36
+ *
37
+ * @interface FormatQualityOptions
38
+ * @description 针对特定图片格式的压缩质量参数。
39
+ * 不同格式使用不同的质量衡量标准。
40
+ */
41
+ interface FormatQualityOptions {
42
+ /** JPEG 质量,范围 1-100,默认 80 */
43
+ jpeg?: number;
44
+ /** PNG 压缩级别,范围 1-9(仅 palette-based),默认 6 */
45
+ png?: number;
46
+ /** WebP 质量,范围 1-100,默认 75 */
47
+ webp?: number;
48
+ /** AVIF 质量,范围 1-100,默认 50 */
49
+ avif?: number;
50
+ /** GIF 优化选项:是否尝试调色板优化,默认 true */
51
+ gif?: boolean;
52
+ /** TIFF 压缩选项:压缩算法,默认 'deflate' */
53
+ tiff?: 'none' | 'lzw' | 'deflate' | 'packbits';
54
+ }
55
+ /**
56
+ * SVGO 单个插件配置
57
+ *
58
+ * @interface SvgoPlugin
59
+ * @description SVGO 插件配置项,name 为插件名称,其余为插件参数。
60
+ */
61
+ interface SvgoPlugin {
62
+ /** SVGO 插件名称 */
63
+ name: string;
64
+ /** 插件参数 */
65
+ [key: string]: unknown;
66
+ }
67
+ /**
68
+ * SVG 优化配置
69
+ *
70
+ * @interface SvgoOptions
71
+ * @description 传递给 SVGO 的插件配置,与 SVGO 官方配置格式一致。
72
+ * 每项为 SVGO 插件名称及激活状态。
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const svgo: SvgoOptions = {
77
+ * plugins: [
78
+ * { name: 'removeViewBox', active: false },
79
+ * { name: 'removeEmptyContainers', active: true }
80
+ * ]
81
+ * }
82
+ * ```
83
+ */
84
+ interface SvgoOptions {
85
+ /** SVGO 插件列表 */
86
+ plugins?: SvgoPlugin[];
87
+ /** 是否启用 SVGO 多进程优化(仅当 SVG 文件较多时建议开启) */
88
+ multipass?: boolean;
89
+ }
90
+ /**
91
+ * 单个文件的优化统计信息
92
+ *
93
+ * @interface ImageOptimizeStats
94
+ * @description 记录单个图片文件经过优化后的详细统计数据
95
+ */
96
+ interface ImageOptimizeStats {
97
+ /** 原始文件路径 */
98
+ file: string;
99
+ /** 相对于输出目录的相对路径 */
100
+ relativePath: string;
101
+ /** 原始文件大小(字节) */
102
+ originalSize: number;
103
+ /** 优化后文件大小(字节) */
104
+ optimizedSize: number;
105
+ /** 压缩率百分比(0-100),如 65.2 表示体积减少 65.2% */
106
+ ratio: number;
107
+ /** 源图片格式 */
108
+ sourceFormat: ImageFormat;
109
+ /** 输出图片格式(与 sourceFormat 相同表示仅压缩,不同表示格式转换) */
110
+ outputFormat: ImageFormat;
111
+ /** 是否发生了格式转换 */
112
+ converted: boolean;
113
+ /** 优化耗时(毫秒) */
114
+ duration: number;
115
+ }
116
+ /**
117
+ * 优化操作的汇总统计信息
118
+ *
119
+ * @interface ImageOptimizeSummary
120
+ * @description 包含整个优化操作的总体统计数据,用于报告生成和日志输出
121
+ */
122
+ interface ImageOptimizeSummary {
123
+ /** 优化的文件总数 */
124
+ totalFiles: number;
125
+ /** 跳过的文件数量 */
126
+ skippedFiles: number;
127
+ /** 失败的文件数量 */
128
+ failedFiles: number;
129
+ /** 所有文件的原始大小总和(字节) */
130
+ totalOriginalSize: number;
131
+ /** 所有文件的优化后大小总和(字节) */
132
+ totalOptimizedSize: number;
133
+ /** 总体压缩率百分比 */
134
+ totalRatio: number;
135
+ /** 按格式分组的统计 */
136
+ byFormat: Record<string, {
137
+ count: number;
138
+ originalSize: number;
139
+ optimizedSize: number;
140
+ ratio: number;
141
+ }>;
142
+ /** 格式转换统计:转换的文件数量 */
143
+ convertedFiles: number;
144
+ /** 优化操作总耗时(毫秒) */
145
+ executionTime: number;
146
+ /** 每个文件的详细优化统计 */
147
+ stats: ImageOptimizeStats[];
148
+ }
149
+ /**
150
+ * 图片优化插件的配置选项
151
+ *
152
+ * @interface ImageOptimizerOptions
153
+ * @extends {BasePluginOptions}
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * imageOptimizer({
158
+ * quality: { jpeg: 80, webp: 75, avif: 50 },
159
+ * convertToWebp: { png: true, jpeg: true },
160
+ * convertToAvif: { png: true },
161
+ * svgo: { plugins: [{ name: 'removeViewBox', active: false }] },
162
+ * keepOriginal: true,
163
+ * parallelLimit: 5,
164
+ * reportOutput: 'image-optimize-report.json'
165
+ * })
166
+ * ```
167
+ */
168
+ interface ImageOptimizerOptions extends BasePluginOptions {
169
+ /** 各格式的压缩质量参数 */
170
+ quality?: FormatQualityOptions;
171
+ /** 是否将指定格式转换为 WebP,值为需要转换的源格式映射 */
172
+ convertToWebp?: Partial<Record<'jpeg' | 'png' | 'gif' | 'tiff', boolean>>;
173
+ /** 是否将指定格式转换为 AVIF,值为需要转换的源格式映射 */
174
+ convertToAvif?: Partial<Record<'jpeg' | 'png' | 'gif' | 'tiff', boolean>>;
175
+ /** 自定义格式转换映射,优先级高于 convertToWebp/convertToAvif */
176
+ convertMapping?: ConvertMapping;
177
+ /** SVG 优化配置 */
178
+ svgo?: SvgoOptions;
179
+ /** 需要优化的文件扩展名列表 */
180
+ includeExtensions?: string[];
181
+ /** 需要排除的路径前缀列表 */
182
+ excludePaths?: string[];
183
+ /** 最小优化阈值(字节),小于此大小的文件将被跳过 */
184
+ threshold?: number;
185
+ /** 是否保留原始文件(格式转换时有效,仅压缩时原文件始终被覆盖) */
186
+ keepOriginal?: boolean;
187
+ /** 压缩报告输出路径,设为 false 则不生成报告 */
188
+ reportOutput?: string | false;
189
+ /** 并发优化的最大文件数 */
190
+ parallelLimit?: number;
191
+ /** 单个图片最大像素数,超过此值的图片将被缩放(0 表示不限制) */
192
+ maxPixels?: number;
193
+ }
194
+
195
+ /**
196
+ * 创建图片优化插件
197
+ *
198
+ * @function imageOptimizer
199
+ * @param {Partial<ImageOptimizerOptions>} [options] - 插件配置选项
200
+ * @returns {Plugin} Vite 插件实例
201
+ *
202
+ * @description 在 Vite 构建完成后自动优化输出目录中的图片文件,
203
+ * 支持多格式压缩、格式转换、并发处理、压缩报告生成等功能。
204
+ * 使用 sharp 处理位图格式,svgo 处理 SVG 格式。
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * // 基本使用:仅压缩
209
+ * imageOptimizer({
210
+ * quality: { jpeg: 80, png: 6, webp: 75 },
211
+ * reportOutput: 'image-optimize-report.json'
212
+ * })
213
+ *
214
+ * // 格式转换:PNG/JPEG → WebP
215
+ * imageOptimizer({
216
+ * convertToWebp: { png: true, jpeg: true },
217
+ * keepOriginal: true,
218
+ * quality: { webp: 75 }
219
+ * })
220
+ *
221
+ * // 自定义转换映射
222
+ * imageOptimizer({
223
+ * convertMapping: { png: 'avif', jpeg: 'webp' },
224
+ * quality: { avif: 50, webp: 75 }
225
+ * })
226
+ *
227
+ * // SVG 优化
228
+ * imageOptimizer({
229
+ * svgo: {
230
+ * plugins: [
231
+ * { name: 'removeViewBox', active: false },
232
+ * { name: 'removeEmptyContainers', active: true }
233
+ * ],
234
+ * multipass: true
235
+ * }
236
+ * })
237
+ * ```
238
+ */
239
+ declare const imageOptimizer: PluginFactory<ImageOptimizerOptions, ImageOptimizerOptions>;
240
+
241
+ export { imageOptimizer };
242
+ export type { ConvertMapping, FormatQualityOptions, ImageFormat, ImageOptimizeStats, ImageOptimizeSummary, ImageOptimizerOptions, SvgoOptions, SvgoPlugin };
@@ -0,0 +1,5 @@
1
+ import{createPluginFactory as A,BasePlugin as B}from"../../factory/index.mjs";import{promises as c}from"node:fs";import y from"node:path";import{scanDirectory as x,resolveReportPath as O,writeJsonReport as k}from"../../common/fs/index.mjs";import{normalizePath as R,isPathExcluded as j}from"../../common/path/index.mjs";import{calcRatio as h,formatFileSize as g}from"../../common/format/index.mjs";import{runWithConcurrency as D}from"../../common/concurrency/index.mjs";import"../../logger/index.mjs";import"../../shared/vite-plugin.DcExl6jd.mjs";import"fs";import"path";const T={".jpg":"jpeg",".jpeg":"jpeg",".png":"png",".webp":"webp",".avif":"avif",".gif":"gif",".tiff":"tiff",".tif":"tiff",".svg":"svg"};function z(e){return T[e]??null}function V(e){return{jpeg:".jpg",png:".png",webp:".webp",avif:".avif",gif:".gif",tiff:".tiff",svg:".svg"}[e]}function I(e,u,t,i){return!(!z(u)||t<i.threshold||i.includeExtensions.length>0&&!i.includeExtensions.includes(u)||j(e,i.excludePaths))}async function G(e,u){return(await x(e,{filter:(t,i,r)=>{const o=y.relative(e,t);return I(o,i,r,u)}})).map(t=>{const i=R(y.relative(e,t.filePath)),r=z(t.extension);return{filePath:t.filePath,relativePath:i,size:t.size,ext:t.extension,format:r}})}let m=null,v=!1;async function E(){if(m)return m;if(v)throw new Error("sharp \u6A21\u5757\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5B89\u88C5: npm install sharp");v=!0;try{const e=await import("sharp");return m=e.default||e,m}catch{throw new Error(`sharp \u6A21\u5757\u52A0\u8F7D\u5931\u8D25\u3002\u56FE\u7247\u4F18\u5316\u63D2\u4EF6\u9700\u8981 sharp \u4F5C\u4E3A\u4F9D\u8D56\u3002
2
+ \u8BF7\u8FD0\u884C: npm install sharp
3
+ sharp \u662F\u53EF\u9009\u4F9D\u8D56\uFF0C\u5982\u4E0D\u9700\u8981\u56FE\u7247\u4F18\u5316\u529F\u80FD\u53EF\u5FFD\u7565\u6B64\u9519\u8BEF\u3002`)}}let d=null,C=!1;async function S(){if(d)return d;if(C)throw new Error("svgo \u6A21\u5757\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5B89\u88C5: npm install svgo");C=!0;try{const e=await import("svgo");return d=e.default||e,d}catch{throw new Error(`svgo \u6A21\u5757\u52A0\u8F7D\u5931\u8D25\u3002SVG \u4F18\u5316\u9700\u8981 svgo \u4F5C\u4E3A\u4F9D\u8D56\u3002
4
+ \u8BF7\u8FD0\u884C: npm install svgo
5
+ \u5982\u4E0D\u9700\u8981 SVG \u4F18\u5316\u529F\u80FD\u53EF\u5FFD\u7565\u6B64\u9519\u8BEF\u3002`)}}function M(e,u){const t={jpeg:80,png:6,webp:75,avif:50,gif:!0,tiff:"deflate"};return u[e]??t[e]}function $(e,u){const t=M(e,u);switch(e){case"jpeg":return{quality:t,mozjpeg:!0};case"png":return{palette:!0,compressionLevel:t};case"webp":return{quality:t,effort:4};case"avif":return{quality:t,effort:4};case"gif":return{effort:7,colours:t===!0?void 0:t};case"tiff":return{compression:t};default:return{}}}async function q(e,u,t,i){const r=Date.now(),o=await E(),p=(await c.stat(e)).size;let l=o(e,{limitInputPixels:i>0?i:void 0});l=l.rotate();const a=$(u,t);l=l.toFormat(u,a),await l.toFile(e+".tmp");const s=(await c.stat(e+".tmp")).size;if(s<p)try{await c.rename(e+".tmp",e)}catch{try{await c.unlink(e+".tmp")}catch{}throw new Error(`\u538B\u7F29\u5931\u8D25: \u65E0\u6CD5\u5199\u5165\u8F93\u51FA\u6587\u4EF6 ${e}`)}else await c.unlink(e+".tmp");const n=Date.now()-r,F=s<p?s:p;return{file:e,relativePath:"",originalSize:p,optimizedSize:F,ratio:h(p,F),sourceFormat:u,outputFormat:u,converted:!1,duration:n}}async function L(e,u,t,i,r,o){const p=Date.now(),l=await E(),a=(await c.stat(e)).size;let s=l(e,{limitInputPixels:r>0?r:void 0});s=s.rotate();const n=$(t,i);s=s.toFormat(t,n);const F=V(t),f=e.replace(/\.[^.]+$/,F);await s.toFile(f+".tmp");const w=(await c.stat(f+".tmp")).size;try{await c.rename(f+".tmp",f)}catch{try{await c.unlink(f+".tmp")}catch{}throw new Error(`\u683C\u5F0F\u8F6C\u6362\u5931\u8D25: \u65E0\u6CD5\u5199\u5165\u8F93\u51FA\u6587\u4EF6 ${f}`)}if(!o&&f!==e)try{await c.unlink(e)}catch{}const b=Date.now()-p;return{file:o?f:e,relativePath:"",originalSize:a,optimizedSize:w,ratio:h(a,w),sourceFormat:u,outputFormat:t,converted:!0,duration:b}}async function W(e,u){const t=Date.now(),{optimize:i}=await S(),r=(await c.stat(e)).size,o=await c.readFile(e,"utf-8"),p=i(o,{path:e,multipass:u.multipass??!1,plugins:u.plugins??[]}),l=Buffer.byteLength(p.data,"utf-8");l<r&&await c.writeFile(e,p.data,"utf-8");const a=l<r?l:r,s=Date.now()-t;return{file:e,relativePath:"",originalSize:r,optimizedSize:a,ratio:h(r,a),sourceFormat:"svg",outputFormat:"svg",converted:!1,duration:s}}async function J(){if(m)return!0;if(v)return!1;try{return await E(),!0}catch{return!1}}async function N(){if(d)return!0;if(C)return!1;try{return await S(),!0}catch{return!1}}function P(e){const u={};if(e.convertToWebp)for(const[t,i]of Object.entries(e.convertToWebp))i&&t!=="svg"&&t!=="webp"&&t!=="avif"&&(u[t]="webp");if(e.convertToAvif)for(const[t,i]of Object.entries(e.convertToAvif))i&&t!=="svg"&&t!=="webp"&&t!=="avif"&&(u[t]="avif");return e.convertMapping&&Object.assign(u,e.convertMapping),u}function H(e,u){return u[e]??e}function U(e,u){return e in u}function K(e){const u=[];for(const[t,i]of Object.entries(e))t===i&&u.push(`\u6E90\u683C\u5F0F\u548C\u76EE\u6807\u683C\u5F0F\u4E0D\u80FD\u76F8\u540C: ${t}`),i==="svg"&&u.push(`\u4E0D\u652F\u6301\u5C06 ${t} \u8F6C\u6362\u4E3A svg \u683C\u5F0F`),t==="svg"&&u.push(`\u4E0D\u652F\u6301\u5C06 svg \u8F6C\u6362\u4E3A ${i} \u683C\u5F0F\uFF0CSVG \u5E94\u4F7F\u7528 svgo \u5355\u72EC\u4F18\u5316`);return u}function Q(e,u,t,i){const r=e.reduce((s,n)=>s+n.originalSize,0),o=e.reduce((s,n)=>s+n.optimizedSize,0),p=h(r,o),l=e.filter(s=>s.converted).length,a={};for(const s of e){const n=s.outputFormat;a[n]||(a[n]={count:0,originalSize:0,optimizedSize:0,ratio:0}),a[n].count++,a[n].originalSize+=s.originalSize,a[n].optimizedSize+=s.optimizedSize}for(const s of Object.values(a))s.ratio=h(s.originalSize,s.optimizedSize);return{totalFiles:e.length,skippedFiles:u,failedFiles:t,totalOriginalSize:r,totalOptimizedSize:o,totalRatio:p,byFormat:a,convertedFiles:l,executionTime:i,stats:e}}async function X(e,u,t){const i=O(e,u);if(!i)return;const r={timestamp:new Date().toISOString(),summary:{totalFiles:t.totalFiles,skippedFiles:t.skippedFiles,failedFiles:t.failedFiles,totalOriginalSize:t.totalOriginalSize,totalOptimizedSize:t.totalOptimizedSize,totalRatio:t.totalRatio,convertedFiles:t.convertedFiles,executionTime:t.executionTime},byFormat:t.byFormat,files:t.stats.map(o=>({file:o.file,relativePath:o.relativePath,originalSize:o.originalSize,optimizedSize:o.optimizedSize,ratio:o.ratio,sourceFormat:o.sourceFormat,outputFormat:o.outputFormat,converted:o.converted,duration:o.duration}))};await k(i,r)}class Y extends B{allStats=[];summary=null;skippedCount=0;failedCount=0;sharpReady=!1;svgoReady=!1;dependencyChecked=!1;convertMapping={};getDefaultOptions(){return{quality:{jpeg:80,png:6,webp:75,avif:50,gif:!0,tiff:"deflate"},convertToWebp:{},convertToAvif:{},convertMapping:{},svgo:{plugins:[],multipass:!1},includeExtensions:[".jpg",".jpeg",".png",".webp",".avif",".gif",".tiff",".tif",".svg"],excludePaths:[],threshold:0,keepOriginal:!0,reportOutput:"image-optimize-report.json",parallelLimit:5,maxPixels:0}}validateOptions(){this.validator.field("threshold").number().minValue(0).field("keepOriginal").boolean().field("includeExtensions").array().field("excludePaths").array().field("reportOutput").custom(i=>i===!1||typeof i=="string","reportOutput \u5FC5\u987B\u4E3A false \u6216\u5B57\u7B26\u4E32\u8DEF\u5F84").field("parallelLimit").number().minValue(1).maxValue(50).field("maxPixels").number().minValue(0).validate();const u=P(this.options),t=K(u);if(t.length>0)throw new Error(`\u56FE\u7247\u4F18\u5316\u914D\u7F6E\u9519\u8BEF: ${t.join("; ")}`)}getPluginName(){return"image-optimizer"}getEnforce(){return"post"}addPluginHooks(u){u.writeBundle=async()=>{await this.safeExecute(()=>this.optimizeAllImages(),"\u4F18\u5316\u56FE\u7247\u8D44\u6E90")}}onConfigResolved(u){super.onConfigResolved(u),this.convertMapping=P(this.options)}async checkDependencies(){this.sharpReady=await J(),this.svgoReady=await N(),this.sharpReady||this.logger.warn("sharp \u6A21\u5757\u4E0D\u53EF\u7528\uFF0C\u4F4D\u56FE\u683C\u5F0F\uFF08JPEG/PNG/WebP/AVIF/GIF/TIFF\uFF09\u4F18\u5316\u5C06\u8DF3\u8FC7\u3002\u8BF7\u5B89\u88C5: npm install sharp"),this.svgoReady||this.logger.warn("svgo \u6A21\u5757\u4E0D\u53EF\u7528\uFF0CSVG \u4F18\u5316\u5C06\u8DF3\u8FC7\u3002\u8BF7\u5B89\u88C5: npm install svgo"),!this.sharpReady&&!this.svgoReady&&this.logger.warn("sharp \u548C svgo \u5747\u4E0D\u53EF\u7528\uFF0C\u56FE\u7247\u4F18\u5316\u63D2\u4EF6\u5C06\u4E0D\u6267\u884C\u4EFB\u4F55\u64CD\u4F5C")}async optimizeAllImages(){if(!this.viteConfig)return;if(this.dependencyChecked||(await this.checkDependencies(),this.dependencyChecked=!0),!this.sharpReady&&!this.svgoReady){this.logger.warn("\u4F9D\u8D56\u4E0D\u53EF\u7528\uFF0C\u8DF3\u8FC7\u56FE\u7247\u4F18\u5316");return}const u=this.viteConfig.build.outDir,t=Date.now();this.logger.info(`\u5F00\u59CB\u626B\u63CF\u56FE\u7247\u6587\u4EF6: ${u}`);const i=await G(u,this.options);if(i.length===0){this.logger.info("\u672A\u627E\u5230\u9700\u8981\u4F18\u5316\u7684\u56FE\u7247\u6587\u4EF6");return}const r=i.filter(l=>l.format==="svg"),o=i.filter(l=>l.format!=="svg");if(this.logger.info(`\u53D1\u73B0 ${i.length} \u4E2A\u5F85\u4F18\u5316\u56FE\u7247 (\u4F4D\u56FE: ${o.length}, SVG: ${r.length})`),this.allStats=[],this.skippedCount=0,this.failedCount=0,o.length>0&&this.sharpReady){const l=await D(o,async a=>this.processBitmap({...a,format:a.format}),this.options.parallelLimit);for(const a of l)a.skipped?this.skippedCount++:a.error?(this.failedCount++,this.logger.warn(`\u4F18\u5316\u5931\u8D25: ${a.error}`)):a.stat&&this.allStats.push(a.stat)}else o.length>0&&!this.sharpReady&&(this.skippedCount+=o.length,this.logger.info(`\u8DF3\u8FC7 ${o.length} \u4E2A\u4F4D\u56FE\u6587\u4EF6\uFF08sharp \u4E0D\u53EF\u7528\uFF09`));if(r.length>0&&this.svgoReady){const l=await D(r,async a=>this.processSvg(a),this.options.parallelLimit);for(const a of l)a.skipped?this.skippedCount++:a.error?(this.failedCount++,this.logger.warn(`SVG \u4F18\u5316\u5931\u8D25: ${a.error}`)):a.stat&&this.allStats.push(a.stat)}else r.length>0&&!this.svgoReady&&(this.skippedCount+=r.length,this.logger.info(`\u8DF3\u8FC7 ${r.length} \u4E2A SVG \u6587\u4EF6\uFF08svgo \u4E0D\u53EF\u7528\uFF09`));const p=Date.now()-t;this.summary=Q(this.allStats,this.skippedCount,this.failedCount,p),this.options.reportOutput&&(await X(u,this.options.reportOutput,this.summary),this.logger.info(`\u4F18\u5316\u62A5\u544A\u5DF2\u751F\u6210: ${this.options.reportOutput}`)),this.logSummary()}async processBitmap(u){try{const t=H(u.format,this.convertMapping);let i;return U(u.format,this.convertMapping)?i=await L(u.filePath,u.format,t,this.options.quality,this.options.maxPixels,this.options.keepOriginal):i=await q(u.filePath,u.format,this.options.quality,this.options.maxPixels),i.relativePath=u.relativePath,{stat:i}}catch(t){const i=t instanceof Error?t.message:String(t);return{error:`${u.relativePath}: ${i}`}}}async processSvg(u){try{const t=await W(u.filePath,this.options.svgo);return t.relativePath=u.relativePath,{stat:t}}catch(t){const i=t instanceof Error?t.message:String(t);return{error:`${u.relativePath}: ${i}`}}}logSummary(){if(!this.summary)return;const{totalFiles:u,skippedFiles:t,failedFiles:i,totalOriginalSize:r,totalOptimizedSize:o,totalRatio:p,convertedFiles:l,executionTime:a}=this.summary;this.logger.success(`\u56FE\u7247\u4F18\u5316\u5B8C\u6210: ${u} \u4E2A\u6587\u4EF6\u5DF2\u4F18\u5316`+(t>0?`\uFF0C${t} \u4E2A\u8DF3\u8FC7`:"")+(i>0?`\uFF0C${i} \u4E2A\u5931\u8D25`:""),`\u539F\u59CB\u4F53\u79EF: ${g(r)} \u2192 \u4F18\u5316\u540E: ${g(o)}\uFF0C\u538B\u7F29\u7387: ${p}%`+(l>0?`\uFF0C\u683C\u5F0F\u8F6C\u6362: ${l} \u4E2A`:"")+`\uFF0C\u8017\u65F6: ${a}ms`);for(const[n,F]of Object.entries(this.summary.byFormat))this.logger.info(` ${n.toUpperCase().padEnd(5)} ${F.count} \u4E2A\u6587\u4EF6\uFF0C${g(F.originalSize)} \u2192 ${g(F.optimizedSize)}\uFF0C\u538B\u7F29\u7387: ${F.ratio}%`);const s=[...this.allStats].sort((n,F)=>F.ratio-n.ratio).slice(0,5);if(s.length>0){this.logger.info("\u538B\u7F29\u7387 Top 5:");for(const n of s){const F=n.converted?` (${n.sourceFormat}\u2192${n.outputFormat})`:"";this.logger.info(` ${n.ratio}% ${g(n.originalSize)} \u2192 ${g(n.optimizedSize)}${F} ${n.relativePath}`)}}}getStats(){return[...this.allStats]}getSummary(){return this.summary}}const Z=A(Y);export{Z as imageOptimizer};
@@ -1 +1 @@
1
- "use strict";const plugins_assetManifest_index=require("./assetManifest/index.cjs"),plugins_autoImport_index=require("./autoImport/index.cjs"),plugins_buildProgress_index=require("./buildProgress/index.cjs"),plugins_bundleAnalyzer_index=require("./bundleAnalyzer/index.cjs"),plugins_compressAssets_index=require("./compressAssets/index.cjs"),plugins_copyFile_index=require("./copyFile/index.cjs"),plugins_envGuard_index=require("./envGuard/index.cjs"),plugins_faviconManager_index=require("./faviconManager/index.cjs"),plugins_generateRouter_index=require("./generateRouter/index.cjs"),plugins_generateVersion_index=require("./generateVersion/index.cjs"),plugins_htmlInject_index=require("./htmlInject/index.cjs"),plugins_loadingManager_index=require("./loadingManager/index.cjs"),plugins_versionUpdateChecker_index=require("./versionUpdateChecker/index.cjs");require("node:path"),require("node:fs"),require("../factory/index.cjs"),require("../logger/index.cjs"),require("../shared/vite-plugin.Bcg6RW2N.cjs"),require("../common/fs/index.cjs"),require("fs"),require("path"),require("../common/path/index.cjs"),require("../common/html/index.cjs"),require("../shared/vite-plugin.CcvHfrL8.cjs"),require("../common/validation/index.cjs"),require("../common/ui/index.cjs"),require("node:zlib"),require("node:util"),require("../common/format/index.cjs"),require("node:stream/promises"),require("crypto"),require("../common/script/index.cjs"),exports.assetManifest=plugins_assetManifest_index.assetManifest,exports.autoImport=plugins_autoImport_index.autoImport,exports.buildProgress=plugins_buildProgress_index.buildProgress,exports.bundleAnalyzer=plugins_bundleAnalyzer_index.bundleAnalyzer,exports.compressAssets=plugins_compressAssets_index.compressAssets,exports.copyFile=plugins_copyFile_index.copyFile,exports.envGuard=plugins_envGuard_index.envGuard,exports.faviconManager=plugins_faviconManager_index.faviconManager,exports.generateRouter=plugins_generateRouter_index.generateRouter,exports.generateVersion=plugins_generateVersion_index.generateVersion,exports.htmlInject=plugins_htmlInject_index.htmlInject,exports.loadingManager=plugins_loadingManager_index.loadingManager,exports.versionUpdateChecker=plugins_versionUpdateChecker_index.versionUpdateChecker;
1
+ "use strict";const plugins_assetManifest_index=require("./assetManifest/index.cjs"),plugins_autoImport_index=require("./autoImport/index.cjs"),plugins_buildProgress_index=require("./buildProgress/index.cjs"),plugins_bundleAnalyzer_index=require("./bundleAnalyzer/index.cjs"),plugins_compressAssets_index=require("./compressAssets/index.cjs"),plugins_copyFile_index=require("./copyFile/index.cjs"),plugins_envGuard_index=require("./envGuard/index.cjs"),plugins_faviconManager_index=require("./faviconManager/index.cjs"),plugins_generateRouter_index=require("./generateRouter/index.cjs"),plugins_generateVersion_index=require("./generateVersion/index.cjs"),plugins_htmlInject_index=require("./htmlInject/index.cjs"),plugins_imageOptimizer_index=require("./imageOptimizer/index.cjs"),plugins_loadingManager_index=require("./loadingManager/index.cjs"),plugins_versionUpdateChecker_index=require("./versionUpdateChecker/index.cjs");require("node:path"),require("node:fs"),require("../factory/index.cjs"),require("../logger/index.cjs"),require("../shared/vite-plugin.Bcg6RW2N.cjs"),require("../common/fs/index.cjs"),require("fs"),require("path"),require("../common/concurrency/index.cjs"),require("../common/path/index.cjs"),require("../common/html/index.cjs"),require("../shared/vite-plugin.CcvHfrL8.cjs"),require("../common/validation/index.cjs"),require("../common/ui/index.cjs"),require("node:zlib"),require("node:util"),require("../common/format/index.cjs"),require("node:stream/promises"),require("crypto"),require("../common/script/index.cjs"),exports.assetManifest=plugins_assetManifest_index.assetManifest,exports.autoImport=plugins_autoImport_index.autoImport,exports.buildProgress=plugins_buildProgress_index.buildProgress,exports.bundleAnalyzer=plugins_bundleAnalyzer_index.bundleAnalyzer,exports.compressAssets=plugins_compressAssets_index.compressAssets,exports.copyFile=plugins_copyFile_index.copyFile,exports.envGuard=plugins_envGuard_index.envGuard,exports.faviconManager=plugins_faviconManager_index.faviconManager,exports.generateRouter=plugins_generateRouter_index.generateRouter,exports.generateVersion=plugins_generateVersion_index.generateVersion,exports.htmlInject=plugins_htmlInject_index.htmlInject,exports.imageOptimizer=plugins_imageOptimizer_index.imageOptimizer,exports.loadingManager=plugins_loadingManager_index.loadingManager,exports.versionUpdateChecker=plugins_versionUpdateChecker_index.versionUpdateChecker;
@@ -9,6 +9,7 @@ export { FaviconManagerOptions, Icon, faviconManager } from './faviconManager/in
9
9
  export { GenerateRouterOptions, NameStrategy, OutputFormat, RouteConfig, RouteMeta, UniAppPageConfig, UniAppPagesJson, UniAppTabBarConfig, generateRouter } from './generateRouter/index.cjs';
10
10
  export { GenerateVersionOptions, OutputType, VersionFormat, VersionInfo, generateVersion } from './generateVersion/index.cjs';
11
11
  export { HtmlInjectOptions, InjectRule, InjectionLogEntry, htmlInject } from './htmlInject/index.cjs';
12
+ export { ConvertMapping, FormatQualityOptions, ImageFormat, ImageOptimizeStats, ImageOptimizeSummary, ImageOptimizerOptions, SvgoOptions, SvgoPlugin, imageOptimizer } from './imageOptimizer/index.cjs';
12
13
  export { AutoBindMode, AutoHideOn, DebounceHide, DelayShow, LoadingCallbacks, LoadingManager, LoadingManagerOptions, LoadingPosition, LoadingStyle, MinDisplayTime, RequestFilter, SpinnerType, TransitionConfig, loadingManager } from './loadingManager/index.cjs';
13
14
  export { PromptStyle, VersionSource, VersionUpdateCheckerOptions, versionUpdateChecker } from './versionUpdateChecker/index.cjs';
14
15
  import '../factory/index.cjs';
@@ -9,6 +9,7 @@ export { FaviconManagerOptions, Icon, faviconManager } from './faviconManager/in
9
9
  export { GenerateRouterOptions, NameStrategy, OutputFormat, RouteConfig, RouteMeta, UniAppPageConfig, UniAppPagesJson, UniAppTabBarConfig, generateRouter } from './generateRouter/index.mjs';
10
10
  export { GenerateVersionOptions, OutputType, VersionFormat, VersionInfo, generateVersion } from './generateVersion/index.mjs';
11
11
  export { HtmlInjectOptions, InjectRule, InjectionLogEntry, htmlInject } from './htmlInject/index.mjs';
12
+ export { ConvertMapping, FormatQualityOptions, ImageFormat, ImageOptimizeStats, ImageOptimizeSummary, ImageOptimizerOptions, SvgoOptions, SvgoPlugin, imageOptimizer } from './imageOptimizer/index.mjs';
12
13
  export { AutoBindMode, AutoHideOn, DebounceHide, DelayShow, LoadingCallbacks, LoadingManager, LoadingManagerOptions, LoadingPosition, LoadingStyle, MinDisplayTime, RequestFilter, SpinnerType, TransitionConfig, loadingManager } from './loadingManager/index.mjs';
13
14
  export { PromptStyle, VersionSource, VersionUpdateCheckerOptions, versionUpdateChecker } from './versionUpdateChecker/index.mjs';
14
15
  import '../factory/index.mjs';
@@ -9,6 +9,7 @@ export { FaviconManagerOptions, Icon, faviconManager } from './faviconManager/in
9
9
  export { GenerateRouterOptions, NameStrategy, OutputFormat, RouteConfig, RouteMeta, UniAppPageConfig, UniAppPagesJson, UniAppTabBarConfig, generateRouter } from './generateRouter/index.js';
10
10
  export { GenerateVersionOptions, OutputType, VersionFormat, VersionInfo, generateVersion } from './generateVersion/index.js';
11
11
  export { HtmlInjectOptions, InjectRule, InjectionLogEntry, htmlInject } from './htmlInject/index.js';
12
+ export { ConvertMapping, FormatQualityOptions, ImageFormat, ImageOptimizeStats, ImageOptimizeSummary, ImageOptimizerOptions, SvgoOptions, SvgoPlugin, imageOptimizer } from './imageOptimizer/index.js';
12
13
  export { AutoBindMode, AutoHideOn, DebounceHide, DelayShow, LoadingCallbacks, LoadingManager, LoadingManagerOptions, LoadingPosition, LoadingStyle, MinDisplayTime, RequestFilter, SpinnerType, TransitionConfig, loadingManager } from './loadingManager/index.js';
13
14
  export { PromptStyle, VersionSource, VersionUpdateCheckerOptions, versionUpdateChecker } from './versionUpdateChecker/index.js';
14
15
  import '../factory/index.js';
@@ -1 +1 @@
1
- export{assetManifest}from"./assetManifest/index.mjs";export{autoImport}from"./autoImport/index.mjs";export{buildProgress}from"./buildProgress/index.mjs";export{bundleAnalyzer}from"./bundleAnalyzer/index.mjs";export{compressAssets}from"./compressAssets/index.mjs";export{copyFile}from"./copyFile/index.mjs";export{envGuard}from"./envGuard/index.mjs";export{faviconManager}from"./faviconManager/index.mjs";export{generateRouter}from"./generateRouter/index.mjs";export{generateVersion}from"./generateVersion/index.mjs";export{htmlInject}from"./htmlInject/index.mjs";export{loadingManager}from"./loadingManager/index.mjs";export{versionUpdateChecker}from"./versionUpdateChecker/index.mjs";import"node:path";import"node:fs";import"../factory/index.mjs";import"../logger/index.mjs";import"../shared/vite-plugin.DcExl6jd.mjs";import"../common/fs/index.mjs";import"fs";import"path";import"../common/path/index.mjs";import"../common/html/index.mjs";import"../shared/vite-plugin.CuXEJAWX.mjs";import"../common/validation/index.mjs";import"../common/ui/index.mjs";import"node:zlib";import"node:util";import"../common/format/index.mjs";import"node:stream/promises";import"crypto";import"../common/script/index.mjs";
1
+ export{assetManifest}from"./assetManifest/index.mjs";export{autoImport}from"./autoImport/index.mjs";export{buildProgress}from"./buildProgress/index.mjs";export{bundleAnalyzer}from"./bundleAnalyzer/index.mjs";export{compressAssets}from"./compressAssets/index.mjs";export{copyFile}from"./copyFile/index.mjs";export{envGuard}from"./envGuard/index.mjs";export{faviconManager}from"./faviconManager/index.mjs";export{generateRouter}from"./generateRouter/index.mjs";export{generateVersion}from"./generateVersion/index.mjs";export{htmlInject}from"./htmlInject/index.mjs";export{imageOptimizer}from"./imageOptimizer/index.mjs";export{loadingManager}from"./loadingManager/index.mjs";export{versionUpdateChecker}from"./versionUpdateChecker/index.mjs";import"node:path";import"node:fs";import"../factory/index.mjs";import"../logger/index.mjs";import"../shared/vite-plugin.DcExl6jd.mjs";import"../common/fs/index.mjs";import"fs";import"path";import"../common/concurrency/index.mjs";import"../common/path/index.mjs";import"../common/html/index.mjs";import"../shared/vite-plugin.CuXEJAWX.mjs";import"../common/validation/index.mjs";import"../common/ui/index.mjs";import"node:zlib";import"node:util";import"../common/format/index.mjs";import"node:stream/promises";import"crypto";import"../common/script/index.mjs";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meng-xi/vite-plugin",
3
3
  "type": "module",
4
- "version": "0.1.7",
4
+ "version": "0.1.8",
5
5
  "private": false,
6
6
  "description": "一个为 Vite 提供实用插件的工具包,同时也是一个完整的插件开发框架",
7
7
  "keywords": [
@@ -25,6 +25,11 @@
25
25
  "import": "./dist/common/index.mjs",
26
26
  "types": "./dist/common/index.d.ts"
27
27
  },
28
+ "./common/concurrency": {
29
+ "require": "./dist/common/concurrency/index.cjs",
30
+ "import": "./dist/common/concurrency/index.mjs",
31
+ "types": "./dist/common/concurrency/index.d.ts"
32
+ },
28
33
  "./common/format": {
29
34
  "require": "./dist/common/format/index.cjs",
30
35
  "import": "./dist/common/format/index.mjs",
@@ -130,6 +135,11 @@
130
135
  "import": "./dist/plugins/htmlInject/index.mjs",
131
136
  "types": "./dist/plugins/htmlInject/index.d.ts"
132
137
  },
138
+ "./plugins/image-optimizer": {
139
+ "require": "./dist/plugins/imageOptimizer/index.cjs",
140
+ "import": "./dist/plugins/imageOptimizer/index.mjs",
141
+ "types": "./dist/plugins/imageOptimizer/index.d.ts"
142
+ },
133
143
  "./plugins/loading-manager": {
134
144
  "require": "./dist/plugins/loadingManager/index.cjs",
135
145
  "import": "./dist/plugins/loadingManager/index.mjs",
@@ -154,6 +164,10 @@
154
164
  "peerDependencies": {
155
165
  "vite": ">=5.0.0 <8.0.0"
156
166
  },
167
+ "optionalDependencies": {
168
+ "sharp": "^0.33.0",
169
+ "svgo": "^3.3.0"
170
+ },
157
171
  "devDependencies": {
158
172
  "@types/node": "^22.0.0",
159
173
  "tsx": "^4.22.3",