@meng-xi/vite-plugin 0.1.0 → 0.1.2
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.
- package/README-en.md +264 -533
- package/README.md +253 -522
- package/dist/common/format/index.cjs +1 -0
- package/dist/common/format/index.d.cts +156 -0
- package/dist/common/format/index.d.mts +156 -0
- package/dist/common/format/index.d.ts +156 -0
- package/dist/common/format/index.mjs +1 -0
- package/dist/common/fs/index.cjs +1 -0
- package/dist/common/fs/index.d.cts +150 -0
- package/dist/common/fs/index.d.mts +150 -0
- package/dist/common/fs/index.d.ts +150 -0
- package/dist/common/fs/index.mjs +1 -0
- package/dist/common/html/index.cjs +2 -0
- package/dist/common/html/index.d.cts +109 -0
- package/dist/common/html/index.d.mts +109 -0
- package/dist/common/html/index.d.ts +109 -0
- package/dist/common/html/index.mjs +2 -0
- package/dist/common/index.cjs +1 -1
- package/dist/common/index.d.cts +7 -417
- package/dist/common/index.d.mts +7 -417
- package/dist/common/index.d.ts +7 -417
- package/dist/common/index.mjs +1 -1
- package/dist/common/object/index.cjs +1 -0
- package/dist/common/object/index.d.cts +30 -0
- package/dist/common/object/index.d.mts +30 -0
- package/dist/common/object/index.d.ts +30 -0
- package/dist/common/object/index.mjs +1 -0
- package/dist/common/script/index.cjs +1 -0
- package/dist/common/script/index.d.cts +54 -0
- package/dist/common/script/index.d.mts +54 -0
- package/dist/common/script/index.d.ts +54 -0
- package/dist/common/script/index.mjs +1 -0
- package/dist/common/validation/index.cjs +1 -0
- package/dist/common/validation/index.d.cts +93 -0
- package/dist/common/validation/index.d.mts +93 -0
- package/dist/common/validation/index.d.ts +93 -0
- package/dist/common/validation/index.mjs +1 -0
- package/dist/factory/index.cjs +1 -1
- package/dist/factory/index.d.cts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.d.ts +1 -1
- package/dist/factory/index.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +16 -3
- package/dist/index.d.mts +16 -3
- package/dist/index.d.ts +16 -3
- package/dist/index.mjs +1 -1
- package/dist/plugins/buildProgress/index.cjs +2 -0
- package/dist/plugins/buildProgress/index.d.cts +187 -0
- package/dist/plugins/buildProgress/index.d.mts +187 -0
- package/dist/plugins/buildProgress/index.d.ts +187 -0
- package/dist/plugins/buildProgress/index.mjs +2 -0
- package/dist/plugins/compressAssets/index.cjs +1 -0
- package/dist/plugins/compressAssets/index.d.cts +132 -0
- package/dist/plugins/compressAssets/index.d.mts +132 -0
- package/dist/plugins/compressAssets/index.d.ts +132 -0
- package/dist/plugins/compressAssets/index.mjs +1 -0
- package/dist/plugins/copyFile/index.cjs +1 -0
- package/dist/plugins/copyFile/index.d.cts +78 -0
- package/dist/plugins/copyFile/index.d.mts +78 -0
- package/dist/plugins/copyFile/index.d.ts +78 -0
- package/dist/plugins/copyFile/index.mjs +1 -0
- package/dist/plugins/faviconManager/index.cjs +1 -0
- package/dist/plugins/faviconManager/index.d.cts +143 -0
- package/dist/plugins/faviconManager/index.d.mts +143 -0
- package/dist/plugins/faviconManager/index.d.ts +143 -0
- package/dist/plugins/faviconManager/index.mjs +1 -0
- package/dist/plugins/generateRouter/index.cjs +35 -0
- package/dist/plugins/generateRouter/index.d.cts +215 -0
- package/dist/plugins/generateRouter/index.d.mts +215 -0
- package/dist/plugins/generateRouter/index.d.ts +215 -0
- package/dist/plugins/generateRouter/index.mjs +35 -0
- package/dist/plugins/generateVersion/index.cjs +1 -0
- package/dist/plugins/generateVersion/index.d.cts +184 -0
- package/dist/plugins/generateVersion/index.d.mts +184 -0
- package/dist/plugins/generateVersion/index.d.ts +184 -0
- package/dist/plugins/generateVersion/index.mjs +1 -0
- package/dist/plugins/htmlInject/index.cjs +7 -0
- package/dist/plugins/htmlInject/index.d.cts +278 -0
- package/dist/plugins/htmlInject/index.d.mts +278 -0
- package/dist/plugins/htmlInject/index.d.ts +278 -0
- package/dist/plugins/htmlInject/index.mjs +7 -0
- package/dist/plugins/index.cjs +1 -1
- package/dist/plugins/index.d.cts +11 -1714
- package/dist/plugins/index.d.mts +11 -1714
- package/dist/plugins/index.d.ts +11 -1714
- package/dist/plugins/index.mjs +1 -1
- package/dist/plugins/loadingManager/index.cjs +487 -0
- package/dist/plugins/loadingManager/index.d.cts +769 -0
- package/dist/plugins/loadingManager/index.d.mts +769 -0
- package/dist/plugins/loadingManager/index.d.ts +769 -0
- package/dist/plugins/loadingManager/index.mjs +487 -0
- package/dist/plugins/versionUpdateChecker/index.cjs +185 -0
- package/dist/plugins/versionUpdateChecker/index.d.cts +200 -0
- package/dist/plugins/versionUpdateChecker/index.d.mts +200 -0
- package/dist/plugins/versionUpdateChecker/index.d.ts +200 -0
- package/dist/plugins/versionUpdateChecker/index.mjs +185 -0
- package/dist/shared/vite-plugin.Bcg6RW2N.cjs +3 -0
- package/dist/shared/{vite-plugin.CiHfwMiN.d.ts → vite-plugin.DRRlWY8P.d.cts} +50 -0
- package/dist/shared/{vite-plugin.CiHfwMiN.d.cts → vite-plugin.DRRlWY8P.d.mts} +50 -0
- package/dist/shared/{vite-plugin.CiHfwMiN.d.mts → vite-plugin.DRRlWY8P.d.ts} +50 -0
- package/dist/shared/{vite-plugin.B88RyRN8.mjs → vite-plugin.DcExl6jd.mjs} +2 -2
- package/package.json +80 -3
- package/dist/shared/vite-plugin.CawoITTT.cjs +0 -1
- package/dist/shared/vite-plugin.D6Law9Ke.mjs +0 -706
- package/dist/shared/vite-plugin.D8L9KzuW.cjs +0 -706
- package/dist/shared/vite-plugin.DFjf9wFM.mjs +0 -2
- package/dist/shared/vite-plugin.DSb6XzBn.mjs +0 -1
- package/dist/shared/vite-plugin.IGZeStMa.cjs +0 -3
- package/dist/shared/vite-plugin.Tab4qcIM.cjs +0 -2
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
## 特性
|
|
17
17
|
|
|
18
|
-
- **开箱即用** - 提供
|
|
18
|
+
- **开箱即用** - 提供 9 个实用插件,覆盖构建进度展示、构建产物压缩、文件复制、路由生成、版本管理、版本更新检查、HTML 注入、图标注入、全局 Loading 状态管理等常见场景
|
|
19
19
|
- **插件开发框架** - 导出 BasePlugin、Logger、Validator 等核心组件,快速构建符合规范的自定义 Vite 插件
|
|
20
20
|
- **完整生命周期** - 支持初始化、配置解析、销毁等生命周期管理,自动组合钩子逻辑
|
|
21
21
|
- **类型安全** - 完整的 TypeScript 类型定义,配置验证器确保参数正确性
|
|
@@ -46,42 +46,21 @@ pnpm add @meng-xi/vite-plugin -D
|
|
|
46
46
|
|
|
47
47
|
```typescript
|
|
48
48
|
import { defineConfig } from 'vite'
|
|
49
|
-
import { buildProgress, copyFile, generateRouter, generateVersion, versionUpdateChecker, faviconManager, loadingManager } from '@meng-xi/vite-plugin'
|
|
49
|
+
import { buildProgress, compressAssets, copyFile, generateRouter, generateVersion, versionUpdateChecker, htmlInject, faviconManager, loadingManager } from '@meng-xi/vite-plugin'
|
|
50
50
|
|
|
51
51
|
export default defineConfig({
|
|
52
52
|
plugins: [
|
|
53
|
-
// 构建进度条
|
|
54
53
|
buildProgress(),
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
targetDir: 'dist/assets'
|
|
60
|
-
}),
|
|
61
|
-
|
|
62
|
-
// 生成路由配置(uni-app)
|
|
63
|
-
generateRouter({
|
|
64
|
-
pagesJsonPath: 'src/pages.json',
|
|
65
|
-
outputPath: 'src/router.config.ts'
|
|
66
|
-
}),
|
|
67
|
-
|
|
68
|
-
// 生成版本号
|
|
69
|
-
generateVersion({
|
|
70
|
-
format: 'datetime',
|
|
71
|
-
outputType: 'both'
|
|
72
|
-
}),
|
|
73
|
-
|
|
74
|
-
// 版本更新检查(配合 generateVersion 使用)
|
|
54
|
+
compressAssets({ algorithm: 'gzip' }),
|
|
55
|
+
copyFile({ sourceDir: 'src/assets', targetDir: 'dist/assets' }),
|
|
56
|
+
generateRouter({ pagesJsonPath: 'src/pages.json', outputPath: 'src/router.config.ts' }),
|
|
57
|
+
generateVersion({ format: 'datetime', outputType: 'both' }),
|
|
75
58
|
versionUpdateChecker(),
|
|
76
|
-
|
|
77
|
-
|
|
59
|
+
htmlInject({
|
|
60
|
+
rules: [{ id: 'meta-description', content: '<meta name="description" content="My App">', position: 'head-end' }]
|
|
61
|
+
}),
|
|
78
62
|
faviconManager('/assets'),
|
|
79
|
-
|
|
80
|
-
// 全局 Loading 状态管理
|
|
81
|
-
loadingManager({
|
|
82
|
-
defaultVisible: true,
|
|
83
|
-
autoHideOn: 'DOMContentLoaded'
|
|
84
|
-
})
|
|
63
|
+
loadingManager({ defaultVisible: true, autoHideOn: 'DOMContentLoaded' })
|
|
85
64
|
]
|
|
86
65
|
})
|
|
87
66
|
```
|
|
@@ -95,8 +74,6 @@ import type { PluginWithInstance } from '@meng-xi/vite-plugin/factory'
|
|
|
95
74
|
import type { GenerateRouterOptions } from '@meng-xi/vite-plugin'
|
|
96
75
|
|
|
97
76
|
const routerPlugin = generateRouter({ watch: true }) as PluginWithInstance<GenerateRouterOptions>
|
|
98
|
-
|
|
99
|
-
// 通过 pluginInstance 访问插件内部
|
|
100
77
|
console.log(routerPlugin.pluginInstance?.options)
|
|
101
78
|
```
|
|
102
79
|
|
|
@@ -105,13 +82,17 @@ console.log(routerPlugin.pluginInstance?.options)
|
|
|
105
82
|
| 插件 | 说明 |
|
|
106
83
|
| -------------------- | --------------------------------------------------------------- |
|
|
107
84
|
| buildProgress | 终端实时构建进度条,支持 bar / spinner / minimal |
|
|
85
|
+
| compressAssets | 构建产物压缩,支持 gzip / brotli / both,并发压缩和统计报告 |
|
|
108
86
|
| copyFile | 构建完成后复制文件或目录,支持增量复制 |
|
|
109
87
|
| generateRouter | 根据 pages.json 自动生成路由配置(uni-app) |
|
|
110
88
|
| generateVersion | 自动生成版本号,支持文件输出和全局变量注入 |
|
|
111
89
|
| versionUpdateChecker | 运行时版本更新检查,支持多种提示样式和自定义回调 |
|
|
90
|
+
| htmlInject | HTML 内容注入,支持多种位置、条件注入、模板变量替换和安全过滤 |
|
|
112
91
|
| faviconManager | 管理网站图标(favicon)链接注入到 HTML 文件,支持字符串简写配置 |
|
|
113
92
|
| loadingManager | 全局 Loading 状态管理,支持请求拦截和白屏 Loading |
|
|
114
93
|
|
|
94
|
+
---
|
|
95
|
+
|
|
115
96
|
### buildProgress
|
|
116
97
|
|
|
117
98
|
在终端实时显示 Vite 构建进度条,支持三种显示格式。
|
|
@@ -142,24 +123,10 @@ console.log(routerPlugin.pluginInstance?.options)
|
|
|
142
123
|
| moduleColor | `(text: string) => string` | 模块名称颜色 |
|
|
143
124
|
|
|
144
125
|
```typescript
|
|
145
|
-
// 默认进度条格式
|
|
146
126
|
buildProgress()
|
|
147
|
-
|
|
148
|
-
// 旋转动画格式
|
|
149
127
|
buildProgress({ format: 'spinner' })
|
|
150
|
-
|
|
151
|
-
// 精简格式
|
|
152
128
|
buildProgress({ format: 'minimal' })
|
|
153
|
-
|
|
154
|
-
// 自定义外观
|
|
155
|
-
buildProgress({
|
|
156
|
-
width: 40,
|
|
157
|
-
completeChar: '■',
|
|
158
|
-
incompleteChar: '□',
|
|
159
|
-
clearOnComplete: false
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
// 自定义颜色主题
|
|
129
|
+
buildProgress({ width: 40, completeChar: '■', incompleteChar: '□', clearOnComplete: false })
|
|
163
130
|
buildProgress({
|
|
164
131
|
theme: {
|
|
165
132
|
completeColor: t => `\x1b[32m${t}\x1b[39m`,
|
|
@@ -171,6 +138,35 @@ buildProgress({
|
|
|
171
138
|
})
|
|
172
139
|
```
|
|
173
140
|
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### compressAssets
|
|
144
|
+
|
|
145
|
+
在 Vite 构建完成后自动压缩输出目录中的文件,支持 gzip 和 brotli 两种压缩算法。
|
|
146
|
+
|
|
147
|
+
| 选项 | 类型 | 默认值 | 描述 |
|
|
148
|
+
| ------------------ | ---------------------------------- | ----------------------------------------------------------- | ------------------------------ |
|
|
149
|
+
| algorithm | `'gzip'` \| `'brotli'` \| `'both'` | `'gzip'` | 压缩算法 |
|
|
150
|
+
| threshold | `number` | `1024` | 最小压缩阈值(字节) |
|
|
151
|
+
| deleteOriginalFile | `boolean` | `false` | 压缩后是否删除原始文件 |
|
|
152
|
+
| includeExtensions | `string[]` | `['.js', '.css', '.html', '.svg', '.json', '.xml', '.txt']` | 需要压缩的文件扩展名 |
|
|
153
|
+
| excludeExtensions | `string[]` | `[]` | 需要排除的文件扩展名 |
|
|
154
|
+
| excludePaths | `string[]` | `[]` | 需要排除的路径前缀 |
|
|
155
|
+
| compressionLevel | `number` | `9` | gzip 压缩级别(1-9) |
|
|
156
|
+
| brotliQuality | `number` | `11` | brotli 压缩质量(1-11) |
|
|
157
|
+
| reportOutput | `string` \| `false` | `'compress-report.json'` | 压缩报告输出路径,false 不生成 |
|
|
158
|
+
| parallelLimit | `number` | `10` | 并发压缩最大文件数 |
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
compressAssets()
|
|
162
|
+
compressAssets({ algorithm: 'brotli' })
|
|
163
|
+
compressAssets({ algorithm: 'both', threshold: 2048, compressionLevel: 9, brotliQuality: 11 })
|
|
164
|
+
compressAssets({ deleteOriginalFile: true, reportOutput: 'compress-report.json' })
|
|
165
|
+
compressAssets({ includeExtensions: ['.js', '.css'], excludePaths: ['assets/images'], parallelLimit: 5 })
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
174
170
|
### copyFile
|
|
175
171
|
|
|
176
172
|
在 Vite 构建完成后复制文件或目录到指定位置,执行时机为 `enforce: 'post'`。
|
|
@@ -184,21 +180,12 @@ buildProgress({
|
|
|
184
180
|
| incremental | `boolean` | `true` | 是否启用增量复制 |
|
|
185
181
|
|
|
186
182
|
```typescript
|
|
187
|
-
|
|
188
|
-
copyFile({
|
|
189
|
-
sourceDir: 'src/assets',
|
|
190
|
-
targetDir: 'dist/assets'
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
// 禁用覆盖和增量复制
|
|
194
|
-
copyFile({
|
|
195
|
-
sourceDir: 'src/static',
|
|
196
|
-
targetDir: 'dist/static',
|
|
197
|
-
overwrite: false,
|
|
198
|
-
incremental: false
|
|
199
|
-
})
|
|
183
|
+
copyFile({ sourceDir: 'src/assets', targetDir: 'dist/assets' })
|
|
184
|
+
copyFile({ sourceDir: 'src/static', targetDir: 'dist/static', overwrite: false, incremental: false })
|
|
200
185
|
```
|
|
201
186
|
|
|
187
|
+
---
|
|
188
|
+
|
|
202
189
|
### generateRouter
|
|
203
190
|
|
|
204
191
|
根据 uni-app 项目的 `pages.json` 自动生成路由配置文件。
|
|
@@ -214,39 +201,21 @@ copyFile({
|
|
|
214
201
|
| watch | `boolean` | `true` | 是否监听变化自动重新生成 |
|
|
215
202
|
| metaMapping | `Record<string, string>` | - | 页面 style 字段到 meta 的映射 |
|
|
216
203
|
| exportTypes | `boolean` | `true` | 是否导出类型定义 |
|
|
217
|
-
| preserveRouteChanges | `boolean` | `true
|
|
204
|
+
| preserveRouteChanges | `boolean` | `true` | 是否保留用户对 routes 的修改 |
|
|
218
205
|
|
|
219
|
-
> 默认 `metaMapping` 为 `{ navigationBarTitleText: 'title', requireAuth: 'requireAuth' }
|
|
206
|
+
> 默认 `metaMapping` 为 `{ navigationBarTitleText: 'title', requireAuth: 'requireAuth' }`。当 `nameStrategy` 为 `'custom'` 时,必须提供 `customNameGenerator`。
|
|
220
207
|
|
|
221
208
|
```typescript
|
|
222
|
-
// 基本使用
|
|
223
209
|
generateRouter()
|
|
224
|
-
|
|
225
|
-
// 自定义 pages.json 路径
|
|
226
210
|
generateRouter({ pagesJsonPath: 'pages.json' })
|
|
227
|
-
|
|
228
|
-
// 输出 JavaScript 文件
|
|
229
211
|
generateRouter({ outputFormat: 'js', outputPath: 'src/router.config.js' })
|
|
230
|
-
|
|
231
|
-
// 使用帕斯卡命名策略
|
|
232
212
|
generateRouter({ nameStrategy: 'pascalCase' })
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
generateRouter({
|
|
236
|
-
nameStrategy: 'custom',
|
|
237
|
-
customNameGenerator: path => `route_${path.replace(/\//g, '_')}`
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
// 自定义元信息映射
|
|
241
|
-
generateRouter({
|
|
242
|
-
metaMapping: {
|
|
243
|
-
navigationBarTitleText: 'title',
|
|
244
|
-
requireAuth: 'requireAuth',
|
|
245
|
-
customField: 'custom'
|
|
246
|
-
}
|
|
247
|
-
})
|
|
213
|
+
generateRouter({ nameStrategy: 'custom', customNameGenerator: path => `route_${path.replace(/\//g, '_')}` })
|
|
214
|
+
generateRouter({ metaMapping: { navigationBarTitleText: 'title', requireAuth: 'requireAuth', customField: 'custom' } })
|
|
248
215
|
```
|
|
249
216
|
|
|
217
|
+
---
|
|
218
|
+
|
|
250
219
|
### generateVersion
|
|
251
220
|
|
|
252
221
|
在 Vite 构建过程中自动生成版本号。
|
|
@@ -285,34 +254,16 @@ generateRouter({
|
|
|
285
254
|
> 当 `format` 为 `'custom'` 时,必须提供 `customFormat`。当 `outputType` 为 `'define'` 或 `'both'` 时,同时注入 `{defineName}_INFO` 全局变量,包含版本号、构建时间、时间戳等完整信息。
|
|
286
255
|
|
|
287
256
|
```typescript
|
|
288
|
-
// 时间戳格式(默认)
|
|
289
257
|
generateVersion()
|
|
290
|
-
|
|
291
|
-
// 日期格式
|
|
292
258
|
generateVersion({ format: 'date' })
|
|
293
|
-
|
|
294
|
-
// 语义化版本格式
|
|
295
259
|
generateVersion({ format: 'semver', semverBase: '2.0.0', prefix: 'v' })
|
|
296
|
-
|
|
297
|
-
// 自定义格式
|
|
298
|
-
generateVersion({
|
|
299
|
-
format: 'custom',
|
|
300
|
-
customFormat: '{YYYY}.{MM}.{DD}-{hash}',
|
|
301
|
-
hashLength: 6
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
// 注入到代码中
|
|
260
|
+
generateVersion({ format: 'custom', customFormat: '{YYYY}.{MM}.{DD}-{hash}', hashLength: 6 })
|
|
305
261
|
generateVersion({ outputType: 'define', defineName: '__VERSION__' })
|
|
306
|
-
|
|
307
|
-
// 同时输出文件和注入代码
|
|
308
|
-
generateVersion({
|
|
309
|
-
outputType: 'both',
|
|
310
|
-
outputFile: 'build-info.json',
|
|
311
|
-
defineName: '__BUILD_VERSION__',
|
|
312
|
-
extra: { environment: 'production' }
|
|
313
|
-
})
|
|
262
|
+
generateVersion({ outputType: 'both', outputFile: 'build-info.json', defineName: '__BUILD_VERSION__', extra: { environment: 'production' } })
|
|
314
263
|
```
|
|
315
264
|
|
|
265
|
+
---
|
|
266
|
+
|
|
316
267
|
### versionUpdateChecker
|
|
317
268
|
|
|
318
269
|
在运行时定期检查版本号变更,发现新版本时提示用户刷新页面。通常与 `generateVersion` 插件配合使用。
|
|
@@ -345,130 +296,135 @@ generateVersion({
|
|
|
345
296
|
> `{{message}}`、`{{currentVersion}}`、`{{newVersion}}`、`{{refreshButton}}`、`{{dismissButton}}` 占位符。回调以函数体字符串形式提供,可用变量:`currentVersion`、`newVersion`。
|
|
346
297
|
|
|
347
298
|
```typescript
|
|
348
|
-
// 基本使用(配合 generateVersion)
|
|
349
299
|
generateVersion({ outputType: 'both' })
|
|
350
300
|
versionUpdateChecker()
|
|
351
|
-
|
|
352
|
-
// 仅从版本文件读取
|
|
353
301
|
versionUpdateChecker({ versionSource: 'file' })
|
|
354
|
-
|
|
355
|
-
// 自定义检查间隔和提示样式
|
|
356
|
-
versionUpdateChecker({
|
|
357
|
-
checkInterval: 60000,
|
|
358
|
-
promptStyle: 'banner'
|
|
359
|
-
})
|
|
360
|
-
|
|
361
|
-
// 底部轻提示
|
|
302
|
+
versionUpdateChecker({ checkInterval: 60000, promptStyle: 'banner' })
|
|
362
303
|
versionUpdateChecker({ promptStyle: 'toast' })
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
versionUpdateChecker({
|
|
366
|
-
promptMessage: '系统已更新,建议刷新体验新功能',
|
|
367
|
-
refreshButtonText: '更新',
|
|
368
|
-
dismissButtonText: '取消'
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
// 自定义回调
|
|
372
|
-
versionUpdateChecker({
|
|
373
|
-
onUpdateAvailable: 'console.log("新版本:", newVersion); return true;',
|
|
374
|
-
onRefresh: 'console.log("用户选择刷新");',
|
|
375
|
-
onDismiss: 'console.log("用户选择忽略");'
|
|
376
|
-
})
|
|
377
|
-
|
|
378
|
-
// 开发环境也启用(调试用)
|
|
304
|
+
versionUpdateChecker({ promptMessage: '系统已更新,建议刷新体验新功能', refreshButtonText: '更新', dismissButtonText: '取消' })
|
|
305
|
+
versionUpdateChecker({ onUpdateAvailable: 'console.log("新版本:", newVersion); return true;', onRefresh: 'console.log("用户选择刷新");', onDismiss: 'console.log("用户选择忽略");' })
|
|
379
306
|
versionUpdateChecker({ enableInDev: true })
|
|
380
307
|
```
|
|
381
308
|
|
|
382
|
-
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### htmlInject
|
|
312
|
+
|
|
313
|
+
在 Vite 构建过程中根据配置规则将 HTML 内容注入到目标文件中,支持多种注入位置、条件注入、模板变量替换和安全过滤。
|
|
314
|
+
|
|
315
|
+
**注入位置:**
|
|
316
|
+
|
|
317
|
+
| 位置 | 说明 |
|
|
318
|
+
| ------------------ | -------------------------- |
|
|
319
|
+
| `head-start` | 注入到 `<head>` 标签开始后 |
|
|
320
|
+
| `head-end` | 注入到 `</head>` 标签前 |
|
|
321
|
+
| `body-start` | 注入到 `<body>` 标签开始后 |
|
|
322
|
+
| `body-end` | 注入到 `</body>` 标签前 |
|
|
323
|
+
| `before-selector` | 注入到选择器匹配内容前 |
|
|
324
|
+
| `after-selector` | 注入到选择器匹配内容后 |
|
|
325
|
+
| `replace-selector` | 替换选择器匹配的内容 |
|
|
326
|
+
|
|
327
|
+
| 选项 | 类型 | 默认值 | 描述 |
|
|
328
|
+
| ------------ | ------------------------ | -------------- | -------------------------- |
|
|
329
|
+
| targetFile | `string` | `'index.html'` | 目标 HTML 文件路径或文件名 |
|
|
330
|
+
| rules | `InjectRule[]` | - | 注入规则数组(必填) |
|
|
331
|
+
| security | `SecurityConfig` | - | 安全过滤配置 |
|
|
332
|
+
| templateVars | `Record<string, string>` | - | 全局模板变量 |
|
|
333
|
+
| logInjection | `boolean` | `true` | 是否输出注入日志 |
|
|
334
|
+
|
|
335
|
+
**InjectRule**
|
|
336
|
+
|
|
337
|
+
| 属性 | 类型 | 默认值 | 描述 |
|
|
338
|
+
| -------------------- | ------------------------ | ---------- | --------------------------------- |
|
|
339
|
+
| id | `string` | - | 规则唯一标识符 |
|
|
340
|
+
| content | `string` | - | 要注入的 HTML 内容 |
|
|
341
|
+
| position | `InjectPosition` | - | 注入位置 |
|
|
342
|
+
| selector | `string` | - | 选择器(selector 相关位置时必填) |
|
|
343
|
+
| selectorMatch | `'string'` \| `'regex'` | `'string'` | 选择器匹配模式 |
|
|
344
|
+
| priority | `number` | `100` | 规则优先级,数值越小越先执行 |
|
|
345
|
+
| condition | `InjectCondition` | - | 注入条件 |
|
|
346
|
+
| templateVars | `Record<string, string>` | - | 规则级模板变量,覆盖全局变量 |
|
|
347
|
+
| allowScriptInjection | `boolean` | `false` | 是否允许注入脚本等危险内容 |
|
|
348
|
+
|
|
349
|
+
**SecurityConfig**
|
|
350
|
+
|
|
351
|
+
| 属性 | 类型 | 默认值 | 描述 |
|
|
352
|
+
| ------------------------ | ---------- | ------ | -------------------- |
|
|
353
|
+
| blockDangerousTags | `boolean` | `true` | 阻止危险标签 |
|
|
354
|
+
| blockDangerousAttributes | `boolean` | `true` | 阻止危险属性 |
|
|
355
|
+
| allowedTags | `string[]` | - | 允许通过的标签白名单 |
|
|
356
|
+
| blockedTags | `string[]` | - | 自定义阻止标签列表 |
|
|
357
|
+
| blockedAttributes | `string[]` | - | 自定义阻止属性列表 |
|
|
383
358
|
|
|
384
|
-
|
|
359
|
+
```typescript
|
|
360
|
+
htmlInject({
|
|
361
|
+
rules: [
|
|
362
|
+
{ id: 'meta-description', content: '<meta name="description" content="{{appName}}">', position: 'head-end', templateVars: { appName: 'My Application' } },
|
|
363
|
+
{ id: 'analytics', content: '<script src="/analytics.js"></script>', position: 'body-end', condition: { type: 'env', value: 'PRODUCTION' }, allowScriptInjection: true }
|
|
364
|
+
]
|
|
365
|
+
})
|
|
366
|
+
```
|
|
385
367
|
|
|
386
|
-
|
|
387
|
-
| ----------- | -------- | ------ | --------------------------- |
|
|
388
|
-
| base | `string` | `'/'` | 图标文件的基础路径 |
|
|
389
|
-
| url | `string` | - | 图标的完整 URL |
|
|
390
|
-
| link | `string` | - | 自定义完整的 link 标签 HTML |
|
|
391
|
-
| icons | `Icon[]` | - | 自定义图标数组 |
|
|
392
|
-
| copyOptions | `object` | - | 图标文件复制配置 |
|
|
368
|
+
---
|
|
393
369
|
|
|
394
|
-
|
|
370
|
+
### faviconManager
|
|
395
371
|
|
|
396
|
-
|
|
372
|
+
管理网站图标(favicon)链接注入到 HTML 文件,支持字符串简写配置和图标文件复制。
|
|
397
373
|
|
|
398
|
-
|
|
|
399
|
-
|
|
|
400
|
-
|
|
|
401
|
-
|
|
|
402
|
-
|
|
|
403
|
-
|
|
|
374
|
+
| 选项 | 类型 | 默认值 | 描述 |
|
|
375
|
+
| ----------- | -------- | ------ | ---------------------------------------- |
|
|
376
|
+
| base | `string` | `'/'` | 图标文件基础路径 |
|
|
377
|
+
| url | `string` | - | 图标完整 URL,优先于 base |
|
|
378
|
+
| link | `string` | - | 自定义完整 link 标签 HTML,优先级最高 |
|
|
379
|
+
| icons | `Icon[]` | - | 自定义图标数组,支持多种格式和尺寸 |
|
|
380
|
+
| copyOptions | `object` | - | 图标文件复制配置(sourceDir, targetDir) |
|
|
404
381
|
|
|
405
|
-
|
|
382
|
+
**Icon**
|
|
406
383
|
|
|
407
|
-
| 属性
|
|
408
|
-
|
|
|
409
|
-
|
|
|
410
|
-
|
|
|
411
|
-
|
|
|
412
|
-
|
|
|
384
|
+
| 属性 | 类型 | 描述 |
|
|
385
|
+
| ----- | -------- | -------------- |
|
|
386
|
+
| rel | `string` | 图标关系类型 |
|
|
387
|
+
| href | `string` | 图标 URL |
|
|
388
|
+
| sizes | `string` | 图标尺寸 |
|
|
389
|
+
| type | `string` | 图标 MIME 类型 |
|
|
413
390
|
|
|
414
391
|
```typescript
|
|
415
|
-
// 使用默认配置
|
|
416
392
|
faviconManager()
|
|
417
|
-
|
|
418
|
-
// 字符串简写(设置 base 路径)
|
|
419
393
|
faviconManager('/assets')
|
|
420
|
-
|
|
421
|
-
// 自定义图标数组
|
|
422
394
|
faviconManager({
|
|
423
395
|
base: '/assets',
|
|
424
396
|
icons: [
|
|
425
397
|
{ rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml' },
|
|
426
|
-
{ rel: 'icon', href: '/favicon-32x32.png', sizes: '32x32', type: 'image/png' }
|
|
427
|
-
{ rel: 'apple-touch-icon', href: '/apple-touch-icon.png', sizes: '180x180' }
|
|
398
|
+
{ rel: 'icon', href: '/favicon-32x32.png', sizes: '32x32', type: 'image/png' }
|
|
428
399
|
]
|
|
429
400
|
})
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
faviconManager({
|
|
433
|
-
link: '<link rel="icon" href="/favicon.svg" type="image/svg+xml" />'
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
// 带文件复制
|
|
437
|
-
faviconManager({
|
|
438
|
-
base: '/assets',
|
|
439
|
-
copyOptions: {
|
|
440
|
-
sourceDir: 'src/assets/icons',
|
|
441
|
-
targetDir: 'dist/assets/icons'
|
|
442
|
-
}
|
|
443
|
-
})
|
|
401
|
+
faviconManager({ link: '<link rel="icon" href="/favicon.svg" type="image/svg+xml" />' })
|
|
402
|
+
faviconManager({ base: '/assets', copyOptions: { sourceDir: 'src/assets/icons', targetDir: 'dist/assets/icons' } })
|
|
444
403
|
```
|
|
445
404
|
|
|
405
|
+
---
|
|
406
|
+
|
|
446
407
|
### loadingManager
|
|
447
408
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
|
456
|
-
|
|
|
457
|
-
|
|
|
458
|
-
|
|
|
459
|
-
|
|
|
460
|
-
|
|
|
461
|
-
|
|
|
462
|
-
|
|
|
463
|
-
|
|
|
464
|
-
|
|
|
465
|
-
|
|
|
466
|
-
|
|
|
467
|
-
| globalName | `string` | `'__LOADING_MANAGER__'` | 注入到浏览器的全局变量名 |
|
|
468
|
-
| customTemplate | `string` | - | 自定义 HTML 模板(需含 `data-loading-text`) |
|
|
469
|
-
| defaultVisible | `boolean` | `false` | 初始是否可见(白屏 Loading) |
|
|
470
|
-
| autoHideOn | `'DOMContentLoaded'` \| `'load'` \| `'manual'` | `'DOMContentLoaded'` | 自动隐藏时机(需 `defaultVisible: true`) |
|
|
471
|
-
| callbacks | `LoadingCallbacks` | - | 生命周期回调 |
|
|
409
|
+
全局 Loading 状态管理,支持请求拦截和白屏 Loading。
|
|
410
|
+
|
|
411
|
+
| 选项 | 类型 | 默认值 | 描述 |
|
|
412
|
+
| -------------- | ----------------------------------------------- | ----------------------- | ------------------------ |
|
|
413
|
+
| position | `'center'` \| `'top'` \| `'bottom'` | `'center'` | Loading 显示位置 |
|
|
414
|
+
| defaultText | `string` | `'加载中...'` | 默认显示文本 |
|
|
415
|
+
| spinnerType | `'spinner'` \| `'dots'` \| `'pulse'` \| `'bar'` | `'spinner'` | 旋转图标类型 |
|
|
416
|
+
| autoBind | `'fetch'` \| `'xhr'` \| `'all'` \| `'none'` | `'none'` | 自动绑定请求拦截模式 |
|
|
417
|
+
| globalName | `string` | `'__LOADING_MANAGER__'` | 注入到浏览器的全局变量名 |
|
|
418
|
+
| defaultVisible | `boolean` | `false` | Loading DOM 初始可见状态 |
|
|
419
|
+
| autoHideOn | `'DOMContentLoaded'` \| `'load'` \| `'manual'` | `'DOMContentLoaded'` | 自动隐藏时机 |
|
|
420
|
+
| style | `LoadingStyle` | - | 自定义样式配置 |
|
|
421
|
+
| transition | `TransitionConfig` | - | 过渡动画配置 |
|
|
422
|
+
| minDisplayTime | `MinDisplayTime` | - | 最小显示时间配置 |
|
|
423
|
+
| delayShow | `DelayShow` | - | 延迟显示配置 |
|
|
424
|
+
| debounceHide | `DebounceHide` | - | 防抖隐藏配置 |
|
|
425
|
+
| requestFilter | `RequestFilter` | - | 请求过滤配置 |
|
|
426
|
+
| customTemplate | `string` | - | 自定义 HTML 模板 |
|
|
427
|
+
| callbacks | `LoadingCallbacks` | - | 生命周期回调 |
|
|
472
428
|
|
|
473
429
|
**LoadingStyle**
|
|
474
430
|
|
|
@@ -479,371 +435,146 @@ faviconManager({
|
|
|
479
435
|
| spinnerSize | `string` | `'40px'` | 图标大小 |
|
|
480
436
|
| textColor | `string` | `'#333'` | 文本颜色 |
|
|
481
437
|
| textSize | `string` | `'14px'` | 文本大小 |
|
|
482
|
-
| customClass | `string` | - | 自定义 CSS 类名 |
|
|
483
|
-
| customStyle | `string` | - | 自定义内联样式 |
|
|
484
438
|
| zIndex | `number` | `9999` | z-index 值 |
|
|
485
439
|
| pointerEvents | `boolean` | `true` | 是否启用遮罩层指针事件 |
|
|
486
440
|
| backdropBlur | `boolean` | `false` | 是否启用背景模糊 |
|
|
487
441
|
| backdropBlurAmount | `number` | `4` | 背景模糊程度(px) |
|
|
442
|
+
| customClass | `string` | - | 自定义 CSS 类名 |
|
|
443
|
+
| customStyle | `string` | - | 自定义内联样式字符串 |
|
|
488
444
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
| 属性 | 类型 | 默认值 | 描述 |
|
|
492
|
-
| -------- | --------- | ------------ | ---------------- |
|
|
493
|
-
| enabled | `boolean` | `true` | 是否启用过渡 |
|
|
494
|
-
| duration | `number` | `200` | 过渡持续时间(ms) |
|
|
495
|
-
| easing | `string` | `'ease-out'` | 缓动函数 |
|
|
496
|
-
|
|
497
|
-
**MinDisplayTime**
|
|
498
|
-
|
|
499
|
-
| 属性 | 类型 | 默认值 | 描述 |
|
|
500
|
-
| -------- | --------- | ------ | ------------------------------------- |
|
|
501
|
-
| enabled | `boolean` | `true` | 是否启用 |
|
|
502
|
-
| duration | `number` | `300` | 最小显示时间(ms),确保 Loading 不闪烁 |
|
|
503
|
-
|
|
504
|
-
**DelayShow**
|
|
505
|
-
|
|
506
|
-
| 属性 | 类型 | 默认值 | 描述 |
|
|
507
|
-
| -------- | --------- | ------ | ---------------------------------------- |
|
|
508
|
-
| enabled | `boolean` | `true` | 是否启用 |
|
|
509
|
-
| duration | `number` | `200` | 延迟时间(ms),请求在此时间内完成则不显示 |
|
|
510
|
-
|
|
511
|
-
**DebounceHide**
|
|
512
|
-
|
|
513
|
-
| 属性 | 类型 | 默认值 | 描述 |
|
|
514
|
-
| -------- | --------- | ------- | ---------------- |
|
|
515
|
-
| enabled | `boolean` | `false` | 是否启用 |
|
|
516
|
-
| duration | `number` | `100` | 防抖等待时间(ms) |
|
|
517
|
-
|
|
518
|
-
**RequestFilter**
|
|
519
|
-
|
|
520
|
-
| 属性 | 类型 | 描述 |
|
|
521
|
-
| ------------------ | ---------- | ----------------------------------------- |
|
|
522
|
-
| excludeUrls | `RegExp[]` | 排除的 URL 正则数组 |
|
|
523
|
-
| includeUrls | `RegExp[]` | 包含的 URL 正则数组(优先级高于 exclude) |
|
|
524
|
-
| excludeMethods | `string[]` | 排除的 HTTP 方法数组 |
|
|
525
|
-
| excludeUrlPrefixes | `string[]` | 排除的 URL 前缀数组(前缀匹配,更高效) |
|
|
526
|
-
|
|
527
|
-
**LoadingCallbacks**
|
|
528
|
-
|
|
529
|
-
回调以**函数体字符串**形式提供(构建时注入到浏览器端,无法传递函数引用)。
|
|
530
|
-
|
|
531
|
-
| 属性 | 类型 | 描述 |
|
|
532
|
-
| ------------ | -------- | --------------------------------- |
|
|
533
|
-
| onBeforeShow | `string` | 显示前回调,`return false` 可阻止 |
|
|
534
|
-
| onShow | `string` | 显示后回调 |
|
|
535
|
-
| onBeforeHide | `string` | 隐藏前回调,`return false` 可阻止 |
|
|
536
|
-
| onHide | `string` | 隐藏后回调 |
|
|
537
|
-
| onDestroy | `string` | 销毁时回调 |
|
|
538
|
-
|
|
539
|
-
**LoadingManager API**
|
|
540
|
-
|
|
541
|
-
通过 `window.__LOADING_MANAGER__` 访问:
|
|
542
|
-
|
|
543
|
-
| 方法 | 说明 |
|
|
544
|
-
| -------------------------- | ------------------------------------------ |
|
|
545
|
-
| `show(text?)` | 显示 Loading,可传入文本 |
|
|
546
|
-
| `hide()` | 隐藏 Loading(受最小显示时间和防抖约束) |
|
|
547
|
-
| `forceHide()` | 强制隐藏,忽略最小显示时间和防抖 |
|
|
548
|
-
| `toggle(text?)` | 切换 Loading 显示/隐藏状态 |
|
|
549
|
-
| `updateText(text)` | 更新文本内容 |
|
|
550
|
-
| `isVisible()` | 获取当前是否显示 |
|
|
551
|
-
| `isPointerEventsEnabled()` | 获取当前是否启用了指针事件 |
|
|
552
|
-
| `enablePointerEvents()` | 启用遮罩层指针事件,拦截所有点击和滚动操作 |
|
|
553
|
-
| `disablePointerEvents()` | 禁用遮罩层指针事件,允许交互穿透 |
|
|
554
|
-
| `togglePointerEvents()` | 切换遮罩层指针事件状态 |
|
|
555
|
-
| `getPendingCount()` | 获取当前挂起的请求数量 |
|
|
556
|
-
| `destroy()` | 销毁实例,清理 DOM 并恢复原始拦截器 |
|
|
445
|
+
**运行时 API:**
|
|
557
446
|
|
|
558
447
|
```typescript
|
|
559
|
-
|
|
560
|
-
loadingManager({ defaultVisible: true, autoHideOn: 'DOMContentLoaded' })
|
|
561
|
-
|
|
562
|
-
// 白屏 Loading:所有资源加载完成后隐藏
|
|
563
|
-
loadingManager({ defaultVisible: true, autoHideOn: 'load' })
|
|
564
|
-
|
|
565
|
-
// Vue/React SPA:白屏即显示,框架渲染完成后手动隐藏
|
|
566
|
-
loadingManager({ defaultVisible: true, autoHideOn: 'manual' })
|
|
567
|
-
// 在应用入口处:window.__LOADING_MANAGER__.hide()
|
|
568
|
-
|
|
569
|
-
// 自动拦截所有请求
|
|
570
|
-
loadingManager({ autoBind: 'all' })
|
|
571
|
-
|
|
572
|
-
// 自定义样式 + 请求过滤
|
|
573
|
-
loadingManager({
|
|
574
|
-
style: { overlayColor: 'rgba(0,0,0,0.5)', spinnerColor: '#fff', backdropBlur: true },
|
|
575
|
-
autoBind: 'fetch',
|
|
576
|
-
requestFilter: { excludeUrls: [/\/api\/health/], excludeUrlPrefixes: ['http://localhost'] }
|
|
577
|
-
})
|
|
578
|
-
|
|
579
|
-
// 防抖隐藏(避免快速闪烁)
|
|
580
|
-
loadingManager({ debounceHide: { enabled: true, duration: 100 } })
|
|
581
|
-
|
|
582
|
-
// 生命周期回调
|
|
583
|
-
loadingManager({
|
|
584
|
-
callbacks: {
|
|
585
|
-
onBeforeShow: 'if (shouldSkip) return false;',
|
|
586
|
-
onShow: 'console.log("loading shown")',
|
|
587
|
-
onBeforeHide: 'if (shouldKeepVisible) return false;',
|
|
588
|
-
onHide: 'console.log("loading hidden")'
|
|
589
|
-
}
|
|
590
|
-
})
|
|
591
|
-
|
|
592
|
-
// 手动控制
|
|
593
|
-
loadingManager()
|
|
594
|
-
window.__LOADING_MANAGER__.show('正在保存...')
|
|
448
|
+
window.__LOADING_MANAGER__.show('加载中...')
|
|
595
449
|
window.__LOADING_MANAGER__.hide()
|
|
450
|
+
window.__LOADING_MANAGER__.forceHide()
|
|
596
451
|
window.__LOADING_MANAGER__.toggle()
|
|
452
|
+
window.__LOADING_MANAGER__.updateText('正在处理...')
|
|
453
|
+
window.__LOADING_MANAGER__.isVisible()
|
|
454
|
+
window.__LOADING_MANAGER__.getPendingCount()
|
|
455
|
+
window.__LOADING_MANAGER__.destroy()
|
|
456
|
+
window.__LOADING_MANAGER__.enablePointerEvents()
|
|
597
457
|
window.__LOADING_MANAGER__.disablePointerEvents()
|
|
458
|
+
window.__LOADING_MANAGER__.togglePointerEvents()
|
|
459
|
+
window.__LOADING_MANAGER__.isPointerEventsEnabled()
|
|
598
460
|
```
|
|
599
461
|
|
|
600
|
-
## 通用工具函数
|
|
601
|
-
|
|
602
|
-
通过 `@meng-xi/vite-plugin/common` 导出,可在自定义插件中复用:
|
|
603
|
-
|
|
604
462
|
```typescript
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
463
|
+
loadingManager()
|
|
464
|
+
loadingManager({ position: 'top', defaultText: '请稍候...' })
|
|
465
|
+
loadingManager({ spinnerType: 'dots' })
|
|
466
|
+
loadingManager({ autoBind: 'fetch', requestFilter: { excludeUrls: [/\/api\/health/], excludeUrlPrefixes: ['http://localhost'] } })
|
|
467
|
+
loadingManager({ style: { overlayColor: 'rgba(0,0,0,0.5)', spinnerColor: '#ff6b6b', backdropBlur: true, backdropBlurAmount: 6 } })
|
|
468
|
+
loadingManager({ transition: { enabled: true, duration: 300, easing: 'cubic-bezier(0.4,0,0.2,1)' } })
|
|
469
|
+
loadingManager({ debounceHide: { enabled: true, duration: 100 } })
|
|
470
|
+
loadingManager({ callbacks: { onShow: 'console.log("loading shown")', onBeforeShow: 'return true', onHide: 'console.log("loading hidden")' } })
|
|
471
|
+
loadingManager({ customTemplate: '<div class="my-loader"><span data-loading-text></span></div>' })
|
|
472
|
+
loadingManager({ defaultVisible: true, autoHideOn: 'DOMContentLoaded' })
|
|
473
|
+
loadingManager({ defaultVisible: true, autoHideOn: 'manual' })
|
|
609
474
|
```
|
|
610
475
|
|
|
611
|
-
|
|
612
|
-
| -------------------------- | --------------------------------------------------------------- |
|
|
613
|
-
| `deepMerge()` | 深度合并对象(undefined 不覆盖,数组直接覆盖) |
|
|
614
|
-
| `formatDate()` | 格式化日期,支持 `{YYYY}`, `{MM}`, `{DD}` 等占位符 |
|
|
615
|
-
| `parseTemplate()` | 解析模板字符串,替换占位符 |
|
|
616
|
-
| `toCamelCase()` | 转换为驼峰命名(camelCase) |
|
|
617
|
-
| `toPascalCase()` | 转换为帕斯卡命名(PascalCase) |
|
|
618
|
-
| `stripJsonComments()` | 移除 JSON 字符串中的注释 |
|
|
619
|
-
| `generateRandomHash()` | 生成随机哈希字符串(1-64 位) |
|
|
620
|
-
| `readFileContent()` | 异步读取文件内容 |
|
|
621
|
-
| `writeFileContent()` | 异步写入文件内容 |
|
|
622
|
-
| `fileExists()` | 异步检查文件是否存在 |
|
|
623
|
-
| `copySourceToTarget()` | 复制文件或目录,支持增量复制和并发控制 |
|
|
624
|
-
| `injectBeforeTag()` | 在 HTML 指定闭合标签前注入代码 |
|
|
625
|
-
| `injectHtmlByPriority()` | 按优先级向 HTML 中注入代码(`</head>` → `</body>` → `</html>`) |
|
|
626
|
-
| `makeCallback()` | 将回调函数体包装为安全的函数表达式(含 try-catch) |
|
|
627
|
-
| `containsScriptTag()` | 检测字符串是否包含 `<script>` 标签 |
|
|
628
|
-
| `validateIdentifierName()` | 验证字符串是否为合法的 JavaScript 标识符,防止原型污染 |
|
|
476
|
+
---
|
|
629
477
|
|
|
630
478
|
## 插件开发框架
|
|
631
479
|
|
|
632
|
-
### BasePlugin
|
|
633
|
-
|
|
634
|
-
`BasePlugin` 是所有插件的基类,提供了完整的生命周期管理和开发规范:
|
|
635
|
-
|
|
636
|
-
#### 生命周期
|
|
637
|
-
|
|
638
|
-
| 阶段 | 方法 | 说明 |
|
|
639
|
-
| -------- | ------------------ | -------------------------------------- |
|
|
640
|
-
| 初始化 | `constructor` | 合并配置、初始化日志和验证器 |
|
|
641
|
-
| 配置解析 | `onConfigResolved` | Vite 配置解析完成时调用 |
|
|
642
|
-
| 钩子注册 | `addPluginHooks` | 注册 Vite 插件钩子 |
|
|
643
|
-
| 销毁 | `destroy` | `closeBundle` 时自动调用,用于清理资源 |
|
|
644
|
-
|
|
645
|
-
#### 钩子自动组合
|
|
646
|
-
|
|
647
|
-
`toPlugin()` 方法会自动组合以下钩子:
|
|
648
|
-
|
|
649
|
-
- **configResolved** - 先执行基类的 `onConfigResolved`,再执行子类注册的钩子
|
|
650
|
-
- **closeBundle** - 先执行子类注册的钩子,再执行基类的 `destroy`
|
|
651
|
-
|
|
652
|
-
> 子类无需手动注册 `closeBundle` 钩子来清理资源,只需重写 `destroy()` 方法即可。
|
|
653
|
-
|
|
654
|
-
#### 必须实现的方法
|
|
655
|
-
|
|
656
|
-
| 方法 | 说明 |
|
|
657
|
-
| ------------------------ | ------------------ |
|
|
658
|
-
| `getPluginName()` | 返回插件名称 |
|
|
659
|
-
| `addPluginHooks(plugin)` | 添加 Vite 插件钩子 |
|
|
660
|
-
|
|
661
|
-
#### 可选重写的方法
|
|
662
|
-
|
|
663
|
-
| 方法 | 默认行为 | 说明 |
|
|
664
|
-
| -------------------------- | ----------- | ---------------------------------- |
|
|
665
|
-
| `getDefaultOptions()` | 返回 `{}` | 提供插件默认配置 |
|
|
666
|
-
| `validateOptions()` | 无验证 | 验证配置参数 |
|
|
667
|
-
| `getEnforce()` | `undefined` | 插件执行时机(`'pre'` / `'post'`) |
|
|
668
|
-
| `onConfigResolved(config)` | 存储配置 | 配置解析完成回调 |
|
|
669
|
-
| `destroy()` | 注销日志 | 插件销毁时的清理逻辑 |
|
|
670
|
-
|
|
671
|
-
#### 内置属性
|
|
672
|
-
|
|
673
|
-
| 属性 | 类型 | 说明 |
|
|
674
|
-
| ------------ | ------------------------ | ----------------- |
|
|
675
|
-
| `options` | `Required<T>` | 合并后的完整配置 |
|
|
676
|
-
| `logger` | `PluginLogger` | 插件日志记录器 |
|
|
677
|
-
| `validator` | `Validator<T>` | 配置验证器 |
|
|
678
|
-
| `viteConfig` | `ResolvedConfig \| null` | Vite 解析后的配置 |
|
|
679
|
-
|
|
680
|
-
#### 错误处理策略
|
|
681
|
-
|
|
682
|
-
通过 `errorStrategy` 配置项控制错误行为:
|
|
683
|
-
|
|
684
|
-
- `'throw'`(默认)- 记录错误并抛出异常,中断构建
|
|
685
|
-
- `'log'` - 记录错误但不抛出,继续执行
|
|
686
|
-
- `'ignore'` - 记录错误但不抛出,继续执行
|
|
687
|
-
|
|
688
|
-
使用 `safeExecute` / `safeExecuteSync` 包裹可能出错的操作:
|
|
689
|
-
|
|
690
|
-
```typescript
|
|
691
|
-
// 异步安全执行
|
|
692
|
-
const result = await this.safeExecute(async () => {
|
|
693
|
-
return await someAsyncOperation()
|
|
694
|
-
}, '执行异步操作')
|
|
695
|
-
|
|
696
|
-
// 同步安全执行
|
|
697
|
-
const value = this.safeExecuteSync(() => {
|
|
698
|
-
return someSyncOperation()
|
|
699
|
-
}, '执行同步操作')
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
### createPluginFactory
|
|
703
|
-
|
|
704
|
-
创建插件工厂函数,支持选项标准化器:
|
|
480
|
+
### BasePlugin
|
|
705
481
|
|
|
706
|
-
|
|
707
|
-
// 基本使用
|
|
708
|
-
const myPlugin = createPluginFactory(MyPlugin)
|
|
709
|
-
|
|
710
|
-
// 带标准化器(支持字符串简写配置)
|
|
711
|
-
const myPlugin = createPluginFactory(MyPlugin, opt => (typeof opt === 'string' ? { path: opt } : opt))
|
|
712
|
-
|
|
713
|
-
// 使用时支持简写
|
|
714
|
-
myPlugin('./custom-path')
|
|
715
|
-
```
|
|
716
|
-
|
|
717
|
-
### Validator
|
|
718
|
-
|
|
719
|
-
流畅的配置验证器,支持链式调用:
|
|
720
|
-
|
|
721
|
-
```typescript
|
|
722
|
-
import { Validator } from '@meng-xi/vite-plugin/common'
|
|
723
|
-
|
|
724
|
-
const validator = new Validator(options)
|
|
725
|
-
validator
|
|
726
|
-
.field('sourceDir')
|
|
727
|
-
.required()
|
|
728
|
-
.string()
|
|
729
|
-
.field('targetDir')
|
|
730
|
-
.required()
|
|
731
|
-
.string()
|
|
732
|
-
.field('overwrite')
|
|
733
|
-
.boolean()
|
|
734
|
-
.default(true)
|
|
735
|
-
.field('port')
|
|
736
|
-
.number()
|
|
737
|
-
.field('list')
|
|
738
|
-
.array()
|
|
739
|
-
.field('config')
|
|
740
|
-
.object()
|
|
741
|
-
.field('name')
|
|
742
|
-
.custom(val => val.length > 0, 'name 不能为空')
|
|
743
|
-
.validate()
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
| 方法 | 说明 |
|
|
747
|
-
| ------------ | -------------------------------------------------- |
|
|
748
|
-
| `field()` | 指定要验证的字段 |
|
|
749
|
-
| `required()` | 标记字段为必填 |
|
|
750
|
-
| `string()` | 验证字段值是否为字符串类型 |
|
|
751
|
-
| `boolean()` | 验证字段值是否为布尔类型 |
|
|
752
|
-
| `number()` | 验证字段值是否为数字类型 |
|
|
753
|
-
| `array()` | 验证字段值是否为数组类型 |
|
|
754
|
-
| `object()` | 验证字段值是否为对象类型 |
|
|
755
|
-
| `default()` | 为字段设置默认值(仅当值为 undefined/null 时生效) |
|
|
756
|
-
| `custom()` | 使用自定义函数验证字段值 |
|
|
757
|
-
| `validate()` | 执行验证,失败时抛出错误 |
|
|
758
|
-
|
|
759
|
-
### Logger
|
|
760
|
-
|
|
761
|
-
全局单例日志管理器,为每个插件提供独立的日志控制:
|
|
762
|
-
|
|
763
|
-
```typescript
|
|
764
|
-
import { Logger } from '@meng-xi/vite-plugin/logger'
|
|
765
|
-
|
|
766
|
-
// 创建日志记录器(通常由 BasePlugin 自动调用)
|
|
767
|
-
Logger.create({ name: 'my-plugin', enabled: true })
|
|
768
|
-
|
|
769
|
-
// 注销插件日志配置(插件销毁时自动调用)
|
|
770
|
-
Logger.unregister('my-plugin')
|
|
771
|
-
|
|
772
|
-
// 销毁单例(测试场景使用)
|
|
773
|
-
Logger.destroy()
|
|
774
|
-
```
|
|
775
|
-
|
|
776
|
-
日志输出格式:
|
|
777
|
-
|
|
778
|
-
```
|
|
779
|
-
ℹ️ [@meng-xi/vite-plugin:my-plugin] Info message
|
|
780
|
-
✅ [@meng-xi/vite-plugin:my-plugin] Success message
|
|
781
|
-
⚠️ [@meng-xi/vite-plugin:my-plugin] Warning message
|
|
782
|
-
❌ [@meng-xi/vite-plugin:my-plugin] Error message
|
|
783
|
-
```
|
|
784
|
-
|
|
785
|
-
### 开发自定义插件示例
|
|
482
|
+
所有内置插件的基类,提供配置管理、日志记录、生命周期管理和安全执行等核心功能。
|
|
786
483
|
|
|
787
484
|
```typescript
|
|
788
|
-
import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin'
|
|
789
|
-
import type { BasePluginOptions, PluginWithInstance } from '@meng-xi/vite-plugin/factory'
|
|
485
|
+
import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin/factory'
|
|
790
486
|
import type { Plugin } from 'vite'
|
|
791
487
|
|
|
792
|
-
interface MyPluginOptions
|
|
793
|
-
|
|
488
|
+
interface MyPluginOptions {
|
|
489
|
+
enabled?: boolean
|
|
490
|
+
message?: string
|
|
794
491
|
}
|
|
795
492
|
|
|
796
493
|
class MyPlugin extends BasePlugin<MyPluginOptions> {
|
|
797
|
-
protected
|
|
798
|
-
return
|
|
494
|
+
protected getPluginName() {
|
|
495
|
+
return 'my-plugin'
|
|
799
496
|
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
this.validator.field('path').required().string().validate()
|
|
497
|
+
protected getDefaultOptions() {
|
|
498
|
+
return { enabled: true, message: 'Hello' }
|
|
803
499
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
return 'my-plugin'
|
|
500
|
+
protected validateOptions() {
|
|
501
|
+
this.validator.field('message').string().validate()
|
|
807
502
|
}
|
|
808
|
-
|
|
809
|
-
protected addPluginHooks(plugin: Plugin): void {
|
|
503
|
+
protected addPluginHooks(plugin: Plugin) {
|
|
810
504
|
plugin.buildStart = () => {
|
|
811
|
-
this.logger.info(
|
|
505
|
+
this.logger.info(this.options.message)
|
|
812
506
|
}
|
|
813
507
|
}
|
|
814
|
-
|
|
815
|
-
protected destroy(): void {
|
|
816
|
-
super.destroy()
|
|
817
|
-
// 自定义清理逻辑,如关闭连接、停止监听等
|
|
818
|
-
}
|
|
819
508
|
}
|
|
820
509
|
|
|
821
|
-
// 基本使用
|
|
822
510
|
export const myPlugin = createPluginFactory(MyPlugin)
|
|
823
|
-
|
|
824
|
-
// 带标准化器(支持字符串简写配置)
|
|
825
|
-
export const myPluginWithNormalizer = createPluginFactory(MyPlugin, opt => (typeof opt === 'string' ? { path: opt } : opt))
|
|
826
|
-
// 使用时支持简写:myPluginWithNormalizer('./custom-path')
|
|
827
511
|
```
|
|
828
512
|
|
|
513
|
+
### 核心组件
|
|
514
|
+
|
|
515
|
+
| 组件 | 导出路径 | 描述 |
|
|
516
|
+
| --------------------- | ------------------------------ | ---------------------- |
|
|
517
|
+
| `BasePlugin` | `@meng-xi/vite-plugin/factory` | 插件基类 |
|
|
518
|
+
| `createPluginFactory` | `@meng-xi/vite-plugin/factory` | 插件工厂函数创建器 |
|
|
519
|
+
| `PluginWithInstance` | `@meng-xi/vite-plugin/factory` | 带实例引用的插件类型 |
|
|
520
|
+
| `Logger` | `@meng-xi/vite-plugin/logger` | 日志管理器(单例模式) |
|
|
521
|
+
| `Validator` | `@meng-xi/vite-plugin/common` | 流畅 API 配置验证器 |
|
|
522
|
+
|
|
523
|
+
### 通用工具库
|
|
524
|
+
|
|
525
|
+
| 模块 | 导出路径 | 描述 |
|
|
526
|
+
| ---------- | ---------------------------------------- | -------------------------------------------------- |
|
|
527
|
+
| format | `@meng-xi/vite-plugin/common/format` | 日期格式化、命名转换、模板解析、HTML 转义 |
|
|
528
|
+
| fs | `@meng-xi/vite-plugin/common/fs` | 文件复制、目录遍历、并发控制 |
|
|
529
|
+
| html | `@meng-xi/vite-plugin/common/html` | HTML 注入(injectBeforeTag, injectHeadAndBody 等) |
|
|
530
|
+
| object | `@meng-xi/vite-plugin/common/object` | 深度合并对象 |
|
|
531
|
+
| script | `@meng-xi/vite-plugin/common/script` | 回调包装、script 标签检测、标识符验证 |
|
|
532
|
+
| validation | `@meng-xi/vite-plugin/common/validation` | 全局名校验、XSS 防护、枚举验证等 |
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
829
536
|
## 子路径导出
|
|
830
537
|
|
|
831
|
-
|
|
538
|
+
支持按需导入以减少打包体积:
|
|
832
539
|
|
|
833
540
|
```typescript
|
|
834
|
-
|
|
835
|
-
import { buildProgress, copyFile, loadingManager, BasePlugin, Logger } from '@meng-xi/vite-plugin'
|
|
541
|
+
import { buildProgress, copyFile, htmlInject, loadingManager, BasePlugin, Logger } from '@meng-xi/vite-plugin'
|
|
836
542
|
|
|
837
|
-
// 按模块导入
|
|
838
543
|
import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin/factory'
|
|
839
544
|
import { Logger } from '@meng-xi/vite-plugin/logger'
|
|
840
|
-
import { buildProgress, copyFile, generateRouter, loadingManager } from '@meng-xi/vite-plugin/plugins'
|
|
841
|
-
import { Validator, readFileContent, writeFileContent } from '@meng-xi/vite-plugin/common'
|
|
545
|
+
import { buildProgress, compressAssets, copyFile, generateRouter, generateVersion, versionUpdateChecker, htmlInject, faviconManager, loadingManager } from '@meng-xi/vite-plugin/plugins'
|
|
546
|
+
import { Validator, readFileContent, writeFileContent, injectHeadAndBody, deepMerge } from '@meng-xi/vite-plugin/common'
|
|
842
547
|
|
|
843
|
-
// 类型导入(从子路径按需导入类型定义)
|
|
844
548
|
import type { PluginWithInstance, PluginFactory, BasePluginOptions } from '@meng-xi/vite-plugin/factory'
|
|
845
|
-
import type { BuildProgressOptions, GenerateVersionOptions, VersionUpdateCheckerOptions, FaviconManagerOptions, LoadingManagerOptions
|
|
846
|
-
import type { DateFormatOptions } from '@meng-xi/vite-plugin/common'
|
|
549
|
+
import type { BuildProgressOptions, CompressAssetsOptions, GenerateVersionOptions, VersionUpdateCheckerOptions, HtmlInjectOptions, FaviconManagerOptions, LoadingManagerOptions } from '@meng-xi/vite-plugin/plugins'
|
|
550
|
+
import type { DateFormatOptions } from '@meng-xi/vite-plugin/common/format'
|
|
551
|
+
import type { HtmlInjectResult, DualInjectResult } from '@meng-xi/vite-plugin/common/html'
|
|
552
|
+
import type { CopyOptions, CopyResult } from '@meng-xi/vite-plugin/common/fs'
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
**所有可用子路径:**
|
|
556
|
+
|
|
557
|
+
```
|
|
558
|
+
@meng-xi/vite-plugin
|
|
559
|
+
@meng-xi/vite-plugin/factory
|
|
560
|
+
@meng-xi/vite-plugin/logger
|
|
561
|
+
@meng-xi/vite-plugin/plugins
|
|
562
|
+
@meng-xi/vite-plugin/plugins/build-progress
|
|
563
|
+
@meng-xi/vite-plugin/plugins/compress-assets
|
|
564
|
+
@meng-xi/vite-plugin/plugins/copy-file
|
|
565
|
+
@meng-xi/vite-plugin/plugins/favicon-manager
|
|
566
|
+
@meng-xi/vite-plugin/plugins/generate-router
|
|
567
|
+
@meng-xi/vite-plugin/plugins/generate-version
|
|
568
|
+
@meng-xi/vite-plugin/plugins/html-inject
|
|
569
|
+
@meng-xi/vite-plugin/plugins/loading-manager
|
|
570
|
+
@meng-xi/vite-plugin/plugins/version-update-checker
|
|
571
|
+
@meng-xi/vite-plugin/common
|
|
572
|
+
@meng-xi/vite-plugin/common/format
|
|
573
|
+
@meng-xi/vite-plugin/common/fs
|
|
574
|
+
@meng-xi/vite-plugin/common/html
|
|
575
|
+
@meng-xi/vite-plugin/common/object
|
|
576
|
+
@meng-xi/vite-plugin/common/script
|
|
577
|
+
@meng-xi/vite-plugin/common/validation
|
|
847
578
|
```
|
|
848
579
|
|
|
849
580
|
## 更新日志
|