@meng-xi/vite-plugin 0.1.2 → 0.1.3
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 +492 -190
- package/README.md +464 -163
- package/dist/common/compress/index.cjs +1 -0
- package/dist/common/compress/index.d.cts +23 -0
- package/dist/common/compress/index.d.mts +23 -0
- package/dist/common/compress/index.d.ts +23 -0
- package/dist/common/compress/index.mjs +1 -0
- package/dist/common/format/index.cjs +1 -1
- package/dist/common/format/index.d.cts +33 -1
- package/dist/common/format/index.d.mts +33 -1
- package/dist/common/format/index.d.ts +33 -1
- package/dist/common/format/index.mjs +1 -1
- package/dist/common/fs/index.cjs +1 -1
- package/dist/common/fs/index.d.cts +70 -2
- package/dist/common/fs/index.d.mts +70 -2
- package/dist/common/fs/index.d.ts +70 -2
- package/dist/common/fs/index.mjs +1 -1
- package/dist/common/index.cjs +1 -1
- package/dist/common/index.d.cts +4 -2
- package/dist/common/index.d.mts +4 -2
- package/dist/common/index.d.ts +4 -2
- package/dist/common/index.mjs +1 -1
- package/dist/common/path/index.cjs +1 -0
- package/dist/common/path/index.d.cts +22 -0
- package/dist/common/path/index.d.mts +22 -0
- package/dist/common/path/index.d.ts +22 -0
- package/dist/common/path/index.mjs +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.mts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.mjs +1 -1
- package/dist/plugins/bundleAnalyzer/index.cjs +235 -0
- package/dist/plugins/bundleAnalyzer/index.d.cts +215 -0
- package/dist/plugins/bundleAnalyzer/index.d.mts +215 -0
- package/dist/plugins/bundleAnalyzer/index.d.ts +215 -0
- package/dist/plugins/bundleAnalyzer/index.mjs +235 -0
- package/dist/plugins/compressAssets/index.cjs +1 -1
- package/dist/plugins/compressAssets/index.mjs +1 -1
- package/dist/plugins/generateRouter/index.cjs +4 -4
- package/dist/plugins/generateRouter/index.mjs +1 -1
- package/dist/plugins/generateVersion/index.cjs +1 -1
- package/dist/plugins/generateVersion/index.mjs +1 -1
- package/dist/plugins/htmlInject/index.cjs +7 -7
- package/dist/plugins/htmlInject/index.mjs +2 -2
- package/dist/plugins/index.cjs +1 -1
- package/dist/plugins/index.d.cts +1 -0
- package/dist/plugins/index.d.mts +1 -0
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.mjs +1 -1
- package/dist/plugins/loadingManager/index.cjs +1 -1
- package/dist/plugins/loadingManager/index.mjs +1 -1
- package/package.json +16 -1
package/README-en.md
CHANGED
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
|
|
16
16
|
## Features
|
|
17
17
|
|
|
18
|
-
- **Ready to Use** - Provides
|
|
19
|
-
and global Loading state management
|
|
20
|
-
- **Plugin Development Framework** - Exports core components like BasePlugin, Logger, Validator for building custom Vite plugins
|
|
18
|
+
- **Ready to Use** - Provides 10 practical plugins covering build progress display, build artifact analysis & compression, file copying, router generation, version management, version update checking, HTML injection,
|
|
19
|
+
icon injection, and global Loading state management
|
|
20
|
+
- **Plugin Development Framework** - Exports core components like BasePlugin, Logger, Validator for building custom Vite plugins that follow conventions
|
|
21
|
+
- **Common Utility Library** - Built-in Common module providing reusable utility functions for formatting, file system, compression, path handling, HTML injection, object operations, script generation, and parameter
|
|
22
|
+
validation
|
|
21
23
|
- **Complete Lifecycle** - Supports initialization, config resolution, destroy lifecycle management with automatic hook composition
|
|
22
24
|
- **Type Safe** - Complete TypeScript type definitions with configuration validators ensuring parameter correctness
|
|
23
25
|
- **Flexible Configuration** - All plugins support detailed configuration to meet diverse scenario requirements
|
|
@@ -47,11 +49,12 @@ pnpm add @meng-xi/vite-plugin -D
|
|
|
47
49
|
|
|
48
50
|
```typescript
|
|
49
51
|
import { defineConfig } from 'vite'
|
|
50
|
-
import { buildProgress, compressAssets, copyFile, generateRouter, generateVersion, versionUpdateChecker, htmlInject, faviconManager, loadingManager } from '@meng-xi/vite-plugin'
|
|
52
|
+
import { buildProgress, bundleAnalyzer, compressAssets, copyFile, generateRouter, generateVersion, versionUpdateChecker, htmlInject, faviconManager, loadingManager } from '@meng-xi/vite-plugin'
|
|
51
53
|
|
|
52
54
|
export default defineConfig({
|
|
53
55
|
plugins: [
|
|
54
56
|
buildProgress(),
|
|
57
|
+
bundleAnalyzer({ outputFormat: 'both', sizeThreshold: 200 }),
|
|
55
58
|
compressAssets({ algorithm: 'gzip' }),
|
|
56
59
|
copyFile({ sourceDir: 'src/assets', targetDir: 'dist/assets' }),
|
|
57
60
|
generateRouter({ pagesJsonPath: 'src/pages.json', outputPath: 'src/router.config.ts' }),
|
|
@@ -80,17 +83,18 @@ console.log(routerPlugin.pluginInstance?.options)
|
|
|
80
83
|
|
|
81
84
|
## Built-in Plugins
|
|
82
85
|
|
|
83
|
-
| Plugin | Description
|
|
84
|
-
| -------------------- |
|
|
85
|
-
| buildProgress | Real-time build progress bar in terminal, supports bar / spinner / minimal
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
86
|
+
| Plugin | Description |
|
|
87
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| buildProgress | Real-time build progress bar in terminal, supports bar / spinner / minimal |
|
|
89
|
+
| bundleAnalyzer | Build artifact size analysis with JSON/HTML reports, gzip calculation, threshold alerts, and build comparison |
|
|
90
|
+
| compressAssets | Compress build artifacts with gzip / brotli / both, concurrent compression and statistics report |
|
|
91
|
+
| copyFile | Copy files or directories after build, supports incremental copying |
|
|
92
|
+
| generateRouter | Auto-generate router config from pages.json (uni-app) |
|
|
93
|
+
| generateVersion | Auto-generate version numbers, supports file output and global variable injection |
|
|
94
|
+
| versionUpdateChecker | Runtime version update checking with multiple prompt styles and custom callbacks |
|
|
95
|
+
| htmlInject | HTML content injection with multiple positions, conditional injection, template variables, and security filtering |
|
|
96
|
+
| faviconManager | Manage website favicon links injection and file copying, supports string shorthand config |
|
|
97
|
+
| loadingManager | Global Loading state management with request interception, debounce, transition animations, and white-screen Loading |
|
|
94
98
|
|
|
95
99
|
---
|
|
96
100
|
|
|
@@ -141,6 +145,44 @@ buildProgress({
|
|
|
141
145
|
|
|
142
146
|
---
|
|
143
147
|
|
|
148
|
+
### bundleAnalyzer
|
|
149
|
+
|
|
150
|
+
Automatically analyze build artifacts in the output directory after Vite build, generating size statistics, module rankings, file type distribution, and other key metrics, with JSON report and HTML visualization support.
|
|
151
|
+
|
|
152
|
+
**Core Features:**
|
|
153
|
+
|
|
154
|
+
- Scan build output directory, analyze chunks, modules, and asset files
|
|
155
|
+
- Calculate original size and gzip compressed size
|
|
156
|
+
- File type distribution statistics by extension
|
|
157
|
+
- Top N largest modules ranking
|
|
158
|
+
- Size threshold alerts (2x threshold marked as critical)
|
|
159
|
+
- Compare with previous build results and generate diff report
|
|
160
|
+
- HTML reports support treemap / sunburst / list visualization charts
|
|
161
|
+
|
|
162
|
+
| Option | Type | Default | Description |
|
|
163
|
+
| ------------------ | --------------------------------------- | ------------------- | --------------------------------------------------------- |
|
|
164
|
+
| outputFormat | `'json'` \| `'html'` \| `'both'` | `'json'` | Report output format |
|
|
165
|
+
| outputFile | `string` | `'bundle-analysis'` | Report output filename (without extension) |
|
|
166
|
+
| openAnalyzer | `boolean` | `false` | Whether to auto-open browser after generating HTML report |
|
|
167
|
+
| sizeThreshold | `number` | `100` | Size alert threshold (KB) |
|
|
168
|
+
| topModules | `number` | `20` | Top N largest modules ranking count |
|
|
169
|
+
| gzipSize | `boolean` | `true` | Whether to calculate gzip size |
|
|
170
|
+
| excludeNodeModules | `boolean` | `false` | Whether to exclude node_modules modules |
|
|
171
|
+
| excludePatterns | `string[]` | `[]` | File path patterns to exclude |
|
|
172
|
+
| includeExtensions | `string[]` | `[]` | File extensions to include, empty means all |
|
|
173
|
+
| compareWith | `string` \| `null` | `null` | Path to previous analysis report for comparison |
|
|
174
|
+
| defaultChartType | `'treemap'` \| `'sunburst'` \| `'list'` | `'treemap'` | Default chart type in HTML report |
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
bundleAnalyzer()
|
|
178
|
+
bundleAnalyzer({ outputFormat: 'both', openAnalyzer: true })
|
|
179
|
+
bundleAnalyzer({ sizeThreshold: 200, topModules: 30, gzipSize: true })
|
|
180
|
+
bundleAnalyzer({ compareWith: 'dist/bundle-analysis.json', defaultChartType: 'sunburst' })
|
|
181
|
+
bundleAnalyzer({ excludeNodeModules: true, includeExtensions: ['.js', '.css'] })
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
144
186
|
### compressAssets
|
|
145
187
|
|
|
146
188
|
Automatically compress files in the output directory after Vite build, supporting both gzip and brotli compression algorithms.
|
|
@@ -268,7 +310,7 @@ generateVersion({ outputType: 'both', outputFile: 'build-info.json', defineName:
|
|
|
268
310
|
|
|
269
311
|
### versionUpdateChecker
|
|
270
312
|
|
|
271
|
-
Periodically check for version changes at runtime
|
|
313
|
+
Periodically check for version changes at runtime, prompting users to refresh when a new version is detected. Typically used with the `generateVersion` plugin.
|
|
272
314
|
|
|
273
315
|
**How it works:**
|
|
274
316
|
|
|
@@ -276,26 +318,26 @@ Periodically check for version changes at runtime and prompt users to refresh wh
|
|
|
276
318
|
2. `versionUpdateChecker` periodically requests the version file at runtime and compares it with the current version
|
|
277
319
|
3. When a version mismatch is detected, a prompt is shown to guide the user to refresh
|
|
278
320
|
|
|
279
|
-
| Option | Type | Default
|
|
280
|
-
| ----------------------- | ------------------------------------ |
|
|
281
|
-
| versionSource | `'define'` \| `'file'` \| `'auto'` | `'auto'`
|
|
282
|
-
| defineName | `string` | `'__APP_VERSION__'`
|
|
283
|
-
| checkUrl | `string` | `'/version.json'`
|
|
284
|
-
| checkInterval | `number` | `300000`
|
|
285
|
-
| checkOnVisibilityChange | `boolean` | `true`
|
|
286
|
-
| enableInDev | `boolean` | `false`
|
|
287
|
-
| promptStyle | `'modal'` \| `'banner'` \| `'toast'` | `'modal'`
|
|
288
|
-
| promptMessage | `string` | `'A new version is available. Refresh now
|
|
289
|
-
| refreshButtonText | `string` | `'Refresh'`
|
|
290
|
-
| dismissButtonText | `string` | `'Later'`
|
|
291
|
-
| customPromptTemplate | `string` | -
|
|
292
|
-
| customStyle | `string` | -
|
|
293
|
-
| onUpdateAvailable | `string` | -
|
|
294
|
-
| onRefresh | `string` | -
|
|
295
|
-
| onDismiss | `string` | -
|
|
321
|
+
| Option | Type | Default | Description |
|
|
322
|
+
| ----------------------- | ------------------------------------ | -------------------------------------------- | ------------------------------------------------------------ |
|
|
323
|
+
| versionSource | `'define'` \| `'file'` \| `'auto'` | `'auto'` | Current version source |
|
|
324
|
+
| defineName | `string` | `'__APP_VERSION__'` | Global variable name in define mode |
|
|
325
|
+
| checkUrl | `string` | `'/version.json'` | URL path for version check file |
|
|
326
|
+
| checkInterval | `number` | `300000` | Check interval (ms, default 5 minutes) |
|
|
327
|
+
| checkOnVisibilityChange | `boolean` | `true` | Whether to check immediately on page visibility change |
|
|
328
|
+
| enableInDev | `boolean` | `false` | Whether to enable in development mode |
|
|
329
|
+
| promptStyle | `'modal'` \| `'banner'` \| `'toast'` | `'modal'` | Update prompt UI style |
|
|
330
|
+
| promptMessage | `string` | `'A new version is available. Refresh now?'` | Prompt message text |
|
|
331
|
+
| refreshButtonText | `string` | `'Refresh Now'` | Refresh button text |
|
|
332
|
+
| dismissButtonText | `string` | `'Later'` | Dismiss button text |
|
|
333
|
+
| customPromptTemplate | `string` | - | Custom HTML template for the prompt UI |
|
|
334
|
+
| customStyle | `string` | - | Custom CSS style string |
|
|
335
|
+
| onUpdateAvailable | `string` | - | Callback when new version is found (function body string) |
|
|
336
|
+
| onRefresh | `string` | - | Callback when user chooses to refresh (function body string) |
|
|
337
|
+
| onDismiss | `string` | - | Callback when user chooses to dismiss (function body string) |
|
|
296
338
|
|
|
297
339
|
> `versionSource` explanation: `'define'` reads from global variable, `'file'` reads from version file, `'auto'` prefers define and falls back to file. Custom templates can use `{{message}}`, `{{currentVersion}}`,
|
|
298
|
-
> `{{newVersion}}`, `{{refreshButton}}`, `{{dismissButton}}` placeholders. Callbacks are provided as function body strings
|
|
340
|
+
> `{{newVersion}}`, `{{refreshButton}}`, `{{dismissButton}}` placeholders. Callbacks are provided as function body strings, available variables: `currentVersion`, `newVersion`.
|
|
299
341
|
|
|
300
342
|
```typescript
|
|
301
343
|
generateVersion({ outputType: 'both' })
|
|
@@ -304,7 +346,7 @@ versionUpdateChecker({ versionSource: 'file' })
|
|
|
304
346
|
versionUpdateChecker({ checkInterval: 60000, promptStyle: 'banner' })
|
|
305
347
|
versionUpdateChecker({ promptStyle: 'toast' })
|
|
306
348
|
versionUpdateChecker({ promptMessage: 'System updated, refresh to experience new features', refreshButtonText: 'Update', dismissButtonText: 'Cancel' })
|
|
307
|
-
versionUpdateChecker({ onUpdateAvailable: 'console.log("New version:", newVersion); return true;', onRefresh: 'console.log("User chose
|
|
349
|
+
versionUpdateChecker({ onUpdateAvailable: 'console.log("New version:", newVersion); return true;', onRefresh: 'console.log("User chose refresh");', onDismiss: 'console.log("User chose dismiss");' })
|
|
308
350
|
versionUpdateChecker({ enableInDev: true })
|
|
309
351
|
```
|
|
310
352
|
|
|
@@ -312,57 +354,56 @@ versionUpdateChecker({ enableInDev: true })
|
|
|
312
354
|
|
|
313
355
|
### htmlInject
|
|
314
356
|
|
|
315
|
-
Inject
|
|
316
|
-
|
|
317
|
-
**Injection positions:**
|
|
318
|
-
|
|
319
|
-
| Position | Description |
|
|
320
|
-
| ------------------ | ------------------------------------------ |
|
|
321
|
-
| `head-start` | Inject after the `<head>` tag opening |
|
|
322
|
-
| `head-end` | Inject before the `</head>` closing tag |
|
|
323
|
-
| `body-start` | Inject after the `<body>` tag opening |
|
|
324
|
-
| `body-end` | Inject before the `</body>` closing tag |
|
|
325
|
-
| `before-selector` | Inject before the selector-matched content |
|
|
326
|
-
| `after-selector` | Inject after the selector-matched content |
|
|
327
|
-
| `replace-selector` | Replace the selector-matched content |
|
|
357
|
+
Inject custom content into HTML files, supporting multiple positions, selector targeting, conditional injection, template variable replacement, and security filtering.
|
|
328
358
|
|
|
329
|
-
| Option | Type | Default | Description
|
|
330
|
-
| ------------ | ------------------------ | -------------- |
|
|
331
|
-
| targetFile | `string` | `'index.html'` | Target HTML file path or filename
|
|
332
|
-
| rules | `InjectRule[]` | - |
|
|
333
|
-
| security | `SecurityConfig` | - | Security filtering
|
|
334
|
-
| templateVars | `Record<string, string>` |
|
|
335
|
-
| logInjection | `boolean` | `true` | Whether to output injection logs
|
|
359
|
+
| Option | Type | Default | Description |
|
|
360
|
+
| ------------ | ------------------------ | -------------- | ------------------------------------------- |
|
|
361
|
+
| targetFile | `string` | `'index.html'` | Target HTML file path or filename |
|
|
362
|
+
| rules | `InjectRule[]` | - | Injection rules list (required) |
|
|
363
|
+
| security | `SecurityConfig` | - | Security filtering config |
|
|
364
|
+
| templateVars | `Record<string, string>` | `{}` | Global template variable mapping |
|
|
365
|
+
| logInjection | `boolean` | `true` | Whether to output injection logs to console |
|
|
336
366
|
|
|
337
367
|
**InjectRule**
|
|
338
368
|
|
|
339
|
-
| Property | Type
|
|
340
|
-
| -------------------- |
|
|
341
|
-
| id | `string`
|
|
342
|
-
| content | `string`
|
|
343
|
-
| position | `
|
|
344
|
-
| selector | `string`
|
|
345
|
-
| selectorMatch | `'string'` \| `'regex'`
|
|
346
|
-
| priority | `number`
|
|
347
|
-
| condition | `InjectCondition`
|
|
348
|
-
| templateVars | `Record<string, string>`
|
|
349
|
-
| allowScriptInjection | `boolean`
|
|
369
|
+
| Property | Type | Default | Description |
|
|
370
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ---------- | --------------------------------------------------------- |
|
|
371
|
+
| id | `string` | - | Unique rule identifier |
|
|
372
|
+
| content | `string` | - | Content to inject |
|
|
373
|
+
| position | `'head-start'` \| `'head-end'` \| `'body-start'` \| `'body-end'` \| `'before-selector'` \| `'after-selector'` \| `'replace-selector'` | - | Injection position |
|
|
374
|
+
| selector | `string` | - | Selector string (required for selector-related positions) |
|
|
375
|
+
| selectorMatch | `'string'` \| `'regex'` | `'string'` | Selector match mode |
|
|
376
|
+
| priority | `number` | `100` | Rule priority, lower values execute first |
|
|
377
|
+
| condition | `InjectCondition` | - | Injection condition |
|
|
378
|
+
| templateVars | `Record<string, string>` | - | Rule-level template variables (override global) |
|
|
379
|
+
| allowScriptInjection | `boolean` | `false` | Whether to allow injecting scripts and dangerous content |
|
|
380
|
+
|
|
381
|
+
**InjectCondition**
|
|
382
|
+
|
|
383
|
+
| Property | Type | Default | Description |
|
|
384
|
+
| -------- | ------------------------------------------ | ------- | -------------------------------------- |
|
|
385
|
+
| type | `'env'` \| `'file-contains'` \| `'custom'` | - | Condition type |
|
|
386
|
+
| value | `string` \| `(...args: any[]) => boolean` | - | Condition value |
|
|
387
|
+
| negate | `boolean` | `false` | Whether to negate the condition result |
|
|
350
388
|
|
|
351
389
|
**SecurityConfig**
|
|
352
390
|
|
|
353
|
-
| Property | Type | Default | Description
|
|
354
|
-
| ------------------------ | ---------- | ------- |
|
|
355
|
-
| blockDangerousTags | `boolean` | `true` |
|
|
356
|
-
| blockDangerousAttributes | `boolean` | `true` |
|
|
357
|
-
| allowedTags | `string[]` | - | Whitelist of allowed tags
|
|
358
|
-
| blockedTags | `string[]` | - | Custom
|
|
359
|
-
| blockedAttributes | `string[]` | - | Custom
|
|
391
|
+
| Property | Type | Default | Description |
|
|
392
|
+
| ------------------------ | ---------- | ------- | ----------------------------------------------------- |
|
|
393
|
+
| blockDangerousTags | `boolean` | `true` | Whether to block dangerous tags (script, etc.) |
|
|
394
|
+
| blockDangerousAttributes | `boolean` | `true` | Whether to block dangerous attributes (onclick, etc.) |
|
|
395
|
+
| allowedTags | `string[]` | - | Whitelist of allowed tags |
|
|
396
|
+
| blockedTags | `string[]` | - | Custom blocked tags list |
|
|
397
|
+
| blockedAttributes | `string[]` | - | Custom blocked attributes list |
|
|
360
398
|
|
|
361
399
|
```typescript
|
|
362
400
|
htmlInject({
|
|
363
401
|
rules: [
|
|
364
|
-
{ id: 'meta-description', content: '<meta name="description" content="
|
|
365
|
-
{ id: 'analytics', content: '<script src="
|
|
402
|
+
{ id: 'meta-description', content: '<meta name="description" content="My App">', position: 'head-end' },
|
|
403
|
+
{ id: 'analytics', content: '<script src="https://analytics.example.com/track.js"></script>', position: 'body-end', allowScriptInjection: true },
|
|
404
|
+
{ id: 'env-var', content: '<script>window.__ENV__ = "{{env}}"</script>', position: 'head-end', templateVars: { env: 'production' }, allowScriptInjection: true },
|
|
405
|
+
{ id: 'before-app', content: '<div>Before App</div>', position: 'before-selector', selector: '<div id="app">' },
|
|
406
|
+
{ id: 'prod-only', content: '<meta name="robots" content="noindex">', position: 'head-end', condition: { type: 'env', value: 'PRODUCTION' } }
|
|
366
407
|
]
|
|
367
408
|
})
|
|
368
409
|
```
|
|
@@ -371,15 +412,15 @@ htmlInject({
|
|
|
371
412
|
|
|
372
413
|
### faviconManager
|
|
373
414
|
|
|
374
|
-
Manage website favicon links injection into HTML files,
|
|
415
|
+
Manage website favicon links injection into HTML files, supports icon file copying, supports string shorthand config.
|
|
375
416
|
|
|
376
|
-
| Option | Type
|
|
377
|
-
| ----------- |
|
|
378
|
-
| base | `string`
|
|
379
|
-
| url | `string`
|
|
380
|
-
| link | `string`
|
|
381
|
-
| icons | `Icon[]`
|
|
382
|
-
| copyOptions | `
|
|
417
|
+
| Option | Type | Default | Description |
|
|
418
|
+
| ----------- | ------------- | ------- | ------------------------------------------------------ |
|
|
419
|
+
| base | `string` | `'/'` | Base path for icon files |
|
|
420
|
+
| url | `string` | - | Complete icon URL (overrides base + favicon.ico) |
|
|
421
|
+
| link | `string` | - | Custom complete link tag HTML (highest priority) |
|
|
422
|
+
| icons | `Icon[]` | - | Custom icon array, supports multiple formats and sizes |
|
|
423
|
+
| copyOptions | `CopyOptions` | - | Icon file copying config |
|
|
383
424
|
|
|
384
425
|
**Icon**
|
|
385
426
|
|
|
@@ -387,12 +428,21 @@ Manage website favicon links injection into HTML files, supporting string shorth
|
|
|
387
428
|
| -------- | -------- | ------------------ |
|
|
388
429
|
| rel | `string` | Icon relation type |
|
|
389
430
|
| href | `string` | Icon URL |
|
|
390
|
-
| sizes | `string` | Icon
|
|
431
|
+
| sizes | `string` | Icon sizes |
|
|
391
432
|
| type | `string` | Icon MIME type |
|
|
392
433
|
|
|
434
|
+
**CopyOptions**
|
|
435
|
+
|
|
436
|
+
| Property | Type | Default | Description |
|
|
437
|
+
| --------- | --------- | ------- | ----------------------------------- |
|
|
438
|
+
| sourceDir | `string` | - | Icon source directory (required) |
|
|
439
|
+
| targetDir | `string` | - | Icon target directory (required) |
|
|
440
|
+
| overwrite | `boolean` | `true` | Whether to overwrite existing files |
|
|
441
|
+
| recursive | `boolean` | `true` | Whether to copy recursively |
|
|
442
|
+
|
|
393
443
|
```typescript
|
|
394
|
-
faviconManager()
|
|
395
444
|
faviconManager('/assets')
|
|
445
|
+
faviconManager({ base: '/assets', url: '/assets/favicon.ico' })
|
|
396
446
|
faviconManager({
|
|
397
447
|
base: '/assets',
|
|
398
448
|
icons: [
|
|
@@ -400,49 +450,109 @@ faviconManager({
|
|
|
400
450
|
{ rel: 'icon', href: '/favicon-32x32.png', sizes: '32x32', type: 'image/png' }
|
|
401
451
|
]
|
|
402
452
|
})
|
|
403
|
-
faviconManager({
|
|
404
|
-
|
|
453
|
+
faviconManager({
|
|
454
|
+
base: '/assets',
|
|
455
|
+
copyOptions: { sourceDir: 'src/assets/icons', targetDir: 'dist/assets/icons' }
|
|
456
|
+
})
|
|
405
457
|
```
|
|
406
458
|
|
|
407
459
|
---
|
|
408
460
|
|
|
409
461
|
### loadingManager
|
|
410
462
|
|
|
411
|
-
Global Loading state management with request interception and white-screen Loading
|
|
412
|
-
|
|
413
|
-
| Option | Type
|
|
414
|
-
| -------------- |
|
|
415
|
-
| position | `
|
|
416
|
-
| defaultText | `string`
|
|
417
|
-
| spinnerType | `
|
|
418
|
-
|
|
|
419
|
-
|
|
|
420
|
-
|
|
|
421
|
-
|
|
|
422
|
-
|
|
|
423
|
-
|
|
|
424
|
-
|
|
|
425
|
-
|
|
|
426
|
-
|
|
|
427
|
-
|
|
|
428
|
-
|
|
|
429
|
-
| callbacks | `LoadingCallbacks`
|
|
463
|
+
Global Loading state management with request interception, debounce, transition animations, and white-screen Loading.
|
|
464
|
+
|
|
465
|
+
| Option | Type | Default | Description |
|
|
466
|
+
| -------------- | ------------------ | ----------------------- | ------------------------------------------------------------- |
|
|
467
|
+
| position | `LoadingPosition` | `'center'` | Loading display position |
|
|
468
|
+
| defaultText | `string` | `'Loading...'` | Default display text |
|
|
469
|
+
| spinnerType | `SpinnerType` | `'spinner'` | Spinner icon type |
|
|
470
|
+
| style | `LoadingStyle` | - | Custom style config |
|
|
471
|
+
| transition | `TransitionConfig` | - | Transition animation config |
|
|
472
|
+
| minDisplayTime | `MinDisplayTime` | - | Minimum display time config |
|
|
473
|
+
| delayShow | `DelayShow` | - | Delay show config |
|
|
474
|
+
| debounceHide | `DebounceHide` | - | Debounce hide config |
|
|
475
|
+
| autoBind | `AutoBindMode` | `'none'` | Auto-bind request interception mode |
|
|
476
|
+
| requestFilter | `RequestFilter` | - | Request filter config |
|
|
477
|
+
| globalName | `string` | `'__LOADING_MANAGER__'` | Injected global variable name |
|
|
478
|
+
| customTemplate | `string` | - | Custom Loading HTML template |
|
|
479
|
+
| defaultVisible | `boolean` | `false` | Loading DOM initial visibility (white-screen Loading) |
|
|
480
|
+
| autoHideOn | `AutoHideOn` | `'DOMContentLoaded'` | Auto-hide timing (only effective when defaultVisible is true) |
|
|
481
|
+
| callbacks | `LoadingCallbacks` | - | Lifecycle callbacks |
|
|
482
|
+
|
|
483
|
+
**LoadingPosition**: `'center'` | `'top'` | `'bottom'`
|
|
484
|
+
|
|
485
|
+
**SpinnerType**: `'spinner'` | `'dots'` | `'pulse'` | `'bar'`
|
|
486
|
+
|
|
487
|
+
**AutoBindMode**: `'fetch'` | `'xhr'` | `'all'` | `'none'`
|
|
488
|
+
|
|
489
|
+
**AutoHideOn**: `'DOMContentLoaded'` | `'load'` | `'manual'`
|
|
430
490
|
|
|
431
491
|
**LoadingStyle**
|
|
432
492
|
|
|
433
493
|
| Property | Type | Default | Description |
|
|
434
494
|
| ------------------ | --------- | ------------------------- | ---------------------------------------- |
|
|
435
495
|
| overlayColor | `string` | `'rgba(255,255,255,0.7)'` | Overlay background color |
|
|
436
|
-
| spinnerColor | `string` | `'#4361ee'` |
|
|
437
|
-
| spinnerSize | `string` | `'40px'` |
|
|
496
|
+
| spinnerColor | `string` | `'#4361ee'` | Loading icon color |
|
|
497
|
+
| spinnerSize | `string` | `'40px'` | Loading icon size |
|
|
438
498
|
| textColor | `string` | `'#333'` | Text color |
|
|
439
499
|
| textSize | `string` | `'14px'` | Text size |
|
|
440
|
-
| zIndex | `number` | `9999` | z-index value |
|
|
441
|
-
| pointerEvents | `boolean` | `true` | Whether to enable overlay pointer events |
|
|
442
|
-
| backdropBlur | `boolean` | `false` | Whether to enable background blur |
|
|
443
|
-
| backdropBlurAmount | `number` | `4` | Background blur amount (px) |
|
|
444
500
|
| customClass | `string` | - | Custom CSS class name |
|
|
445
501
|
| customStyle | `string` | - | Custom inline style string |
|
|
502
|
+
| zIndex | `number` | `9999` | Overlay z-index |
|
|
503
|
+
| pointerEvents | `boolean` | `true` | Whether to enable overlay pointer events |
|
|
504
|
+
| backdropBlur | `boolean` | `false` | Whether to enable backdrop blur |
|
|
505
|
+
| backdropBlurAmount | `number` | `4` | Backdrop blur amount (px) |
|
|
506
|
+
|
|
507
|
+
**TransitionConfig**
|
|
508
|
+
|
|
509
|
+
| Property | Type | Default | Description |
|
|
510
|
+
| -------- | --------- | ------------ | ------------------------------ |
|
|
511
|
+
| enabled | `boolean` | `true` | Whether to enable transition |
|
|
512
|
+
| duration | `number` | `200` | Transition duration (ms) |
|
|
513
|
+
| easing | `string` | `'ease-out'` | CSS transition easing function |
|
|
514
|
+
|
|
515
|
+
**MinDisplayTime**
|
|
516
|
+
|
|
517
|
+
| Property | Type | Default | Description |
|
|
518
|
+
| -------- | --------- | ------- | -------------------------------------- |
|
|
519
|
+
| enabled | `boolean` | `true` | Whether to enable minimum display time |
|
|
520
|
+
| duration | `number` | `300` | Minimum display time (ms) |
|
|
521
|
+
|
|
522
|
+
**DelayShow**
|
|
523
|
+
|
|
524
|
+
| Property | Type | Default | Description |
|
|
525
|
+
| -------- | --------- | ------- | --------------------------------------------------------------- |
|
|
526
|
+
| enabled | `boolean` | `true` | Whether to enable delay show |
|
|
527
|
+
| duration | `number` | `200` | Delay time (ms), requests completed within this time won't show |
|
|
528
|
+
|
|
529
|
+
**DebounceHide**
|
|
530
|
+
|
|
531
|
+
| Property | Type | Default | Description |
|
|
532
|
+
| -------- | --------- | ------- | ------------------------------- |
|
|
533
|
+
| enabled | `boolean` | `false` | Whether to enable debounce hide |
|
|
534
|
+
| duration | `number` | `100` | Debounce wait time (ms) |
|
|
535
|
+
|
|
536
|
+
**RequestFilter**
|
|
537
|
+
|
|
538
|
+
| Property | Type | Description |
|
|
539
|
+
| ------------------ | ---------- | ------------------------------ |
|
|
540
|
+
| excludeUrls | `RegExp[]` | URL regex patterns to exclude |
|
|
541
|
+
| includeUrls | `RegExp[]` | URL regex patterns to include |
|
|
542
|
+
| excludeMethods | `string[]` | HTTP methods to exclude |
|
|
543
|
+
| excludeUrlPrefixes | `string[]` | URL string prefixes to exclude |
|
|
544
|
+
|
|
545
|
+
**LoadingCallbacks**
|
|
546
|
+
|
|
547
|
+
| Property | Type | Description |
|
|
548
|
+
| ------------ | -------- | -------------------------------------------------------- |
|
|
549
|
+
| onBeforeShow | `string` | Before show callback (`return false` to prevent showing) |
|
|
550
|
+
| onShow | `string` | After show callback |
|
|
551
|
+
| onBeforeHide | `string` | Before hide callback (`return false` to prevent hiding) |
|
|
552
|
+
| onHide | `string` | After hide callback |
|
|
553
|
+
| onDestroy | `string` | On destroy callback |
|
|
554
|
+
|
|
555
|
+
> Callbacks are provided as function body strings because they need to be injected into client-side code. `customTemplate` must contain an element with the `data-loading-text` attribute for text display.
|
|
446
556
|
|
|
447
557
|
**Runtime API:**
|
|
448
558
|
|
|
@@ -450,28 +560,27 @@ Global Loading state management with request interception and white-screen Loadi
|
|
|
450
560
|
window.__LOADING_MANAGER__.show('Loading...')
|
|
451
561
|
window.__LOADING_MANAGER__.hide()
|
|
452
562
|
window.__LOADING_MANAGER__.forceHide()
|
|
453
|
-
window.__LOADING_MANAGER__.toggle()
|
|
563
|
+
window.__LOADING_MANAGER__.toggle('Loading...')
|
|
454
564
|
window.__LOADING_MANAGER__.updateText('Processing...')
|
|
455
565
|
window.__LOADING_MANAGER__.isVisible()
|
|
456
566
|
window.__LOADING_MANAGER__.getPendingCount()
|
|
457
|
-
window.__LOADING_MANAGER__.destroy()
|
|
458
567
|
window.__LOADING_MANAGER__.enablePointerEvents()
|
|
459
568
|
window.__LOADING_MANAGER__.disablePointerEvents()
|
|
460
|
-
window.__LOADING_MANAGER__.
|
|
461
|
-
window.__LOADING_MANAGER__.isPointerEventsEnabled()
|
|
569
|
+
window.__LOADING_MANAGER__.destroy()
|
|
462
570
|
```
|
|
463
571
|
|
|
464
572
|
```typescript
|
|
465
573
|
loadingManager()
|
|
466
|
-
loadingManager({
|
|
467
|
-
loadingManager({ spinnerType: 'dots' })
|
|
468
|
-
loadingManager({ autoBind: 'fetch', requestFilter: { excludeUrls: [/\/api\/health/]
|
|
469
|
-
loadingManager({
|
|
574
|
+
loadingManager({ defaultVisible: true, autoHideOn: 'DOMContentLoaded' })
|
|
575
|
+
loadingManager({ position: 'top', defaultText: 'Please wait...', spinnerType: 'dots' })
|
|
576
|
+
loadingManager({ autoBind: 'fetch', requestFilter: { excludeUrls: [/\/api\/health/] } })
|
|
577
|
+
loadingManager({
|
|
578
|
+
style: { overlayColor: 'rgba(0,0,0,0.5)', spinnerColor: '#ff6b6b', backdropBlur: true, backdropBlurAmount: 6 }
|
|
579
|
+
})
|
|
470
580
|
loadingManager({ transition: { enabled: true, duration: 300, easing: 'cubic-bezier(0.4,0,0.2,1)' } })
|
|
471
581
|
loadingManager({ debounceHide: { enabled: true, duration: 100 } })
|
|
472
|
-
loadingManager({ callbacks: { onShow: 'console.log("
|
|
582
|
+
loadingManager({ callbacks: { onShow: 'console.log("shown")', onBeforeShow: 'return true' } })
|
|
473
583
|
loadingManager({ customTemplate: '<div class="my-loader"><span data-loading-text></span></div>' })
|
|
474
|
-
loadingManager({ defaultVisible: true, autoHideOn: 'DOMContentLoaded' })
|
|
475
584
|
loadingManager({ defaultVisible: true, autoHideOn: 'manual' })
|
|
476
585
|
```
|
|
477
586
|
|
|
@@ -479,32 +588,41 @@ loadingManager({ defaultVisible: true, autoHideOn: 'manual' })
|
|
|
479
588
|
|
|
480
589
|
## Plugin Development Framework
|
|
481
590
|
|
|
591
|
+
This package not only provides built-in plugins but also exports a complete plugin development framework to help quickly build custom Vite plugins that follow conventions.
|
|
592
|
+
|
|
482
593
|
### BasePlugin
|
|
483
594
|
|
|
484
|
-
The base class for all built-in plugins, providing core
|
|
595
|
+
The base class for all built-in plugins, providing core capabilities such as configuration management, logging, error handling, and lifecycle management.
|
|
485
596
|
|
|
486
597
|
```typescript
|
|
487
|
-
import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin
|
|
598
|
+
import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin'
|
|
488
599
|
import type { Plugin } from 'vite'
|
|
489
600
|
|
|
490
601
|
interface MyPluginOptions {
|
|
491
|
-
|
|
492
|
-
message?: string
|
|
602
|
+
prefix?: string
|
|
493
603
|
}
|
|
494
604
|
|
|
495
605
|
class MyPlugin extends BasePlugin<MyPluginOptions> {
|
|
496
606
|
protected getPluginName() {
|
|
497
607
|
return 'my-plugin'
|
|
498
608
|
}
|
|
609
|
+
|
|
499
610
|
protected getDefaultOptions() {
|
|
500
|
-
return {
|
|
611
|
+
return { prefix: '[app]' }
|
|
501
612
|
}
|
|
613
|
+
|
|
502
614
|
protected validateOptions() {
|
|
503
|
-
this.validator.field('
|
|
615
|
+
this.validator.field('prefix').string().notEmpty().validate()
|
|
504
616
|
}
|
|
617
|
+
|
|
505
618
|
protected addPluginHooks(plugin: Plugin) {
|
|
506
|
-
plugin.
|
|
507
|
-
|
|
619
|
+
plugin.writeBundle = {
|
|
620
|
+
order: 'post',
|
|
621
|
+
handler: async () => {
|
|
622
|
+
await this.safeExecute(async () => {
|
|
623
|
+
this.logger.info('Plugin executing...')
|
|
624
|
+
}, 'Execute custom logic')
|
|
625
|
+
}
|
|
508
626
|
}
|
|
509
627
|
}
|
|
510
628
|
}
|
|
@@ -512,86 +630,270 @@ class MyPlugin extends BasePlugin<MyPluginOptions> {
|
|
|
512
630
|
export const myPlugin = createPluginFactory(MyPlugin)
|
|
513
631
|
```
|
|
514
632
|
|
|
515
|
-
|
|
633
|
+
**BasePlugin Core Methods:**
|
|
634
|
+
|
|
635
|
+
| Method | Description |
|
|
636
|
+
| ------------------- | -------------------------------------------------------------- |
|
|
637
|
+
| `getDefaultOptions` | Returns plugin default config, can be overridden by subclasses |
|
|
638
|
+
| `validateOptions` | Validates user config, can be overridden by subclasses |
|
|
639
|
+
| `getPluginName` | Returns plugin name (abstract method, must be implemented) |
|
|
640
|
+
| `getEnforce` | Returns plugin execution timing (pre / post / undefined) |
|
|
641
|
+
| `addPluginHooks` | Registers Vite hooks (abstract method, must be implemented) |
|
|
642
|
+
| `onConfigResolved` | Config resolution complete callback |
|
|
643
|
+
| `destroy` | Plugin destroy callback |
|
|
644
|
+
| `safeExecute` | Safely execute async function with automatic error handling |
|
|
645
|
+
| `safeExecuteSync` | Safely execute sync function with automatic error handling |
|
|
646
|
+
| `handleError` | Handle errors based on errorStrategy |
|
|
647
|
+
| `toPlugin` | Convert to Vite plugin object |
|
|
648
|
+
|
|
649
|
+
**BasePluginOptions Base Config:**
|
|
650
|
+
|
|
651
|
+
| Option | Type | Default | Description |
|
|
652
|
+
| ------------- | ---------------------------------- | --------- | ----------------------- |
|
|
653
|
+
| enabled | `boolean` | `true` | Whether to enable |
|
|
654
|
+
| verbose | `boolean` | `true` | Whether to log |
|
|
655
|
+
| errorStrategy | `'throw'` \| `'log'` \| `'ignore'` | `'throw'` | Error handling strategy |
|
|
656
|
+
|
|
657
|
+
### createPluginFactory
|
|
658
|
+
|
|
659
|
+
Creates a plugin factory function that converts a BasePlugin subclass into a directly usable Vite plugin function.
|
|
660
|
+
|
|
661
|
+
```typescript
|
|
662
|
+
import { createPluginFactory } from '@meng-xi/vite-plugin'
|
|
663
|
+
|
|
664
|
+
const myPlugin = createPluginFactory(MyPlugin)
|
|
665
|
+
|
|
666
|
+
// Supports options normalizer (e.g. string shorthand config)
|
|
667
|
+
const myPluginWithNormalizer = createPluginFactory(MyPlugin, opt => (typeof opt === 'string' ? { prefix: opt } : opt))
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
### Logger
|
|
671
|
+
|
|
672
|
+
Global singleton log manager, providing independent log proxies for each plugin.
|
|
673
|
+
|
|
674
|
+
```typescript
|
|
675
|
+
import { Logger } from '@meng-xi/vite-plugin/logger'
|
|
676
|
+
|
|
677
|
+
const logger = Logger.create({ name: 'my-plugin', enabled: true })
|
|
678
|
+
logger.info('Info log')
|
|
679
|
+
logger.success('Success log')
|
|
680
|
+
logger.warn('Warning log')
|
|
681
|
+
logger.error('Error log')
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
### Validator
|
|
516
685
|
|
|
517
|
-
|
|
518
|
-
| --------------------- | ------------------------------ | ----------------------------------- |
|
|
519
|
-
| `BasePlugin` | `@meng-xi/vite-plugin/factory` | Plugin base class |
|
|
520
|
-
| `createPluginFactory` | `@meng-xi/vite-plugin/factory` | Plugin factory function creator |
|
|
521
|
-
| `PluginWithInstance` | `@meng-xi/vite-plugin/factory` | Plugin type with instance reference |
|
|
522
|
-
| `Logger` | `@meng-xi/vite-plugin/logger` | Log manager (singleton pattern) |
|
|
523
|
-
| `Validator` | `@meng-xi/vite-plugin/common` | Fluent API configuration validator |
|
|
686
|
+
Chain-style configuration validator for validating plugin configuration parameters.
|
|
524
687
|
|
|
525
|
-
|
|
688
|
+
```typescript
|
|
689
|
+
import { Validator } from '@meng-xi/vite-plugin/common/validation'
|
|
526
690
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
| fs | `@meng-xi/vite-plugin/common/fs` | File copying, directory traversal, concurrency control |
|
|
531
|
-
| html | `@meng-xi/vite-plugin/common/html` | HTML injection (injectBeforeTag, injectHeadAndBody, etc.) |
|
|
532
|
-
| object | `@meng-xi/vite-plugin/common/object` | Deep merge objects |
|
|
533
|
-
| script | `@meng-xi/vite-plugin/common/script` | Callback wrapping, script tag detection, identifier validation |
|
|
534
|
-
| validation | `@meng-xi/vite-plugin/common/validation` | Global name validation, XSS prevention, enum validation, etc. |
|
|
691
|
+
const validator = new Validator(myOptions)
|
|
692
|
+
validator.field('port').number().minValue(1).maxValue(65535).field('host').string().notEmpty().field('mode').enum(['development', 'production']).validate()
|
|
693
|
+
```
|
|
535
694
|
|
|
536
695
|
---
|
|
537
696
|
|
|
538
|
-
##
|
|
697
|
+
## Common Utility Modules
|
|
539
698
|
|
|
540
|
-
|
|
699
|
+
Built-in general-purpose utility function library, organized by functional modules, supporting on-demand sub-path imports.
|
|
700
|
+
|
|
701
|
+
### Import Methods
|
|
541
702
|
|
|
542
703
|
```typescript
|
|
543
|
-
|
|
704
|
+
// Import all utilities
|
|
705
|
+
import { formatFileSize, scanDirectory } from '@meng-xi/vite-plugin/common'
|
|
706
|
+
|
|
707
|
+
// Import by module
|
|
708
|
+
import { formatFileSize } from '@meng-xi/vite-plugin/common/format'
|
|
709
|
+
import { scanDirectory, writeJsonReport } from '@meng-xi/vite-plugin/common/fs'
|
|
710
|
+
import { calculateGzipSize } from '@meng-xi/vite-plugin/common/compress'
|
|
711
|
+
import { isNodeModule } from '@meng-xi/vite-plugin/common/path'
|
|
712
|
+
```
|
|
544
713
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
714
|
+
### Module List
|
|
715
|
+
|
|
716
|
+
| Sub-path | Description |
|
|
717
|
+
| ---------------------------------------- | ----------------------- |
|
|
718
|
+
| `@meng-xi/vite-plugin/common/compress` | Compression utilities |
|
|
719
|
+
| `@meng-xi/vite-plugin/common/format` | Formatting utilities |
|
|
720
|
+
| `@meng-xi/vite-plugin/common/fs` | File system utilities |
|
|
721
|
+
| `@meng-xi/vite-plugin/common/html` | HTML injection utils |
|
|
722
|
+
| `@meng-xi/vite-plugin/common/object` | Object operation utils |
|
|
723
|
+
| `@meng-xi/vite-plugin/common/path` | Path handling utils |
|
|
724
|
+
| `@meng-xi/vite-plugin/common/script` | Script generation utils |
|
|
725
|
+
| `@meng-xi/vite-plugin/common/validation` | Validation utilities |
|
|
726
|
+
|
|
727
|
+
### compress — Compression
|
|
728
|
+
|
|
729
|
+
| Function | Description |
|
|
730
|
+
| ------------------- | ---------------------------------------------------- |
|
|
731
|
+
| `calculateGzipSize` | Calculate gzip compressed size of given data (bytes) |
|
|
732
|
+
|
|
733
|
+
```typescript
|
|
734
|
+
import { calculateGzipSize } from '@meng-xi/vite-plugin/common/compress'
|
|
735
|
+
|
|
736
|
+
const size = await calculateGzipSize(Buffer.from('hello world'))
|
|
555
737
|
```
|
|
556
738
|
|
|
557
|
-
|
|
739
|
+
### format — Formatting
|
|
740
|
+
|
|
741
|
+
| Function | Description |
|
|
742
|
+
| --------------------- | -------------------------------------------------- |
|
|
743
|
+
| `formatFileSize` | Format bytes to human-readable file size string |
|
|
744
|
+
| `getExtension` | Get file extension (lowercase) |
|
|
745
|
+
| `formatDate` | Format date |
|
|
746
|
+
| `parseTemplate` | Parse template string, replace placeholders |
|
|
747
|
+
| `toCamelCase` | Convert string to camelCase |
|
|
748
|
+
| `toPascalCase` | Convert string to PascalCase |
|
|
749
|
+
| `padNumber` | Pad number with leading zeros |
|
|
750
|
+
| `generateRandomHash` | Generate random hash string |
|
|
751
|
+
| `getDateFormatParams` | Get date formatting parameters |
|
|
752
|
+
| `stripJsonComments` | Remove comments from JSON string |
|
|
753
|
+
| `escapeHtmlAttr` | Escape special characters in HTML attribute values |
|
|
558
754
|
|
|
755
|
+
```typescript
|
|
756
|
+
import { formatFileSize, formatDate, toCamelCase } from '@meng-xi/vite-plugin/common/format'
|
|
757
|
+
|
|
758
|
+
formatFileSize(2461726) // '2.35MB'
|
|
759
|
+
formatDate(new Date(), '{YYYY}-{MM}-{DD}') // '2026-05-31'
|
|
760
|
+
toCamelCase('pages/user/profile') // 'pagesUserProfile'
|
|
559
761
|
```
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
@meng-xi/vite-plugin/common/
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
762
|
+
|
|
763
|
+
### fs — File System
|
|
764
|
+
|
|
765
|
+
| Function | Description |
|
|
766
|
+
| -------------------- | --------------------------------------------- |
|
|
767
|
+
| `scanDirectory` | Recursively scan directory, collect file info |
|
|
768
|
+
| `writeJsonReport` | Write data to JSON file |
|
|
769
|
+
| `writeFileContent` | Write file content |
|
|
770
|
+
| `readFileContent` | Read file content |
|
|
771
|
+
| `fileExists` | Check if file exists |
|
|
772
|
+
| `checkSourceExists` | Check if source file exists |
|
|
773
|
+
| `ensureTargetDir` | Create target directory |
|
|
774
|
+
| `copySourceToTarget` | Execute file copy operation |
|
|
775
|
+
| `runWithConcurrency` | Batch execution with concurrency limit |
|
|
776
|
+
|
|
777
|
+
```typescript
|
|
778
|
+
import { scanDirectory, writeJsonReport } from '@meng-xi/vite-plugin/common/fs'
|
|
779
|
+
|
|
780
|
+
const files = await scanDirectory('dist', {
|
|
781
|
+
includeExtensions: ['.js', '.css'],
|
|
782
|
+
excludePatterns: ['node_modules'],
|
|
783
|
+
filter: (filePath, ext, size) => size > 1024
|
|
784
|
+
})
|
|
785
|
+
|
|
786
|
+
await writeJsonReport('dist/report.json', { timestamp: Date.now(), files })
|
|
580
787
|
```
|
|
581
788
|
|
|
582
|
-
|
|
789
|
+
### html — HTML Injection
|
|
583
790
|
|
|
584
|
-
|
|
791
|
+
| Function | Description |
|
|
792
|
+
| ----------------------------- | ---------------------------------------- |
|
|
793
|
+
| `injectBeforeTag` | Inject code before specified closing tag |
|
|
794
|
+
| `injectHtmlByPriority` | Inject code into HTML by priority |
|
|
795
|
+
| `injectBeforeTagWithFallback` | Inject code with fallback strategy |
|
|
796
|
+
| `injectHeadAndBody` | Dual-zone HTML injection (head + body) |
|
|
585
797
|
|
|
586
|
-
|
|
798
|
+
```typescript
|
|
799
|
+
import { injectBeforeTag, injectHeadAndBody } from '@meng-xi/vite-plugin/common/html'
|
|
587
800
|
|
|
588
|
-
|
|
801
|
+
const result = injectBeforeTag(html, '</head>', '<style>body{margin:0}</style>')
|
|
802
|
+
const dual = injectHeadAndBody(html, '<style>...</style>', '<script>...</script>')
|
|
803
|
+
```
|
|
589
804
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
805
|
+
### object — Object Operations
|
|
806
|
+
|
|
807
|
+
| Function | Description |
|
|
808
|
+
| ----------- | ------------------ |
|
|
809
|
+
| `deepMerge` | Deep merge objects |
|
|
810
|
+
|
|
811
|
+
```typescript
|
|
812
|
+
import { deepMerge } from '@meng-xi/vite-plugin/common/object'
|
|
813
|
+
|
|
814
|
+
deepMerge({ a: { b: 1 } }, { a: { c: 2 } }) // { a: { b: 1, c: 2 } }
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### path — Path Handling
|
|
818
|
+
|
|
819
|
+
| Function | Description |
|
|
820
|
+
| -------------- | --------------------------------------- |
|
|
821
|
+
| `isNodeModule` | Check if module ID is from node_modules |
|
|
822
|
+
|
|
823
|
+
```typescript
|
|
824
|
+
import { isNodeModule } from '@meng-xi/vite-plugin/common/path'
|
|
825
|
+
|
|
826
|
+
isNodeModule('node_modules/lodash/index.js') // true
|
|
827
|
+
isNodeModule('src/utils/helper.ts') // false
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
### script — Script Generation
|
|
831
|
+
|
|
832
|
+
| Function | Description |
|
|
833
|
+
| ------------------------ | -------------------------------------------------------------- |
|
|
834
|
+
| `makeCallback` | Wrap callback function body string as safe function expression |
|
|
835
|
+
| `containsScriptTag` | Detect if string contains `<script>` tag |
|
|
836
|
+
| `validateIdentifierName` | Validate if string is a valid JS identifier |
|
|
837
|
+
|
|
838
|
+
```typescript
|
|
839
|
+
import { makeCallback, validateIdentifierName } from '@meng-xi/vite-plugin/common/script'
|
|
840
|
+
|
|
841
|
+
makeCallback('console.log("done")')
|
|
842
|
+
// 'function() { try { console.log("done") } catch(e) { console.error("[callback] error:", e); } }'
|
|
843
|
+
|
|
844
|
+
validateIdentifierName('__APP_VERSION__') // passes
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
### validation — Validation
|
|
848
|
+
|
|
849
|
+
| Function | Description |
|
|
850
|
+
| ---------------------------- | ----------------------------------- |
|
|
851
|
+
| `Validator` | Chain-style configuration validator |
|
|
852
|
+
| `validateGlobalName` | Validate global variable name |
|
|
853
|
+
| `validateNoScriptInTemplate` | Validate no script tag in template |
|
|
854
|
+
| `validateCallbackFields` | Validate callback function fields |
|
|
855
|
+
| `validateNonNegativeNumber` | Validate non-negative number |
|
|
856
|
+
| `validateNestedDuration` | Validate nested duration config |
|
|
857
|
+
| `validateEnumValue` | Validate enum value |
|
|
858
|
+
|
|
859
|
+
```typescript
|
|
860
|
+
import { Validator } from '@meng-xi/vite-plugin/common/validation'
|
|
861
|
+
|
|
862
|
+
const validator = new Validator(options)
|
|
863
|
+
validator.field('port').number().minValue(1).maxValue(65535).validate()
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
---
|
|
867
|
+
|
|
868
|
+
## Sub-path Exports
|
|
869
|
+
|
|
870
|
+
| Sub-path | Description |
|
|
871
|
+
| ----------------------------------------------------- | ------------------------------------ |
|
|
872
|
+
| `@meng-xi/vite-plugin` | Main entry (all plugins + framework) |
|
|
873
|
+
| `@meng-xi/vite-plugin/factory` | Plugin development framework |
|
|
874
|
+
| `@meng-xi/vite-plugin/logger` | Log manager |
|
|
875
|
+
| `@meng-xi/vite-plugin/plugins` | All plugins |
|
|
876
|
+
| `@meng-xi/vite-plugin/common` | All utility functions |
|
|
877
|
+
| `@meng-xi/vite-plugin/common/compress` | Compression utilities |
|
|
878
|
+
| `@meng-xi/vite-plugin/common/format` | Formatting utilities |
|
|
879
|
+
| `@meng-xi/vite-plugin/common/fs` | File system utilities |
|
|
880
|
+
| `@meng-xi/vite-plugin/common/html` | HTML injection utilities |
|
|
881
|
+
| `@meng-xi/vite-plugin/common/object` | Object operation utilities |
|
|
882
|
+
| `@meng-xi/vite-plugin/common/path` | Path handling utilities |
|
|
883
|
+
| `@meng-xi/vite-plugin/common/script` | Script generation utilities |
|
|
884
|
+
| `@meng-xi/vite-plugin/common/validation` | Validation utilities |
|
|
885
|
+
| `@meng-xi/vite-plugin/plugins/build-progress` | buildProgress plugin |
|
|
886
|
+
| `@meng-xi/vite-plugin/plugins/bundle-analyzer` | bundleAnalyzer plugin |
|
|
887
|
+
| `@meng-xi/vite-plugin/plugins/compress-assets` | compressAssets plugin |
|
|
888
|
+
| `@meng-xi/vite-plugin/plugins/copy-file` | copyFile plugin |
|
|
889
|
+
| `@meng-xi/vite-plugin/plugins/favicon-manager` | faviconManager plugin |
|
|
890
|
+
| `@meng-xi/vite-plugin/plugins/generate-router` | generateRouter plugin |
|
|
891
|
+
| `@meng-xi/vite-plugin/plugins/generate-version` | generateVersion plugin |
|
|
892
|
+
| `@meng-xi/vite-plugin/plugins/html-inject` | htmlInject plugin |
|
|
893
|
+
| `@meng-xi/vite-plugin/plugins/loading-manager` | loadingManager plugin |
|
|
894
|
+
| `@meng-xi/vite-plugin/plugins/version-update-checker` | versionUpdateChecker plugin |
|
|
895
|
+
|
|
896
|
+
---
|
|
595
897
|
|
|
596
898
|
## License
|
|
597
899
|
|