@meng-xi/vite-plugin 0.0.4 → 0.0.5
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 +88 -70
- package/README.md +90 -51
- package/dist/common/index.cjs +1 -1
- package/dist/common/index.d.cts +76 -1
- package/dist/common/index.d.mts +76 -1
- package/dist/common/index.d.ts +76 -1
- package/dist/common/index.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/plugins/index.cjs +1 -1
- package/dist/plugins/index.d.cts +131 -1
- package/dist/plugins/index.d.mts +131 -1
- package/dist/plugins/index.d.ts +131 -1
- package/dist/plugins/index.mjs +1 -1
- package/dist/shared/vite-plugin.BZsetDCm.cjs +1 -0
- package/dist/shared/vite-plugin.CS9a5kjK.mjs +36 -0
- package/dist/shared/vite-plugin.CgnG5_UX.cjs +36 -0
- package/dist/shared/vite-plugin.YvjM8LxW.mjs +1 -0
- package/package.json +5 -5
- package/dist/shared/vite-plugin.D6NYITpX.cjs +0 -1
- package/dist/shared/vite-plugin.D8HTI0Ni.cjs +0 -2
- package/dist/shared/vite-plugin.Dd2ogbSe.mjs +0 -2
- package/dist/shared/vite-plugin.HZb-1B5l.mjs +0 -1
package/dist/common/index.d.ts
CHANGED
|
@@ -84,6 +84,38 @@ declare function readDirRecursive(dirPath: string, recursive: boolean): Promise<
|
|
|
84
84
|
* @returns 是否需要更新
|
|
85
85
|
*/
|
|
86
86
|
declare function shouldUpdateFile(sourceFile: string, targetFile: string): Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* 检查文件是否存在
|
|
89
|
+
* @param filePath 文件路径
|
|
90
|
+
* @returns 是否存在
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* if (await fileExists('/path/to/file')) {
|
|
95
|
+
* console.log('文件存在')
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare function fileExists(filePath: string): Promise<boolean>;
|
|
100
|
+
/**
|
|
101
|
+
* 带并发限制的批量执行
|
|
102
|
+
*
|
|
103
|
+
* @param items 待处理项
|
|
104
|
+
* @param handler 处理函数
|
|
105
|
+
* @param concurrency 并发数
|
|
106
|
+
* @returns 处理结果数组,顺序与输入项对应
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const urls = ['url1', 'url2', 'url3', 'url4', 'url5']
|
|
111
|
+
* const results = await runWithConcurrency(
|
|
112
|
+
* urls,
|
|
113
|
+
* async (url) => fetch(url),
|
|
114
|
+
* 3 // 最多同时处理3个请求
|
|
115
|
+
* )
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
declare function runWithConcurrency<T, R>(items: T[], handler: (item: T) => Promise<R>, concurrency: number): Promise<R[]>;
|
|
87
119
|
/**
|
|
88
120
|
* 执行文件复制操作(优化版:并行IO)
|
|
89
121
|
* @param sourcePath 源文件或目录路径
|
|
@@ -201,6 +233,49 @@ declare function formatDate(date: Date, format: string): string;
|
|
|
201
233
|
* ```
|
|
202
234
|
*/
|
|
203
235
|
declare function parseTemplate(template: string, values: Record<string, string>): string;
|
|
236
|
+
/**
|
|
237
|
+
* 将字符串转换为驼峰命名(camelCase)
|
|
238
|
+
*
|
|
239
|
+
* @param str 输入字符串
|
|
240
|
+
* @param separators 分隔符正则,默认为斜杠和横线
|
|
241
|
+
* @returns 驼峰命名字符串
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* toCamelCase('pages/user/profile') // 'pagesUserProfile'
|
|
246
|
+
* toCamelCase('user-profile-page') // 'userProfilePage'
|
|
247
|
+
* toCamelCase('/pages/index') // 'pagesIndex'
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
declare function toCamelCase(str: string, separators?: RegExp): string;
|
|
251
|
+
/**
|
|
252
|
+
* 将字符串转换为帕斯卡命名(PascalCase)
|
|
253
|
+
*
|
|
254
|
+
* @param str 输入字符串
|
|
255
|
+
* @param separators 分隔符正则,默认为斜杠和横线
|
|
256
|
+
* @returns 帕斯卡命名字符串
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* toPascalCase('pages/user/profile') // 'PagesUserProfile'
|
|
261
|
+
* toPascalCase('user-profile-page') // 'UserProfilePage'
|
|
262
|
+
* toPascalCase('/pages/index') // 'PagesIndex'
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
declare function toPascalCase(str: string, separators?: RegExp): string;
|
|
266
|
+
/**
|
|
267
|
+
* 移除 JSON 字符串中的注释
|
|
268
|
+
*
|
|
269
|
+
* @param jsonString 包含注释的 JSON 字符串
|
|
270
|
+
* @returns 移除注释后的 JSON 字符串
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```typescript
|
|
274
|
+
* stripJsonComments('{\n // comment\n "name": "test"\n}')
|
|
275
|
+
* // '{\n "name": "test"\n}'
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
278
|
+
declare function stripJsonComments(jsonString: string): string;
|
|
204
279
|
|
|
205
280
|
/**
|
|
206
281
|
* 深度合并对象
|
|
@@ -231,5 +306,5 @@ declare function parseTemplate(template: string, values: Record<string, string>)
|
|
|
231
306
|
*/
|
|
232
307
|
declare function deepMerge<T extends Record<string, any>>(...sources: Partial<T>[]): T;
|
|
233
308
|
|
|
234
|
-
export { checkSourceExists, copySourceToTarget, deepMerge, ensureTargetDir, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, readDirRecursive, readFileSync, shouldUpdateFile, writeFileContent };
|
|
309
|
+
export { checkSourceExists, copySourceToTarget, deepMerge, ensureTargetDir, fileExists, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, readDirRecursive, readFileSync, runWithConcurrency, shouldUpdateFile, stripJsonComments, toCamelCase, toPascalCase, writeFileContent };
|
|
235
310
|
export type { DateFormatOptions };
|
package/dist/common/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{c as checkSourceExists,a as copySourceToTarget,e as ensureTargetDir,f as formatDate,g as generateRandomHash,
|
|
1
|
+
export{c as checkSourceExists,a as copySourceToTarget,e as ensureTargetDir,f as fileExists,b as formatDate,g as generateRandomHash,d as getDateFormatParams,p as padNumber,h as parseTemplate,r as readDirRecursive,i as readFileSync,j as runWithConcurrency,s as shouldUpdateFile,k as stripJsonComments,t as toCamelCase,l as toPascalCase,w as writeFileContent}from"../shared/vite-plugin.YvjM8LxW.mjs";export{V as Validator,d as deepMerge}from"../shared/vite-plugin.B88RyRN8.mjs";import"fs";import"path";import"crypto";
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const format=require("./shared/vite-plugin.
|
|
1
|
+
"use strict";const format=require("./shared/vite-plugin.BZsetDCm.cjs"),validation=require("./shared/vite-plugin.IGZeStMa.cjs"),index=require("./shared/vite-plugin.DqWt65U-.cjs"),logger_index=require("./logger/index.cjs"),index$1=require("./shared/vite-plugin.CgnG5_UX.cjs");require("fs"),require("path"),require("crypto"),exports.checkSourceExists=format.checkSourceExists,exports.copySourceToTarget=format.copySourceToTarget,exports.ensureTargetDir=format.ensureTargetDir,exports.fileExists=format.fileExists,exports.formatDate=format.formatDate,exports.generateRandomHash=format.generateRandomHash,exports.getDateFormatParams=format.getDateFormatParams,exports.padNumber=format.padNumber,exports.parseTemplate=format.parseTemplate,exports.readDirRecursive=format.readDirRecursive,exports.readFileSync=format.readFileSync,exports.runWithConcurrency=format.runWithConcurrency,exports.shouldUpdateFile=format.shouldUpdateFile,exports.stripJsonComments=format.stripJsonComments,exports.toCamelCase=format.toCamelCase,exports.toPascalCase=format.toPascalCase,exports.writeFileContent=format.writeFileContent,exports.Validator=validation.Validator,exports.deepMerge=validation.deepMerge,exports.BasePlugin=index.BasePlugin,exports.createPluginFactory=index.createPluginFactory,exports.Logger=logger_index.Logger,exports.copyFile=index$1.copyFile,exports.generateRouter=index$1.generateRouter,exports.generateVersion=index$1.generateVersion,exports.injectIco=index$1.injectIco;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { DateFormatOptions, checkSourceExists, copySourceToTarget, deepMerge, ensureTargetDir, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, readDirRecursive, readFileSync, shouldUpdateFile, writeFileContent } from './common/index.cjs';
|
|
1
|
+
export { DateFormatOptions, checkSourceExists, copySourceToTarget, deepMerge, ensureTargetDir, fileExists, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, readDirRecursive, readFileSync, runWithConcurrency, shouldUpdateFile, stripJsonComments, toCamelCase, toPascalCase, writeFileContent } from './common/index.cjs';
|
|
2
2
|
export { V as Validator } from './shared/vite-plugin.CiHfwMiN.cjs';
|
|
3
3
|
export { BasePlugin, createPluginFactory } from './factory/index.cjs';
|
|
4
4
|
export { L as Logger, P as PluginLogger } from './shared/vite-plugin.B3PARlU9.cjs';
|
|
5
|
-
export { copyFile, generateVersion, injectIco } from './plugins/index.cjs';
|
|
5
|
+
export { copyFile, generateRouter, generateVersion, injectIco } from './plugins/index.cjs';
|
|
6
6
|
import 'vite';
|
|
7
7
|
import './shared/vite-plugin.UkE7CdSe.cjs';
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { DateFormatOptions, checkSourceExists, copySourceToTarget, deepMerge, ensureTargetDir, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, readDirRecursive, readFileSync, shouldUpdateFile, writeFileContent } from './common/index.mjs';
|
|
1
|
+
export { DateFormatOptions, checkSourceExists, copySourceToTarget, deepMerge, ensureTargetDir, fileExists, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, readDirRecursive, readFileSync, runWithConcurrency, shouldUpdateFile, stripJsonComments, toCamelCase, toPascalCase, writeFileContent } from './common/index.mjs';
|
|
2
2
|
export { V as Validator } from './shared/vite-plugin.CiHfwMiN.mjs';
|
|
3
3
|
export { BasePlugin, createPluginFactory } from './factory/index.mjs';
|
|
4
4
|
export { L as Logger, P as PluginLogger } from './shared/vite-plugin.B3PARlU9.mjs';
|
|
5
|
-
export { copyFile, generateVersion, injectIco } from './plugins/index.mjs';
|
|
5
|
+
export { copyFile, generateRouter, generateVersion, injectIco } from './plugins/index.mjs';
|
|
6
6
|
import 'vite';
|
|
7
7
|
import './shared/vite-plugin.UkE7CdSe.mjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { DateFormatOptions, checkSourceExists, copySourceToTarget, deepMerge, ensureTargetDir, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, readDirRecursive, readFileSync, shouldUpdateFile, writeFileContent } from './common/index.js';
|
|
1
|
+
export { DateFormatOptions, checkSourceExists, copySourceToTarget, deepMerge, ensureTargetDir, fileExists, formatDate, generateRandomHash, getDateFormatParams, padNumber, parseTemplate, readDirRecursive, readFileSync, runWithConcurrency, shouldUpdateFile, stripJsonComments, toCamelCase, toPascalCase, writeFileContent } from './common/index.js';
|
|
2
2
|
export { V as Validator } from './shared/vite-plugin.CiHfwMiN.js';
|
|
3
3
|
export { BasePlugin, createPluginFactory } from './factory/index.js';
|
|
4
4
|
export { L as Logger, P as PluginLogger } from './shared/vite-plugin.B3PARlU9.js';
|
|
5
|
-
export { copyFile, generateVersion, injectIco } from './plugins/index.js';
|
|
5
|
+
export { copyFile, generateRouter, generateVersion, injectIco } from './plugins/index.js';
|
|
6
6
|
import 'vite';
|
|
7
7
|
import './shared/vite-plugin.UkE7CdSe.js';
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{c as checkSourceExists,a as copySourceToTarget,e as ensureTargetDir,f as formatDate,g as generateRandomHash,
|
|
1
|
+
export{c as checkSourceExists,a as copySourceToTarget,e as ensureTargetDir,f as fileExists,b as formatDate,g as generateRandomHash,d as getDateFormatParams,p as padNumber,h as parseTemplate,r as readDirRecursive,i as readFileSync,j as runWithConcurrency,s as shouldUpdateFile,k as stripJsonComments,t as toCamelCase,l as toPascalCase,w as writeFileContent}from"./shared/vite-plugin.YvjM8LxW.mjs";export{V as Validator,d as deepMerge}from"./shared/vite-plugin.B88RyRN8.mjs";export{B as BasePlugin,c as createPluginFactory}from"./shared/vite-plugin.C7isVPKg.mjs";export{Logger}from"./logger/index.mjs";export{c as copyFile,g as generateRouter,a as generateVersion,i as injectIco}from"./shared/vite-plugin.CS9a5kjK.mjs";import"fs";import"path";import"crypto";
|
package/dist/plugins/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const index=require("../shared/vite-plugin.
|
|
1
|
+
"use strict";const index=require("../shared/vite-plugin.CgnG5_UX.cjs");require("../shared/vite-plugin.DqWt65U-.cjs"),require("../logger/index.cjs"),require("fs"),require("path"),require("crypto"),require("../shared/vite-plugin.IGZeStMa.cjs"),require("../shared/vite-plugin.BZsetDCm.cjs"),exports.copyFile=index.copyFile,exports.generateRouter=index.generateRouter,exports.generateVersion=index.generateVersion,exports.injectIco=index.injectIco;
|
package/dist/plugins/index.d.cts
CHANGED
|
@@ -72,6 +72,136 @@ interface CopyFileOptions extends BasePluginOptions {
|
|
|
72
72
|
*/
|
|
73
73
|
declare const copyFile: PluginFactory<CopyFileOptions, CopyFileOptions>;
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* 输出文件格式类型
|
|
77
|
+
*/
|
|
78
|
+
type OutputFormat = 'ts' | 'js';
|
|
79
|
+
/**
|
|
80
|
+
* 路由名称生成策略
|
|
81
|
+
*/
|
|
82
|
+
type NameStrategy = 'path' | 'camelCase' | 'pascalCase' | 'custom';
|
|
83
|
+
/**
|
|
84
|
+
* 生成路由配置插件选项
|
|
85
|
+
*/
|
|
86
|
+
interface GenerateRouterOptions extends BasePluginOptions {
|
|
87
|
+
/**
|
|
88
|
+
* pages.json 文件路径(相对于项目根目录)
|
|
89
|
+
*
|
|
90
|
+
* @default 'src/pages.json'
|
|
91
|
+
*/
|
|
92
|
+
pagesJsonPath?: string;
|
|
93
|
+
/**
|
|
94
|
+
* 输出文件路径(相对于项目根目录)
|
|
95
|
+
*
|
|
96
|
+
* @default 'src/router.config.ts'
|
|
97
|
+
*/
|
|
98
|
+
outputPath?: string;
|
|
99
|
+
/**
|
|
100
|
+
* 输出文件格式
|
|
101
|
+
*
|
|
102
|
+
* @default 'ts'
|
|
103
|
+
*/
|
|
104
|
+
outputFormat?: OutputFormat;
|
|
105
|
+
/**
|
|
106
|
+
* 路由名称生成策略
|
|
107
|
+
*
|
|
108
|
+
* @default 'camelCase'
|
|
109
|
+
*/
|
|
110
|
+
nameStrategy?: NameStrategy;
|
|
111
|
+
/**
|
|
112
|
+
* 自定义路由名称生成函数
|
|
113
|
+
*
|
|
114
|
+
* @param path - 页面路径
|
|
115
|
+
* @returns 路由名称
|
|
116
|
+
*/
|
|
117
|
+
customNameGenerator?: (path: string) => string;
|
|
118
|
+
/**
|
|
119
|
+
* 是否包含子包路由
|
|
120
|
+
*
|
|
121
|
+
* @default true
|
|
122
|
+
*/
|
|
123
|
+
includeSubPackages?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* 是否监听 pages.json 变化并自动重新生成
|
|
126
|
+
*
|
|
127
|
+
* @default true
|
|
128
|
+
*/
|
|
129
|
+
watch?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* 额外的元信息字段映射
|
|
132
|
+
*
|
|
133
|
+
* @description 将 pages.json 中 style 的字段映射到 meta 中
|
|
134
|
+
* @example { 'navigationBarTitleText': 'title', 'requireAuth': 'requireAuth' }
|
|
135
|
+
*/
|
|
136
|
+
metaMapping?: Record<string, string>;
|
|
137
|
+
/**
|
|
138
|
+
* 是否导出类型定义
|
|
139
|
+
*
|
|
140
|
+
* @default true
|
|
141
|
+
*/
|
|
142
|
+
exportTypes?: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* 是否保留用户对 routes 配置的修改
|
|
145
|
+
*
|
|
146
|
+
* @description 开启后,用户在 routes 数组中修改的字段将被保留
|
|
147
|
+
* @default true
|
|
148
|
+
*/
|
|
149
|
+
preserveRouteChanges?: boolean;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* 生成路由配置插件
|
|
154
|
+
*
|
|
155
|
+
* @param {GenerateRouterOptions} options - 插件配置选项
|
|
156
|
+
* @returns {Plugin} 一个 Vite 插件实例
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* // 基本使用 - 使用默认配置
|
|
161
|
+
* generateRouter()
|
|
162
|
+
*
|
|
163
|
+
* // 自定义 pages.json 路径
|
|
164
|
+
* generateRouter({
|
|
165
|
+
* pagesJsonPath: 'pages.json'
|
|
166
|
+
* })
|
|
167
|
+
*
|
|
168
|
+
* // 输出 JavaScript 文件
|
|
169
|
+
* generateRouter({
|
|
170
|
+
* outputFormat: 'js',
|
|
171
|
+
* outputPath: 'src/router.config.js'
|
|
172
|
+
* })
|
|
173
|
+
*
|
|
174
|
+
* // 使用帕斯卡命名策略
|
|
175
|
+
* generateRouter({
|
|
176
|
+
* nameStrategy: 'pascalCase'
|
|
177
|
+
* })
|
|
178
|
+
*
|
|
179
|
+
* // 自定义路由名称生成
|
|
180
|
+
* generateRouter({
|
|
181
|
+
* nameStrategy: 'custom',
|
|
182
|
+
* customNameGenerator: (path) => `route_${path.replace(/\//g, '_')}`
|
|
183
|
+
* })
|
|
184
|
+
*
|
|
185
|
+
* // 自定义元信息映射
|
|
186
|
+
* generateRouter({
|
|
187
|
+
* metaMapping: {
|
|
188
|
+
* navigationBarTitleText: 'title',
|
|
189
|
+
* requireAuth: 'requireAuth',
|
|
190
|
+
* customField: 'custom'
|
|
191
|
+
* }
|
|
192
|
+
* })
|
|
193
|
+
* ```
|
|
194
|
+
*
|
|
195
|
+
* @remarks
|
|
196
|
+
* 该插件会读取 uni-app 项目的 pages.json 文件,自动生成路由配置文件:
|
|
197
|
+
* - 支持主包和子包页面
|
|
198
|
+
* - 自动识别 tabBar 页面
|
|
199
|
+
* - 支持多种路由名称生成策略
|
|
200
|
+
* - 支持自定义元信息字段映射
|
|
201
|
+
* - 开发模式下自动监听 pages.json 变化并重新生成
|
|
202
|
+
*/
|
|
203
|
+
declare const generateRouter: PluginFactory<GenerateRouterOptions, GenerateRouterOptions>;
|
|
204
|
+
|
|
75
205
|
/**
|
|
76
206
|
* 版本号格式类型
|
|
77
207
|
*
|
|
@@ -372,4 +502,4 @@ interface InjectIcoOptions extends BasePluginOptions {
|
|
|
372
502
|
*/
|
|
373
503
|
declare const injectIco: PluginFactory<InjectIcoOptions, string | InjectIcoOptions>;
|
|
374
504
|
|
|
375
|
-
export { copyFile, generateVersion, injectIco };
|
|
505
|
+
export { copyFile, generateRouter, generateVersion, injectIco };
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -72,6 +72,136 @@ interface CopyFileOptions extends BasePluginOptions {
|
|
|
72
72
|
*/
|
|
73
73
|
declare const copyFile: PluginFactory<CopyFileOptions, CopyFileOptions>;
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* 输出文件格式类型
|
|
77
|
+
*/
|
|
78
|
+
type OutputFormat = 'ts' | 'js';
|
|
79
|
+
/**
|
|
80
|
+
* 路由名称生成策略
|
|
81
|
+
*/
|
|
82
|
+
type NameStrategy = 'path' | 'camelCase' | 'pascalCase' | 'custom';
|
|
83
|
+
/**
|
|
84
|
+
* 生成路由配置插件选项
|
|
85
|
+
*/
|
|
86
|
+
interface GenerateRouterOptions extends BasePluginOptions {
|
|
87
|
+
/**
|
|
88
|
+
* pages.json 文件路径(相对于项目根目录)
|
|
89
|
+
*
|
|
90
|
+
* @default 'src/pages.json'
|
|
91
|
+
*/
|
|
92
|
+
pagesJsonPath?: string;
|
|
93
|
+
/**
|
|
94
|
+
* 输出文件路径(相对于项目根目录)
|
|
95
|
+
*
|
|
96
|
+
* @default 'src/router.config.ts'
|
|
97
|
+
*/
|
|
98
|
+
outputPath?: string;
|
|
99
|
+
/**
|
|
100
|
+
* 输出文件格式
|
|
101
|
+
*
|
|
102
|
+
* @default 'ts'
|
|
103
|
+
*/
|
|
104
|
+
outputFormat?: OutputFormat;
|
|
105
|
+
/**
|
|
106
|
+
* 路由名称生成策略
|
|
107
|
+
*
|
|
108
|
+
* @default 'camelCase'
|
|
109
|
+
*/
|
|
110
|
+
nameStrategy?: NameStrategy;
|
|
111
|
+
/**
|
|
112
|
+
* 自定义路由名称生成函数
|
|
113
|
+
*
|
|
114
|
+
* @param path - 页面路径
|
|
115
|
+
* @returns 路由名称
|
|
116
|
+
*/
|
|
117
|
+
customNameGenerator?: (path: string) => string;
|
|
118
|
+
/**
|
|
119
|
+
* 是否包含子包路由
|
|
120
|
+
*
|
|
121
|
+
* @default true
|
|
122
|
+
*/
|
|
123
|
+
includeSubPackages?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* 是否监听 pages.json 变化并自动重新生成
|
|
126
|
+
*
|
|
127
|
+
* @default true
|
|
128
|
+
*/
|
|
129
|
+
watch?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* 额外的元信息字段映射
|
|
132
|
+
*
|
|
133
|
+
* @description 将 pages.json 中 style 的字段映射到 meta 中
|
|
134
|
+
* @example { 'navigationBarTitleText': 'title', 'requireAuth': 'requireAuth' }
|
|
135
|
+
*/
|
|
136
|
+
metaMapping?: Record<string, string>;
|
|
137
|
+
/**
|
|
138
|
+
* 是否导出类型定义
|
|
139
|
+
*
|
|
140
|
+
* @default true
|
|
141
|
+
*/
|
|
142
|
+
exportTypes?: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* 是否保留用户对 routes 配置的修改
|
|
145
|
+
*
|
|
146
|
+
* @description 开启后,用户在 routes 数组中修改的字段将被保留
|
|
147
|
+
* @default true
|
|
148
|
+
*/
|
|
149
|
+
preserveRouteChanges?: boolean;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* 生成路由配置插件
|
|
154
|
+
*
|
|
155
|
+
* @param {GenerateRouterOptions} options - 插件配置选项
|
|
156
|
+
* @returns {Plugin} 一个 Vite 插件实例
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* // 基本使用 - 使用默认配置
|
|
161
|
+
* generateRouter()
|
|
162
|
+
*
|
|
163
|
+
* // 自定义 pages.json 路径
|
|
164
|
+
* generateRouter({
|
|
165
|
+
* pagesJsonPath: 'pages.json'
|
|
166
|
+
* })
|
|
167
|
+
*
|
|
168
|
+
* // 输出 JavaScript 文件
|
|
169
|
+
* generateRouter({
|
|
170
|
+
* outputFormat: 'js',
|
|
171
|
+
* outputPath: 'src/router.config.js'
|
|
172
|
+
* })
|
|
173
|
+
*
|
|
174
|
+
* // 使用帕斯卡命名策略
|
|
175
|
+
* generateRouter({
|
|
176
|
+
* nameStrategy: 'pascalCase'
|
|
177
|
+
* })
|
|
178
|
+
*
|
|
179
|
+
* // 自定义路由名称生成
|
|
180
|
+
* generateRouter({
|
|
181
|
+
* nameStrategy: 'custom',
|
|
182
|
+
* customNameGenerator: (path) => `route_${path.replace(/\//g, '_')}`
|
|
183
|
+
* })
|
|
184
|
+
*
|
|
185
|
+
* // 自定义元信息映射
|
|
186
|
+
* generateRouter({
|
|
187
|
+
* metaMapping: {
|
|
188
|
+
* navigationBarTitleText: 'title',
|
|
189
|
+
* requireAuth: 'requireAuth',
|
|
190
|
+
* customField: 'custom'
|
|
191
|
+
* }
|
|
192
|
+
* })
|
|
193
|
+
* ```
|
|
194
|
+
*
|
|
195
|
+
* @remarks
|
|
196
|
+
* 该插件会读取 uni-app 项目的 pages.json 文件,自动生成路由配置文件:
|
|
197
|
+
* - 支持主包和子包页面
|
|
198
|
+
* - 自动识别 tabBar 页面
|
|
199
|
+
* - 支持多种路由名称生成策略
|
|
200
|
+
* - 支持自定义元信息字段映射
|
|
201
|
+
* - 开发模式下自动监听 pages.json 变化并重新生成
|
|
202
|
+
*/
|
|
203
|
+
declare const generateRouter: PluginFactory<GenerateRouterOptions, GenerateRouterOptions>;
|
|
204
|
+
|
|
75
205
|
/**
|
|
76
206
|
* 版本号格式类型
|
|
77
207
|
*
|
|
@@ -372,4 +502,4 @@ interface InjectIcoOptions extends BasePluginOptions {
|
|
|
372
502
|
*/
|
|
373
503
|
declare const injectIco: PluginFactory<InjectIcoOptions, string | InjectIcoOptions>;
|
|
374
504
|
|
|
375
|
-
export { copyFile, generateVersion, injectIco };
|
|
505
|
+
export { copyFile, generateRouter, generateVersion, injectIco };
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -72,6 +72,136 @@ interface CopyFileOptions extends BasePluginOptions {
|
|
|
72
72
|
*/
|
|
73
73
|
declare const copyFile: PluginFactory<CopyFileOptions, CopyFileOptions>;
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* 输出文件格式类型
|
|
77
|
+
*/
|
|
78
|
+
type OutputFormat = 'ts' | 'js';
|
|
79
|
+
/**
|
|
80
|
+
* 路由名称生成策略
|
|
81
|
+
*/
|
|
82
|
+
type NameStrategy = 'path' | 'camelCase' | 'pascalCase' | 'custom';
|
|
83
|
+
/**
|
|
84
|
+
* 生成路由配置插件选项
|
|
85
|
+
*/
|
|
86
|
+
interface GenerateRouterOptions extends BasePluginOptions {
|
|
87
|
+
/**
|
|
88
|
+
* pages.json 文件路径(相对于项目根目录)
|
|
89
|
+
*
|
|
90
|
+
* @default 'src/pages.json'
|
|
91
|
+
*/
|
|
92
|
+
pagesJsonPath?: string;
|
|
93
|
+
/**
|
|
94
|
+
* 输出文件路径(相对于项目根目录)
|
|
95
|
+
*
|
|
96
|
+
* @default 'src/router.config.ts'
|
|
97
|
+
*/
|
|
98
|
+
outputPath?: string;
|
|
99
|
+
/**
|
|
100
|
+
* 输出文件格式
|
|
101
|
+
*
|
|
102
|
+
* @default 'ts'
|
|
103
|
+
*/
|
|
104
|
+
outputFormat?: OutputFormat;
|
|
105
|
+
/**
|
|
106
|
+
* 路由名称生成策略
|
|
107
|
+
*
|
|
108
|
+
* @default 'camelCase'
|
|
109
|
+
*/
|
|
110
|
+
nameStrategy?: NameStrategy;
|
|
111
|
+
/**
|
|
112
|
+
* 自定义路由名称生成函数
|
|
113
|
+
*
|
|
114
|
+
* @param path - 页面路径
|
|
115
|
+
* @returns 路由名称
|
|
116
|
+
*/
|
|
117
|
+
customNameGenerator?: (path: string) => string;
|
|
118
|
+
/**
|
|
119
|
+
* 是否包含子包路由
|
|
120
|
+
*
|
|
121
|
+
* @default true
|
|
122
|
+
*/
|
|
123
|
+
includeSubPackages?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* 是否监听 pages.json 变化并自动重新生成
|
|
126
|
+
*
|
|
127
|
+
* @default true
|
|
128
|
+
*/
|
|
129
|
+
watch?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* 额外的元信息字段映射
|
|
132
|
+
*
|
|
133
|
+
* @description 将 pages.json 中 style 的字段映射到 meta 中
|
|
134
|
+
* @example { 'navigationBarTitleText': 'title', 'requireAuth': 'requireAuth' }
|
|
135
|
+
*/
|
|
136
|
+
metaMapping?: Record<string, string>;
|
|
137
|
+
/**
|
|
138
|
+
* 是否导出类型定义
|
|
139
|
+
*
|
|
140
|
+
* @default true
|
|
141
|
+
*/
|
|
142
|
+
exportTypes?: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* 是否保留用户对 routes 配置的修改
|
|
145
|
+
*
|
|
146
|
+
* @description 开启后,用户在 routes 数组中修改的字段将被保留
|
|
147
|
+
* @default true
|
|
148
|
+
*/
|
|
149
|
+
preserveRouteChanges?: boolean;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* 生成路由配置插件
|
|
154
|
+
*
|
|
155
|
+
* @param {GenerateRouterOptions} options - 插件配置选项
|
|
156
|
+
* @returns {Plugin} 一个 Vite 插件实例
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* // 基本使用 - 使用默认配置
|
|
161
|
+
* generateRouter()
|
|
162
|
+
*
|
|
163
|
+
* // 自定义 pages.json 路径
|
|
164
|
+
* generateRouter({
|
|
165
|
+
* pagesJsonPath: 'pages.json'
|
|
166
|
+
* })
|
|
167
|
+
*
|
|
168
|
+
* // 输出 JavaScript 文件
|
|
169
|
+
* generateRouter({
|
|
170
|
+
* outputFormat: 'js',
|
|
171
|
+
* outputPath: 'src/router.config.js'
|
|
172
|
+
* })
|
|
173
|
+
*
|
|
174
|
+
* // 使用帕斯卡命名策略
|
|
175
|
+
* generateRouter({
|
|
176
|
+
* nameStrategy: 'pascalCase'
|
|
177
|
+
* })
|
|
178
|
+
*
|
|
179
|
+
* // 自定义路由名称生成
|
|
180
|
+
* generateRouter({
|
|
181
|
+
* nameStrategy: 'custom',
|
|
182
|
+
* customNameGenerator: (path) => `route_${path.replace(/\//g, '_')}`
|
|
183
|
+
* })
|
|
184
|
+
*
|
|
185
|
+
* // 自定义元信息映射
|
|
186
|
+
* generateRouter({
|
|
187
|
+
* metaMapping: {
|
|
188
|
+
* navigationBarTitleText: 'title',
|
|
189
|
+
* requireAuth: 'requireAuth',
|
|
190
|
+
* customField: 'custom'
|
|
191
|
+
* }
|
|
192
|
+
* })
|
|
193
|
+
* ```
|
|
194
|
+
*
|
|
195
|
+
* @remarks
|
|
196
|
+
* 该插件会读取 uni-app 项目的 pages.json 文件,自动生成路由配置文件:
|
|
197
|
+
* - 支持主包和子包页面
|
|
198
|
+
* - 自动识别 tabBar 页面
|
|
199
|
+
* - 支持多种路由名称生成策略
|
|
200
|
+
* - 支持自定义元信息字段映射
|
|
201
|
+
* - 开发模式下自动监听 pages.json 变化并重新生成
|
|
202
|
+
*/
|
|
203
|
+
declare const generateRouter: PluginFactory<GenerateRouterOptions, GenerateRouterOptions>;
|
|
204
|
+
|
|
75
205
|
/**
|
|
76
206
|
* 版本号格式类型
|
|
77
207
|
*
|
|
@@ -372,4 +502,4 @@ interface InjectIcoOptions extends BasePluginOptions {
|
|
|
372
502
|
*/
|
|
373
503
|
declare const injectIco: PluginFactory<InjectIcoOptions, string | InjectIcoOptions>;
|
|
374
504
|
|
|
375
|
-
export { copyFile, generateVersion, injectIco };
|
|
505
|
+
export { copyFile, generateRouter, generateVersion, injectIco };
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{c as copyFile,g as generateVersion,i as injectIco}from"../shared/vite-plugin.
|
|
1
|
+
export{c as copyFile,g as generateRouter,a as generateVersion,i as injectIco}from"../shared/vite-plugin.CS9a5kjK.mjs";import"../shared/vite-plugin.C7isVPKg.mjs";import"../logger/index.mjs";import"fs";import"path";import"crypto";import"../shared/vite-plugin.B88RyRN8.mjs";import"../shared/vite-plugin.YvjM8LxW.mjs";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const o=require("fs"),u=require("path"),crypto=require("crypto");function _interopDefaultCompat(e){return e&&typeof e=="object"&&"default"in e?e.default:e}const o__default=_interopDefaultCompat(o),u__default=_interopDefaultCompat(u),g=10;async function checkSourceExists(e){try{await o__default.promises.access(e,o__default.constants.F_OK)}catch(t){const r=t;throw r.code==="ENOENT"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728 - ${e}`):r.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u6E90\u6587\u4EF6 - ${e}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u68C0\u67E5\u6E90\u6587\u4EF6\u65F6\u51FA\u9519 - ${e}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}async function ensureTargetDir(e){try{await o__default.promises.mkdir(e,{recursive:!0})}catch(t){const r=t;throw r.code==="EACCES"?new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u521B\u5EFA\u76EE\u6807\u76EE\u5F55 - ${e}`):new Error(`\u590D\u5236\u6587\u4EF6\u5931\u8D25\uFF1A\u521B\u5EFA\u76EE\u6807\u76EE\u5F55\u65F6\u51FA\u9519 - ${e}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}async function readDirRecursive(e,t){const r=await o__default.promises.readdir(e,{withFileTypes:!0}),s=[];for(const n of r){const i=u__default.join(e,n.name),l=n.isFile(),F=n.isDirectory();if(s.push({path:i,isFile:l,isDirectory:F}),F&&t){const p=await readDirRecursive(i,t);s.push(...p)}}return s}async function shouldUpdateFile(e,t){try{const[r,s]=await Promise.all([o__default.promises.stat(e),o__default.promises.stat(t)]);return r.mtimeMs>s.mtimeMs||r.size!==s.size}catch{return!0}}async function fileExists(e){try{return await o__default.promises.access(e,o__default.constants.F_OK),!0}catch{return!1}}async function runWithConcurrency(e,t,r){const s=[];let n=0;async function i(){for(;n<e.length;){const F=n++,p=await t(e[F]);s[F]=p}}const l=Array(Math.min(r,e.length)).fill(null).map(()=>i());return await Promise.all(l),s}async function copySourceToTarget(e,t,r){const s=Date.now(),{recursive:n,overwrite:i,incremental:l=!1,parallelLimit:F=g}=r;let p=0,f=0,d=0;if((await o__default.promises.stat(e)).isDirectory()){await ensureTargetDir(t);const c=await readDirRecursive(e,n),D=c.filter(a=>a.isFile);d=c.filter(a=>a.isDirectory).length;const h=new Set;for(const a of D){const w=u__default.relative(e,a.path),m=u__default.dirname(u__default.join(t,w));h.add(m)}await Promise.all([...h].map(a=>ensureTargetDir(a)));const C=await runWithConcurrency(D,async a=>{const w=u__default.relative(e,a.path),m=u__default.join(t,w);let E=i;return E||(E=!await fileExists(m)),l&&E&&(E=await shouldUpdateFile(a.path,m)),E?(await o__default.promises.copyFile(a.path,m),{copied:!0,skipped:!1}):{copied:!1,skipped:!0}},F);for(const a of C)a.copied&&p++,a.skipped&&f++}else{await ensureTargetDir(u__default.dirname(t));let c=i;c||(c=!await fileExists(t)),l&&c&&(c=await shouldUpdateFile(e,t)),c?(await o__default.promises.copyFile(e,t),p++):f++}const y=Date.now()-s;return{copiedFiles:p,skippedFiles:f,copiedDirs:d,executionTime:y}}async function writeFileContent(e,t){try{await o__default.promises.writeFile(e,t,"utf-8")}catch(r){const s=r;throw s.code==="EACCES"?new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u5199\u5165\u6587\u4EF6 - ${e}`):new Error(`\u5199\u5165\u6587\u4EF6\u5931\u8D25\uFF1A\u5199\u5165\u6587\u4EF6\u65F6\u51FA\u9519 - ${e}\uFF0C\u9519\u8BEF\uFF1A${s.message}`)}}function readFileSync(e){try{return o__default.readFileSync(e,"utf-8")}catch(t){const r=t;throw r.code==="EACCES"?new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u6CA1\u6709\u6743\u9650\u8BFB\u53D6\u6587\u4EF6 - ${e}`):new Error(`\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25\uFF1A\u8BFB\u53D6\u6587\u4EF6\u65F6\u51FA\u9519 - ${e}\uFF0C\u9519\u8BEF\uFF1A${r.message}`)}}function padNumber(e,t=2){return e.toString().padStart(t,"0")}function generateRandomHash(e=8){const t=Math.max(1,Math.min(64,e));return crypto.randomBytes(Math.ceil(t/2)).toString("hex").slice(0,t)}function getDateFormatParams(e=new Date){return{YYYY:e.getFullYear().toString(),YY:e.getFullYear().toString().slice(-2),MM:padNumber(e.getMonth()+1),DD:padNumber(e.getDate()),HH:padNumber(e.getHours()),mm:padNumber(e.getMinutes()),ss:padNumber(e.getSeconds()),SSS:padNumber(e.getMilliseconds(),3),timestamp:e.getTime().toString()}}function formatDate(e,t){const r=getDateFormatParams(e);let s=t;for(const[n,i]of Object.entries(r))s=s.replace(new RegExp(`\\{${n}\\}`,"g"),i);return s}function parseTemplate(e,t){let r=e;for(const[s,n]of Object.entries(t))r=r.replace(new RegExp(`\\{${s}\\}`,"g"),n);return r}function toCamelCase(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map((r,s)=>s===0?r.toLowerCase():r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function toPascalCase(e,t=/[/-]/){return e.replace(/^\/+/,"").split(t).filter(Boolean).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function stripJsonComments(e){return e.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"")}exports.checkSourceExists=checkSourceExists,exports.copySourceToTarget=copySourceToTarget,exports.ensureTargetDir=ensureTargetDir,exports.fileExists=fileExists,exports.formatDate=formatDate,exports.generateRandomHash=generateRandomHash,exports.getDateFormatParams=getDateFormatParams,exports.padNumber=padNumber,exports.parseTemplate=parseTemplate,exports.readDirRecursive=readDirRecursive,exports.readFileSync=readFileSync,exports.runWithConcurrency=runWithConcurrency,exports.shouldUpdateFile=shouldUpdateFile,exports.stripJsonComments=stripJsonComments,exports.toCamelCase=toCamelCase,exports.toPascalCase=toPascalCase,exports.writeFileContent=writeFileContent;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import{c as n,B as c}from"./vite-plugin.C7isVPKg.mjs";import{c as p,a as g,t as F,l as d,i as m,k as E,w as f,d as D,g as C,h as v}from"./vite-plugin.YvjM8LxW.mjs";import"crypto";import{resolve as h,join as y}from"path";import{existsSync as l,watch as b}from"fs";import{V as $}from"./vite-plugin.B88RyRN8.mjs";class w extends c{getDefaultOptions(){return{overwrite:!0,recursive:!0,incremental:!0}}validateOptions(){this.validator.field("sourceDir").required().string().custom(e=>e.trim()!=="","sourceDir \u4E0D\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32").field("targetDir").required().string().custom(e=>e.trim()!=="","targetDir \u4E0D\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32").field("overwrite").boolean().field("recursive").boolean().field("incremental").boolean().validate()}getPluginName(){return"copy-file"}getEnforce(){return"post"}async copyFiles(){const{sourceDir:e,targetDir:t,overwrite:s=!0,recursive:u=!0,incremental:i=!0,enabled:o=!0}=this.options;if(!o){this.logger.info(`\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u6267\u884C\uFF1A\u4ECE ${e} \u590D\u5236\u5230 ${t}`);return}await p(e);const a=await g(e,t,{recursive:u,overwrite:s,incremental:i});this.logger.success(`\u590D\u5236\u6587\u4EF6\u6210\u529F\uFF1A\u4ECE ${e} \u5230 ${t}`,`\u590D\u5236\u4E86 ${a.copiedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u4E86 ${a.skippedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8017\u65F6 ${a.executionTime}ms`)}addPluginHooks(e){e.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u590D\u5236\u6587\u4EF6")}}}const B=n(w);class T extends c{projectRoot=process.cwd();tabBarPages=new Set;watcher=null;getDefaultOptions(){return{pagesJsonPath:"src/pages.json",outputPath:"src/router.config.ts",outputFormat:"ts",nameStrategy:"camelCase",includeSubPackages:!0,watch:!0,exportTypes:!0,preserveRouteChanges:!0,metaMapping:{navigationBarTitleText:"title",requireAuth:"requireAuth"}}}validateOptions(){if(this.validator.field("pagesJsonPath").string().field("outputPath").string().field("outputFormat").custom(e=>!e||["ts","js"].includes(e),"outputFormat \u5FC5\u987B\u662F ts \u6216 js").field("nameStrategy").custom(e=>!e||["path","camelCase","pascalCase","custom"].includes(e),"nameStrategy \u5FC5\u987B\u662F path, camelCase, pascalCase \u6216 custom").validate(),this.options.nameStrategy==="custom"&&!this.options.customNameGenerator)throw new Error("\u5F53 nameStrategy \u4E3A custom \u65F6\uFF0C\u5FC5\u987B\u63D0\u4F9B customNameGenerator")}getPluginName(){return"generate-router"}generateRouteName(e){switch(this.options.nameStrategy){case"path":return e.replace(/\//g,"_").replace(/^_/,"");case"camelCase":return F(e);case"pascalCase":return d(e);case"custom":return this.options.customNameGenerator(e);default:return F(e)}}extractMeta(e,t){const s={},u=e.style||{},i=this.options.metaMapping||{};for(const[o,a]of Object.entries(i))u[o]!==void 0&&(s[a]=u[o]);return this.tabBarPages.has(t)&&(s.isTab=!0),s}parsePageToRoute(e,t=""){const s=t?`/${t}/${e.path}`:`/${e.path}`,u=this.generateRouteName(s),i=this.extractMeta(e,s.replace(/^\//,"")),o={path:s,name:u};return Object.keys(i).length>0&&(o.meta=i),o}parsePagesJson(e){const t=[];if(!e.pages||!Array.isArray(e.pages)||e.pages.length===0)return this.logger.warn("pages.json \u4E2D\u6CA1\u6709\u6709\u6548\u7684\u9875\u9762\u914D\u7F6E"),t;if(this.tabBarPages.clear(),e.tabBar?.list)for(const s of e.tabBar.list)this.tabBarPages.add(s.pagePath);for(const s of e.pages)t.push(this.parsePageToRoute(s));if(this.options.includeSubPackages&&e.subPackages){for(const s of e.subPackages)if(s.pages&&Array.isArray(s.pages))for(const u of s.pages)t.push(this.parsePageToRoute(u,s.root))}return t}generateTypeDefinitions(){return!this.options.exportTypes||this.options.outputFormat==="js"?"":`
|
|
2
|
+
/**
|
|
3
|
+
* \u8DEF\u7531\u5143\u4FE1\u606F
|
|
4
|
+
*/
|
|
5
|
+
export interface RouteMeta {
|
|
6
|
+
/** \u9875\u9762\u6807\u9898 */
|
|
7
|
+
title?: string
|
|
8
|
+
/** \u662F\u5426\u4E3ATabBar\u9875\u9762 */
|
|
9
|
+
isTab?: boolean
|
|
10
|
+
/** \u662F\u5426\u9700\u8981\u767B\u5F55 */
|
|
11
|
+
requireAuth?: boolean
|
|
12
|
+
/** \u81EA\u5B9A\u4E49\u6269\u5C55\u5B57\u6BB5 */
|
|
13
|
+
[key: string]: unknown
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* \u8DEF\u7531\u914D\u7F6E\u9879
|
|
18
|
+
*/
|
|
19
|
+
export interface RouteConfig {
|
|
20
|
+
/** \u8DEF\u7531\u8DEF\u5F84 */
|
|
21
|
+
path: string
|
|
22
|
+
/** \u8DEF\u7531\u540D\u79F0\uFF08\u7528\u4E8E\u547D\u540D\u8DEF\u7531\u5BFC\u822A\uFF09 */
|
|
23
|
+
name?: string
|
|
24
|
+
/** \u8DEF\u7531\u5143\u4FE1\u606F */
|
|
25
|
+
meta?: RouteMeta
|
|
26
|
+
}
|
|
27
|
+
`}generateFileContent(e){const t=this.generateTypeDefinitions(),s=this.options.outputFormat==="ts",u=JSON.stringify(e,null," ").replace(/"(\w+)":/g,"$1:").replace(/: "([^"]+)"/g,": '$1'");return`${t}
|
|
28
|
+
/**
|
|
29
|
+
* \u8DEF\u7531\u914D\u7F6E\u5217\u8868
|
|
30
|
+
* @description \u7531 pages.json \u81EA\u52A8\u751F\u6210
|
|
31
|
+
*/
|
|
32
|
+
export const routes${s?": RouteConfig[]":""} = ${u}
|
|
33
|
+
|
|
34
|
+
export default routes
|
|
35
|
+
`}readPagesJson(){const e=h(this.projectRoot,this.options.pagesJsonPath);if(!l(e))return this.logger.warn(`pages.json \u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`),null;try{const t=m(e),s=E(t);return JSON.parse(s)}catch(t){return this.logger.error(`\u89E3\u6790 pages.json \u5931\u8D25: ${t.message}`),null}}extractExistingRoutes(e){const t=new Map,s=e.match(/export const routes[^=]*=\s*(\[[\s\S]*?\](?=\s*\n|\s*$|\s*\/\/))/);if(!s)return t;try{let u=s[1].replace(/(\w+)(?=\s*:)/g,'"$1"').replace(/'([^']*)'/g,'"$1"').replace(/,\s*([\]\}])/g,"$1");const i=JSON.parse(u);for(const o of i)o.path&&t.set(o.path,o)}catch{this.logger.warn("\u89E3\u6790\u73B0\u6709 routes \u914D\u7F6E\u5931\u8D25\uFF0C\u5C06\u5B8C\u5168\u91CD\u65B0\u751F\u6210")}return t}mergeRoutes(e,t){return e.map(s=>{const u=t.get(s.path);if(!u)return s;const i={};return s.meta&&Object.assign(i,s.meta),u.meta&&Object.assign(i,u.meta),{...u,path:s.path,meta:Object.keys(i).length>0?i:void 0}})}async generateRouterConfig(){const e=this.readPagesJson();if(!e)return;let t=this.parsePagesJson(e);const s=h(this.projectRoot,this.options.outputPath);if(this.options.preserveRouteChanges&&l(s))try{const i=m(s),o=this.extractExistingRoutes(i);o.size>0&&(t=this.mergeRoutes(t,o),this.logger.info("\u5DF2\u5408\u5E76\u7528\u6237\u5BF9\u8DEF\u7531\u914D\u7F6E\u7684\u4FEE\u6539"))}catch{}const u=this.generateFileContent(t);await f(s,u),this.logger.success(`\u8DEF\u7531\u914D\u7F6E\u6587\u4EF6\u5DF2\u751F\u6210: ${s}`),this.logger.info(`\u5171\u751F\u6210 ${t.length} \u6761\u8DEF\u7531\u914D\u7F6E`)}startWatching(){if(!this.options.watch)return;const e=h(this.projectRoot,this.options.pagesJsonPath);l(e)&&(this.watcher=b(e,async t=>{t==="change"&&(this.logger.info("\u68C0\u6D4B\u5230 pages.json \u53D8\u5316\uFF0C\u91CD\u65B0\u751F\u6210\u8DEF\u7531\u914D\u7F6E..."),await this.safeExecute(()=>this.generateRouterConfig(),"\u91CD\u65B0\u751F\u6210\u8DEF\u7531\u914D\u7F6E"))}),this.logger.info(`\u6B63\u5728\u76D1\u542C pages.json \u53D8\u5316: ${e}`))}stopWatching(){this.watcher&&(this.watcher.close(),this.watcher=null)}addPluginHooks(e){e.configResolved=async t=>{this.options.enabled&&(this.projectRoot=t.root,await this.safeExecute(()=>this.generateRouterConfig(),"\u751F\u6210\u8DEF\u7531\u914D\u7F6E"),t.command==="serve"&&this.startWatching())},e.buildEnd=()=>{this.stopWatching()}}}const P=n(T);let x=class extends c{version="";buildTime=new Date;getDefaultOptions(){return{format:"timestamp",semverBase:"1.0.0",autoIncrement:!1,outputType:"file",outputFile:"version.json",defineName:"__APP_VERSION__",hashLength:8,prefix:"",suffix:""}}validateOptions(){if(this.validator.field("format").custom(e=>!e||["timestamp","date","datetime","semver","hash","custom"].includes(e),"format \u5FC5\u987B\u662F timestamp, date, datetime, semver, hash \u6216 custom").field("outputType").custom(e=>!e||["file","define","both"].includes(e),"outputType \u5FC5\u987B\u662F file, define \u6216 both").field("hashLength").number().custom(e=>!e||e>0&&e<=32,"hashLength \u5FC5\u987B\u5728 1-32 \u4E4B\u95F4").validate(),this.options.format==="custom"&&!this.options.customFormat)throw new Error("\u5F53 format \u4E3A custom \u65F6\uFF0C\u5FC5\u987B\u63D0\u4F9B customFormat")}getPluginName(){return"generate-version"}generateVersion(){const e=D(this.buildTime),t=C(this.options.hashLength);let s;switch(this.options.format){case"timestamp":s=`${e.YYYY}${e.MM}${e.DD}${e.HH}${e.mm}${e.ss}`;break;case"date":s=`${e.YYYY}.${e.MM}.${e.DD}`;break;case"datetime":s=`${e.YYYY}.${e.MM}.${e.DD}.${e.HH}${e.mm}${e.ss}`;break;case"semver":s=this.options.semverBase||"1.0.0";break;case"hash":s=t;break;case"custom":s=this.parseCustomFormat({...e,hash:t});break;default:s=e.timestamp}const u=this.options.prefix||"",i=this.options.suffix||"";return`${u}${s}${i}`}parseCustomFormat(e){const t={...e};if(this.options.semverBase){const[s,u,i]=this.options.semverBase.split(".");t.major=s||"1",t.minor=u||"0",t.patch=i||"0"}return v(this.options.customFormat||"",t)}generateVersionInfo(){return{version:this.version,buildTime:this.buildTime.toISOString(),timestamp:this.buildTime.getTime(),format:this.options.format,...this.options.extra}}async writeVersionFile(e){const t=y(e,this.options.outputFile||"version.json"),s=this.generateVersionInfo();await f(t,JSON.stringify(s,null,2)),this.logger.success(`\u7248\u672C\u6587\u4EF6\u5DF2\u751F\u6210: ${t}`)}addPluginHooks(e){const t=e.configResolved;e.configResolved=s=>{this.options.enabled&&(this.buildTime=new Date,this.version=this.generateVersion(),this.logger.info(`\u751F\u6210\u7248\u672C\u53F7: ${this.version}`)),typeof t=="function"&&t(s)},(this.options.outputType==="define"||this.options.outputType==="both")&&(e.config=()=>{if(!this.options.enabled)return{};this.version||(this.buildTime=new Date,this.version=this.generateVersion());const s=this.options.defineName||"__APP_VERSION__";return this.logger.info(`\u6CE8\u5165\u5168\u5C40\u53D8\u91CF: ${s} = "${this.version}"`),{define:{[s]:JSON.stringify(this.version),[`${s}_INFO`]:JSON.stringify(this.generateVersionInfo())}}}),(this.options.outputType==="file"||this.options.outputType==="both")&&(e.writeBundle=async()=>{!this.options.enabled||!this.viteConfig||await this.safeExecute(async()=>{const s=this.viteConfig.build.outDir;await this.writeVersionFile(s)},"\u5199\u5165\u7248\u672C\u6587\u4EF6")})}};const A=n(x);function j(r){const e=[];if(r.link)return[];if(r.icons&&r.icons.length>0)for(const t of r.icons){const s={rel:t.rel,href:t.href};t.sizes&&(s.sizes=t.sizes),t.type&&(s.type=t.type),e.push({tag:"link",attrs:s,injectTo:"head"})}else if(r.url)e.push({tag:"link",attrs:{rel:"icon",href:r.url},injectTo:"head"});else{const t=r.base||"/",s=t.endsWith("/")?`${t}favicon.ico`:`${t}/favicon.ico`;e.push({tag:"link",attrs:{rel:"icon",href:s},injectTo:"head"})}return e}class k extends c{getDefaultOptions(){return{base:"/"}}validateOptions(){this.validator.field("base").string().field("url").string().field("link").string().field("icons").array(),this.options?.copyOptions&&(this.validator.field("copyOptions").object(),new $(this.options.copyOptions).field("sourceDir").required().string().field("targetDir").required().string().field("overwrite").boolean().field("recursive").boolean().validate()),this.validator.validate()}getPluginName(){return"inject-ico"}getIconTagDescriptors(){if(!this.options.enabled)return this.logger.info("\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165"),[];const e=j(this.options);return e.length>0&&this.logger.success(`\u6210\u529F\u6CE8\u5165 ${e.length} \u4E2A\u56FE\u6807\u6807\u7B7E\u5230 HTML \u6587\u4EF6`),e}injectCustomLinkTag(e){if(!this.options.enabled||!this.options.link)return e;const t=this.options.link,s=/<\/head>/i,u=e.match(s);if(u&&u.index!==void 0){const i=e.slice(0,u.index)+t+`
|
|
36
|
+
`+e.slice(u.index);return this.logger.success("\u6210\u529F\u6CE8\u5165\u81EA\u5B9A\u4E49\u56FE\u6807\u6807\u7B7E\u5230 HTML \u6587\u4EF6"),this.logger.info(` - ${t}`),i}return this.logger.warn("\u672A\u627E\u5230 </head> \u6807\u7B7E\uFF0C\u8DF3\u8FC7\u56FE\u6807\u6CE8\u5165"),e}async copyFiles(){if(!this.options.enabled){this.logger.info("\u63D2\u4EF6\u5DF2\u7981\u7528\uFF0C\u8DF3\u8FC7\u6587\u4EF6\u590D\u5236");return}const{copyOptions:e}=this.options;if(!e)return;const{sourceDir:t,targetDir:s,overwrite:u=!0,recursive:i=!0}=e;await p(t);const o=await g(t,s,{recursive:i,overwrite:u,incremental:!0});this.logger.success(`\u56FE\u6807\u6587\u4EF6\u590D\u5236\u6210\u529F\uFF1A\u4ECE ${t} \u5230 ${s}`,`\u590D\u5236\u4E86 ${o.copiedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u4E86 ${o.skippedFiles} \u4E2A\u6587\u4EF6\uFF0C\u8017\u65F6 ${o.executionTime}ms`)}addPluginHooks(e){e.transformIndexHtml={order:"pre",handler:t=>{if(this.options.link)return this.injectCustomLinkTag(t);const s=this.getIconTagDescriptors();return s.length>0?{html:t,tags:s}:t}},e.writeBundle=async()=>{await this.safeExecute(()=>this.copyFiles(),"\u56FE\u6807\u6587\u4EF6\u590D\u5236")}}}const R=n(k,r=>typeof r=="string"?{base:r}:r||{});export{A as a,B as c,P as g,R as i};
|