@vureact/compiler-core 1.2.1 → 1.4.0
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.md +1 -1
- package/README.zh.md +1 -1
- package/lib/{chunk-SQRJUILR.js → chunk-IVRFEV6H.js} +1411 -1249
- package/lib/{chunk-7FIMRVQS.esm.js → chunk-NF5BSPYE.esm.js} +1352 -1190
- package/lib/cli.d.cts +1 -2
- package/lib/cli.d.ts +1 -2
- package/lib/cli.esm.js +104 -47
- package/lib/cli.js +106 -49
- package/lib/compiler-core.d.cts +1117 -1179
- package/lib/compiler-core.d.ts +1117 -1179
- package/lib/compiler-core.esm.js +2 -2
- package/lib/compiler-core.js +3 -3
- package/package.json +99 -83
package/lib/compiler-core.d.cts
CHANGED
|
@@ -1,11 +1,150 @@
|
|
|
1
1
|
import { GeneratorOptions as GeneratorOptions$1 } from '@babel/generator';
|
|
2
|
+
import { ParseResult as ParseResult$1 } from '@babel/parser';
|
|
2
3
|
import * as t from '@babel/types';
|
|
3
4
|
import { Expression, ArrayExpression, JSXIdentifier } from '@babel/types';
|
|
4
|
-
import { ParseResult as ParseResult$1 } from '@babel/parser';
|
|
5
5
|
import { RootNode, SourceLocation } from '@vue/compiler-core';
|
|
6
6
|
import { SFCTemplateBlock, SFCScriptBlock, SFCStyleBlock } from '@vue/compiler-sfc';
|
|
7
7
|
import { Options } from 'prettier';
|
|
8
8
|
|
|
9
|
+
interface FileLockOptions {
|
|
10
|
+
/**
|
|
11
|
+
* 锁过期时间(毫秒)
|
|
12
|
+
* 默认: 10000 (10秒)
|
|
13
|
+
*/
|
|
14
|
+
stale?: number;
|
|
15
|
+
/**
|
|
16
|
+
* 锁更新间隔(毫秒)
|
|
17
|
+
* 默认: stale / 2
|
|
18
|
+
*/
|
|
19
|
+
update?: number;
|
|
20
|
+
/**
|
|
21
|
+
* 重试配置
|
|
22
|
+
* 可以是重试次数或 retry 选项对象
|
|
23
|
+
* 默认: 5
|
|
24
|
+
*/
|
|
25
|
+
retries?: number | {
|
|
26
|
+
retries?: number;
|
|
27
|
+
factor?: number;
|
|
28
|
+
minTimeout?: number;
|
|
29
|
+
maxTimeout?: number;
|
|
30
|
+
randomize?: boolean;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* 是否解析符号链接
|
|
34
|
+
* 默认: true
|
|
35
|
+
*/
|
|
36
|
+
realpath?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* 自定义锁文件路径
|
|
39
|
+
* 默认: `${filePath}.lock`
|
|
40
|
+
*/
|
|
41
|
+
lockfilePath?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type CompilationUnit = SFCUnit | ScriptUnit | StyleUnit;
|
|
45
|
+
interface SFCUnit extends BaseUnit {
|
|
46
|
+
type: CacheKey.SFC;
|
|
47
|
+
output?: {
|
|
48
|
+
jsx: OutputItem;
|
|
49
|
+
css: Partial<OutputItem>;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
interface ScriptUnit extends BaseUnit {
|
|
53
|
+
type: CacheKey.SCRIPT;
|
|
54
|
+
output?: {
|
|
55
|
+
script: OutputItem;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
interface StyleUnit extends Omit<BaseUnit, 'hasRoute'> {
|
|
59
|
+
type: CacheKey.STYLE;
|
|
60
|
+
output?: {
|
|
61
|
+
style: OutputItem;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
interface AssetUnit extends Omit<BaseUnit, 'fileId' | 'source' | 'hasRoute'> {
|
|
65
|
+
type: CacheKey.ASSET;
|
|
66
|
+
}
|
|
67
|
+
interface BaseUnit extends FileMeta {
|
|
68
|
+
file: string;
|
|
69
|
+
fileId: string;
|
|
70
|
+
source: string;
|
|
71
|
+
hasRoute?: boolean;
|
|
72
|
+
}
|
|
73
|
+
interface OutputItem {
|
|
74
|
+
file: string;
|
|
75
|
+
code: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
type LoadedCache<T = CacheMeta> = {
|
|
79
|
+
key: CacheKey;
|
|
80
|
+
target: T[];
|
|
81
|
+
source: CacheList;
|
|
82
|
+
};
|
|
83
|
+
type CacheMeta = Vue2ReactCacheMeta | FileCacheMeta;
|
|
84
|
+
declare enum CacheKey {
|
|
85
|
+
SFC = "sfc",
|
|
86
|
+
SCRIPT = "script",
|
|
87
|
+
STYLE = "style",
|
|
88
|
+
ASSET = "copied"
|
|
89
|
+
}
|
|
90
|
+
interface CacheList {
|
|
91
|
+
[CacheKey.SFC]: Vue2ReactCacheMeta[];
|
|
92
|
+
[CacheKey.SCRIPT]: ScriptCacheMeta[];
|
|
93
|
+
[CacheKey.STYLE]: StyleCacheMeta[];
|
|
94
|
+
[CacheKey.ASSET]: FileCacheMeta[];
|
|
95
|
+
}
|
|
96
|
+
type Vue2ReactCacheMeta = Omit<SFCUnit, 'source'>;
|
|
97
|
+
type ScriptCacheMeta = Omit<ScriptUnit, 'source'>;
|
|
98
|
+
type StyleCacheMeta = Omit<StyleUnit, 'source'>;
|
|
99
|
+
interface FileCacheMeta extends FileMeta {
|
|
100
|
+
file: string;
|
|
101
|
+
}
|
|
102
|
+
interface FileMeta {
|
|
103
|
+
fileSize: number;
|
|
104
|
+
mtime: number;
|
|
105
|
+
hash?: string;
|
|
106
|
+
}
|
|
107
|
+
interface CacheCheckResult {
|
|
108
|
+
shouldCompile: boolean;
|
|
109
|
+
hash?: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
type CompilationResult = SFCCompilationResult | ScriptCompilationResult | StyleCompilationResult;
|
|
113
|
+
interface SFCCompilationResult extends BaseCompilationResult {
|
|
114
|
+
fileInfo: {
|
|
115
|
+
jsx: {
|
|
116
|
+
file: string;
|
|
117
|
+
lang: string;
|
|
118
|
+
};
|
|
119
|
+
css: {
|
|
120
|
+
file?: string;
|
|
121
|
+
hash?: string;
|
|
122
|
+
code?: string;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
interface ScriptCompilationResult extends BaseCompilationResult {
|
|
127
|
+
fileInfo: {
|
|
128
|
+
script: {
|
|
129
|
+
file: string;
|
|
130
|
+
lang: string;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
interface StyleCompilationResult extends Omit<BaseCompilationResult, 'hasRoute' | keyof GeneratorResult> {
|
|
135
|
+
code: string;
|
|
136
|
+
fileInfo: {
|
|
137
|
+
style: {
|
|
138
|
+
file: string;
|
|
139
|
+
lang: string;
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
interface BaseCompilationResult extends GeneratorResult {
|
|
144
|
+
fileId: string;
|
|
145
|
+
hasRoute?: boolean;
|
|
146
|
+
}
|
|
147
|
+
|
|
9
148
|
type LangType = 'js' | 'jsx' | 'ts' | 'tsx';
|
|
10
149
|
|
|
11
150
|
type ReactiveTypes = 'ref' | 'reactive' | 'indirect' | 'none';
|
|
@@ -122,1279 +261,1078 @@ interface IPropsContext {
|
|
|
122
261
|
slotTypes: t.TSType[];
|
|
123
262
|
}
|
|
124
263
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
* 负责将 Vue SFC 源码解析为包含模板、脚本、样式等各个块的结构化数据。
|
|
142
|
-
*
|
|
143
|
-
* @param source - Vue 单文件组件的源码字符串
|
|
144
|
-
* @param ctx - 编译上下文对象
|
|
145
|
-
* @param plugins - 可选的插件注册表,用于对解析结果进行自定义处理和增强
|
|
146
|
-
* @returns 解析结果对象,包含模板、脚本、样式块的解析信息
|
|
147
|
-
* @throws 不会直接抛出异常,错误信息会通过日志系统记录
|
|
148
|
-
*
|
|
149
|
-
* @remarks
|
|
150
|
-
* - 函数内部使用 Vue 官方的 `@vue/compiler-sfc` 进行基础解析
|
|
151
|
-
* - 解析结果会经过后处理阶段,包括脚本元数据扫描
|
|
152
|
-
* - 插件按照注册顺序依次执行,可以对解析结果进行修改或增强
|
|
153
|
-
* - 错误处理:语法错误和编译错误会通过日志系统记录,不会中断执行
|
|
154
|
-
*
|
|
155
|
-
* @example
|
|
156
|
-
* ```typescript
|
|
157
|
-
* // 基础用法:解析一个简单的 Vue 组件
|
|
158
|
-
*
|
|
159
|
-
* const vueSource = `
|
|
160
|
-
* <template>
|
|
161
|
-
* <div class="greeting">
|
|
162
|
-
* Hello, {{ name }}!
|
|
163
|
-
* </div>
|
|
164
|
-
* </template>
|
|
165
|
-
*
|
|
166
|
-
* <script setup lang="ts">
|
|
167
|
-
* import { ref } from 'vue'
|
|
168
|
-
*
|
|
169
|
-
* const name = ref('World')
|
|
170
|
-
* const count = ref(0)
|
|
171
|
-
*
|
|
172
|
-
* function increment() {
|
|
173
|
-
* count.value++
|
|
174
|
-
* }
|
|
175
|
-
* </script>
|
|
176
|
-
*
|
|
177
|
-
* <style scoped>
|
|
178
|
-
* .greeting {
|
|
179
|
-
* color: #42b983;
|
|
180
|
-
* font-size: 1.5rem;
|
|
181
|
-
* }
|
|
182
|
-
* </style>
|
|
183
|
-
* `;
|
|
184
|
-
*
|
|
185
|
-
* const ctx: ICompilationContext = {
|
|
186
|
-
* filename: 'MyComponent.vue',
|
|
187
|
-
* // 其他上下文配置...
|
|
188
|
-
* };
|
|
189
|
-
*
|
|
190
|
-
* const result = parseSFC(vueSource, ctx);
|
|
191
|
-
*
|
|
192
|
-
* // 访问解析结果
|
|
193
|
-
* console.log(result.template?.ast); // 模板的 AST 节点
|
|
194
|
-
* console.log(result.script?.ast); // 脚本的 Babel 解析结果
|
|
195
|
-
* console.log(result.style?.source); // 样式块原始信息
|
|
196
|
-
*
|
|
197
|
-
* // 使用可选插件配置,进行自定义处理
|
|
198
|
-
* const options: ParserOptions = {
|
|
199
|
-
* plugins: {
|
|
200
|
-
* myPlugin: (result, ctx) => {
|
|
201
|
-
* // 提取组件元数据
|
|
202
|
-
* const componentName = extractComponentName(result);
|
|
203
|
-
* // 添加自定义分析结果
|
|
204
|
-
* result.metadata = {
|
|
205
|
-
* name: componentName,
|
|
206
|
-
* analyzedAt: new Date().toISOString()
|
|
207
|
-
* };
|
|
208
|
-
* }
|
|
209
|
-
* }
|
|
210
|
-
* };
|
|
211
|
-
*
|
|
212
|
-
* const resultWithPlugin = parseSFC(vueSource, compilationContext, options);
|
|
213
|
-
* ```
|
|
214
|
-
*/
|
|
215
|
-
declare function parseSFC(source: string, ctx: ICompilationContext, options?: ParserOptions): ParseResult;
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* 仅用于解析 script 文件,参数与 parseSFC 一致
|
|
219
|
-
*/
|
|
220
|
-
declare function parseOnlyScript(source: string, ctx: ICompilationContext, options?: ParserOptions): ParseResult;
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* 解析 Vue 组件源码的统一入口函数。
|
|
224
|
-
*
|
|
225
|
-
* 根据输入类型自动选择解析器:
|
|
226
|
-
* - `sfc`: 解析 Vue 单文件组件(包含 template/script/style)
|
|
227
|
-
* - `script-*`: 仅解析脚本文件(如 .js、.ts)
|
|
228
|
-
*
|
|
229
|
-
* @param source - 源码字符串
|
|
230
|
-
* @param ctx - 编译上下文,包含输入类型、文件名等信息
|
|
231
|
-
* @param options - 可选的解析器配置,如插件
|
|
232
|
-
* @returns 解析结果对象,包含模板、脚本、样式的结构化数据
|
|
233
|
-
*/
|
|
234
|
-
declare function parse(source: string, ctx: ICompilationContext, options?: ParserOptions): ParseResult;
|
|
235
|
-
|
|
236
|
-
interface ScriptBlockIR {
|
|
237
|
-
/** Transformed full script AST (used for script-only input). */
|
|
238
|
-
scriptAST?: ParseResult$1;
|
|
239
|
-
imports: t.ImportDeclaration[];
|
|
240
|
-
exports: t.ExportDeclaration[];
|
|
241
|
-
tsTypes: t.TypeScript[];
|
|
242
|
-
/** Executable statements extracted from script block. */
|
|
243
|
-
statement: {
|
|
244
|
-
/** Statements hoisted outside component function. */
|
|
245
|
-
global: t.Node[];
|
|
246
|
-
/** Statements kept inside component function. */
|
|
247
|
-
local: ParseResult$1<t.File> | null;
|
|
248
|
-
};
|
|
264
|
+
type CompilerPlugins = PluginRegister<CompilationResult> & {
|
|
265
|
+
/**
|
|
266
|
+
* Register parser plugins
|
|
267
|
+
*/
|
|
268
|
+
parser?: PluginRegister<ParseResult>;
|
|
269
|
+
/**
|
|
270
|
+
* Register transformer plugins
|
|
271
|
+
*/
|
|
272
|
+
transformer?: PluginRegister<ReactIRDescriptor>;
|
|
273
|
+
/**
|
|
274
|
+
* Register codegen plugins
|
|
275
|
+
*/
|
|
276
|
+
codegen?: PluginRegister<GeneratorResult>;
|
|
277
|
+
};
|
|
278
|
+
interface PluginRegister<T> {
|
|
279
|
+
[name: string]: (result: T, ctx: ICompilationContext) => void;
|
|
249
280
|
}
|
|
250
281
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
282
|
+
interface CompilerOptions {
|
|
283
|
+
/**
|
|
284
|
+
* Manually specify the root directory.
|
|
285
|
+
* @default process.cwd()
|
|
286
|
+
*/
|
|
287
|
+
root?: string;
|
|
288
|
+
/**
|
|
289
|
+
* Path to the source file or directory.
|
|
290
|
+
* - If it is a file, compile the single file.
|
|
291
|
+
* - If it is a directory, recursively compile all .vue files under the directory.
|
|
292
|
+
*
|
|
293
|
+
* @default
|
|
294
|
+
* 'src/' // The src directory under the root directory
|
|
295
|
+
*/
|
|
296
|
+
input?: string;
|
|
297
|
+
/**
|
|
298
|
+
* Whether to enable build cache and reuse the previous cache results
|
|
299
|
+
* @default true
|
|
300
|
+
*/
|
|
301
|
+
cache?: boolean;
|
|
302
|
+
/**
|
|
303
|
+
* @see {@link OutputConfig}
|
|
304
|
+
*/
|
|
305
|
+
output?: OutputConfig;
|
|
306
|
+
/**
|
|
307
|
+
* Excluded file/directory matching patterns (glob syntax supported).
|
|
308
|
+
* @default
|
|
309
|
+
* [
|
|
310
|
+
* 'node_modules/**',
|
|
311
|
+
* 'dist/**',
|
|
312
|
+
* 'build/**',
|
|
313
|
+
* '.git/**',
|
|
314
|
+
* '.vureact/**'
|
|
315
|
+
* ]
|
|
316
|
+
*/
|
|
317
|
+
exclude?: string[];
|
|
318
|
+
/**
|
|
319
|
+
* Whether to recursively search subdirectories.
|
|
320
|
+
* @default true
|
|
321
|
+
*/
|
|
322
|
+
recursive?: boolean;
|
|
323
|
+
/**
|
|
324
|
+
* Options passed through to babel-generator.
|
|
325
|
+
* @see {@link GeneratorOptions}
|
|
326
|
+
*/
|
|
327
|
+
generate?: GeneratorOptions$1;
|
|
328
|
+
/**
|
|
329
|
+
* Watch files in real time and auto-recompile on changes.
|
|
330
|
+
* @default false
|
|
331
|
+
*/
|
|
332
|
+
watch?: boolean;
|
|
333
|
+
/**
|
|
334
|
+
* Whether to process Less/Sass style languages into CSS
|
|
335
|
+
* @default true
|
|
336
|
+
*/
|
|
337
|
+
preprocessStyles?: boolean;
|
|
338
|
+
/**
|
|
339
|
+
* Specify the path to the Vue Router config file
|
|
340
|
+
* The file must default export createRouter
|
|
341
|
+
* Used to inject Router Provider in React's main.tsx or main.jsx
|
|
342
|
+
*
|
|
343
|
+
*
|
|
344
|
+
*
|
|
345
|
+
* @see {@link RouterConfig}
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* ```js
|
|
349
|
+
* router: {
|
|
350
|
+
* configFile: 'src/router/index.ts'
|
|
351
|
+
* }
|
|
352
|
+
* ```
|
|
353
|
+
*
|
|
354
|
+
* Assumes the config file default exports createRouter:
|
|
355
|
+
*
|
|
356
|
+
* ```js
|
|
357
|
+
* // src/router/index.ts
|
|
358
|
+
* export default createRouter({ ... })
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
361
|
+
router?: RouterConfig;
|
|
362
|
+
/**
|
|
363
|
+
* Can be used to add plugins and customize the output results of
|
|
364
|
+
* the parse/transform/codegen/compiled stages respectively.
|
|
365
|
+
*
|
|
366
|
+
* @see {@link CompilerPlugins}
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```ts
|
|
370
|
+
* plugins: {
|
|
371
|
+
* // For example, add custom data to the parsing results.
|
|
372
|
+
* parser: {
|
|
373
|
+
* myPlugin: (result, ctx) => {
|
|
374
|
+
* result.metadata = {
|
|
375
|
+
* timestamp: Date.now()
|
|
376
|
+
* }
|
|
377
|
+
* },
|
|
378
|
+
* },
|
|
379
|
+
*
|
|
380
|
+
* // If the key names parse/transform/codegen are not specified,
|
|
381
|
+
* // the plugin will execute upon completion of compilation.
|
|
382
|
+
* yourPlguin: (result) => {
|
|
383
|
+
* console.log(result)
|
|
384
|
+
* }
|
|
385
|
+
* }
|
|
386
|
+
* ```
|
|
387
|
+
*/
|
|
388
|
+
plugins?: CompilerPlugins;
|
|
389
|
+
/**
|
|
390
|
+
* @see {@link FormatConfig}
|
|
391
|
+
*/
|
|
392
|
+
format?: FormatConfig;
|
|
393
|
+
/**
|
|
394
|
+
* Log Control Options
|
|
395
|
+
* @see {@link LoggingConfig}
|
|
396
|
+
*/
|
|
397
|
+
logging?: LoggingConfig;
|
|
398
|
+
/**
|
|
399
|
+
* Execute only after the first successful full compilation.
|
|
400
|
+
*/
|
|
401
|
+
onSuccess?: () => Promise<void | undefined>;
|
|
402
|
+
/**
|
|
403
|
+
* Execute after file are added or recompiled in `watch` mode.
|
|
404
|
+
*
|
|
405
|
+
* @param event Add or modify file
|
|
406
|
+
* @param unit Current sfc or script file compilation unit
|
|
407
|
+
*/
|
|
408
|
+
onChange?: (event: 'add' | 'change', unit: CompilationUnit) => Promise<void | undefined>;
|
|
341
409
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
410
|
+
interface OutputConfig {
|
|
411
|
+
/**
|
|
412
|
+
* Output the name of the root directory corresponding to the file's location.
|
|
413
|
+
* @default '.vureact'
|
|
414
|
+
*/
|
|
415
|
+
workspace?: string;
|
|
416
|
+
/**
|
|
417
|
+
* Output directory name, relative to `output.workspace`
|
|
418
|
+
* @default 'dist'
|
|
419
|
+
*/
|
|
420
|
+
outDir?: string;
|
|
421
|
+
/**
|
|
422
|
+
* Whether to automatically call Vite to initialize a standard
|
|
423
|
+
* React project environment before compilation.
|
|
424
|
+
* @default true
|
|
425
|
+
*/
|
|
426
|
+
bootstrapVite?: boolean | {
|
|
427
|
+
/**
|
|
428
|
+
* Specify the React template type.
|
|
429
|
+
* @default 'react-ts'
|
|
430
|
+
*/
|
|
431
|
+
template?: 'react-ts' | 'react';
|
|
432
|
+
/**
|
|
433
|
+
* Specify the Vite version for initial installation, which must start with '@'.
|
|
434
|
+
* @default '@latest'
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
*
|
|
438
|
+
* ```js
|
|
439
|
+
* { vite: '@7' }
|
|
440
|
+
* ```
|
|
441
|
+
*/
|
|
442
|
+
vite?: string;
|
|
443
|
+
/**
|
|
444
|
+
* Specify the React version for initial installation.
|
|
445
|
+
* @default 'latest'
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
*
|
|
449
|
+
* ```js
|
|
450
|
+
* { react: '^19.2.0' }
|
|
451
|
+
* ```
|
|
452
|
+
*/
|
|
453
|
+
react?: string;
|
|
359
454
|
};
|
|
455
|
+
/**
|
|
456
|
+
* Specify asset files that do not need to be copied.
|
|
457
|
+
* They can be filenames or paths, using fuzzy matching.
|
|
458
|
+
* @default
|
|
459
|
+
* [
|
|
460
|
+
* 'package.json',
|
|
461
|
+
* 'package-lock.json',
|
|
462
|
+
* 'pnpm-lock.yaml',
|
|
463
|
+
* 'index.html',
|
|
464
|
+
* 'tsconfig.',
|
|
465
|
+
* 'vite.config.',
|
|
466
|
+
* 'eslint.config.',
|
|
467
|
+
* 'readme.',
|
|
468
|
+
* 'vue.',
|
|
469
|
+
* '.vue',
|
|
470
|
+
* 'vureact.config.js',
|
|
471
|
+
* 'vureact.config.ts',
|
|
472
|
+
* ]
|
|
473
|
+
*/
|
|
474
|
+
ignoreAssets?: string[];
|
|
360
475
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
476
|
+
interface RouterConfig {
|
|
477
|
+
/**
|
|
478
|
+
* Path to the Vue Router config file.
|
|
479
|
+
* Must be the location where `createRouter` is **exported as default**.
|
|
480
|
+
*/
|
|
481
|
+
configFile: string;
|
|
482
|
+
/**
|
|
483
|
+
* Automatically update the react app entry file to use the VuReact Router Provider.
|
|
484
|
+
*
|
|
485
|
+
* Note: Injection only occurs when `output.bootstrapVite` is enabled.
|
|
486
|
+
*
|
|
487
|
+
* @default true
|
|
488
|
+
*/
|
|
489
|
+
autoUpdateEntry?: boolean;
|
|
364
490
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
491
|
+
interface FormatConfig {
|
|
492
|
+
/**
|
|
493
|
+
* @default false
|
|
494
|
+
*/
|
|
495
|
+
enabled?: boolean;
|
|
496
|
+
/**
|
|
497
|
+
* @default 'prettier'
|
|
498
|
+
*/
|
|
499
|
+
formatter?: 'prettier' | 'builtin';
|
|
500
|
+
/**
|
|
501
|
+
* Configure the formatting options for Prettier,
|
|
502
|
+
* which takes effect only when the formatter is set to 'prettier'.
|
|
503
|
+
*/
|
|
504
|
+
prettierOptions?: Options;
|
|
371
505
|
}
|
|
372
|
-
interface
|
|
373
|
-
|
|
506
|
+
interface LoggingConfig {
|
|
507
|
+
/**
|
|
508
|
+
* @default true
|
|
509
|
+
*/
|
|
510
|
+
enabled?: boolean;
|
|
511
|
+
/** Whether to output warning messages. */
|
|
512
|
+
warnings?: boolean;
|
|
513
|
+
/** Whether to output info messages. */
|
|
514
|
+
info?: boolean;
|
|
515
|
+
/** Whether to output error messages. */
|
|
516
|
+
errors?: boolean;
|
|
374
517
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
518
|
+
|
|
519
|
+
declare class Helper {
|
|
520
|
+
private compilerOpts;
|
|
521
|
+
private pathFilter;
|
|
522
|
+
private workspaceDir;
|
|
523
|
+
private outDir;
|
|
524
|
+
constructor(opts: CompilerOptions);
|
|
525
|
+
/**
|
|
526
|
+
* 获取用户的项目根目录
|
|
527
|
+
*/
|
|
528
|
+
getProjectRoot(): string;
|
|
529
|
+
/**
|
|
530
|
+
* 获取输入文件的路径
|
|
531
|
+
*/
|
|
532
|
+
getInputPath(): string;
|
|
533
|
+
/**
|
|
534
|
+
* 检查 input 路径是否是单个文件
|
|
535
|
+
*/
|
|
536
|
+
isSingleFile(): boolean;
|
|
537
|
+
/**
|
|
538
|
+
* 获取输出文件的路径。如:'[root]/.vureact/dist/'
|
|
539
|
+
* @param addInput 会输出如:'[root]/.vureact/dist/[input]/'
|
|
540
|
+
*/
|
|
541
|
+
getOuputPath(addInput?: boolean): string;
|
|
542
|
+
getOutDirName(): string;
|
|
543
|
+
getWorkspaceDir(): string;
|
|
544
|
+
/**
|
|
545
|
+
* 根据相对输出路径反推源文件路径
|
|
546
|
+
*/
|
|
547
|
+
getSourcePath(outputPath: string): string;
|
|
548
|
+
getIgnoreAssets(): Set<string>;
|
|
549
|
+
getIsCache(): boolean;
|
|
550
|
+
/**
|
|
551
|
+
* 返回原始目录下的 package.json 路径
|
|
552
|
+
*/
|
|
553
|
+
getRootPkgPath(): string;
|
|
554
|
+
/**
|
|
555
|
+
* 返回 output 的 package.json 路径
|
|
556
|
+
*/
|
|
557
|
+
getOutputPkgPath(): string;
|
|
558
|
+
/**
|
|
559
|
+
* 返回文件相对工作区的路径
|
|
560
|
+
*/
|
|
561
|
+
relativePath(filePath: string): string;
|
|
562
|
+
/**
|
|
563
|
+
* 替换 .vue 文件名后缀为 .jsx/.tsx
|
|
564
|
+
* @param filePath 文件完整路径
|
|
565
|
+
* @param ext 文件拓展名
|
|
566
|
+
* @returns 返回文件的相对路径,不包含当前工作区路径
|
|
567
|
+
*/
|
|
568
|
+
replaceVueFileExt(filePath: string, ext: string): string;
|
|
569
|
+
/**
|
|
570
|
+
* 判断是否应该跳过不需要进行文件搜索的路径
|
|
571
|
+
*/
|
|
572
|
+
shouldSkipPath(filePath: string): boolean;
|
|
573
|
+
/**
|
|
574
|
+
* 自动根据项目结构推导 react-app 目录下的对应位置
|
|
575
|
+
*/
|
|
576
|
+
resolveOutputPath(filePath: string, extname?: string): string;
|
|
577
|
+
/**
|
|
578
|
+
* 格式化代码
|
|
579
|
+
*/
|
|
580
|
+
formatCode({ code, fileInfo }: CompilationResult): Promise<string>;
|
|
581
|
+
/**
|
|
582
|
+
* 通用的缓存校验工具函数
|
|
583
|
+
* @param current 当前文件元数据
|
|
584
|
+
* @param cached 缓存中的旧数据
|
|
585
|
+
* @param getSource 获取文件内容的函数(仅在元数据不一致时才调用,避免多余 I/O)
|
|
586
|
+
*/
|
|
587
|
+
checkCacheStatus(current: FileMeta, cached: CacheMeta | undefined, getSource: () => Promise<string>): Promise<CacheCheckResult>;
|
|
588
|
+
/**
|
|
589
|
+
* 对比相同两个文件的基础元数据
|
|
590
|
+
*/
|
|
591
|
+
compareFileMeta(a: FileMeta, b: FileMeta): boolean;
|
|
592
|
+
/**
|
|
593
|
+
* 统一的写文件方法,包含自动创建目录(带文件互斥锁可选)
|
|
594
|
+
* @param filePath - 要写入的文件路径
|
|
595
|
+
* @param content - 要写入的内容
|
|
596
|
+
* @param options - 可选配置项
|
|
597
|
+
* @param options.lock - 是否启用文件锁(默认false)
|
|
598
|
+
*/
|
|
599
|
+
writeFileWithDir(filePath: string, content: string, options?: FileLockOptions & {
|
|
600
|
+
lock?: boolean;
|
|
601
|
+
}): Promise<void>;
|
|
602
|
+
rmFile(filePath: string): Promise<void>;
|
|
603
|
+
/**
|
|
604
|
+
* 加载指定文件的缓存内容
|
|
605
|
+
* @param key 缓存键
|
|
606
|
+
*/
|
|
607
|
+
loadCache(key: CacheKey.SFC): Promise<LoadedCache<Vue2ReactCacheMeta>>;
|
|
608
|
+
loadCache(key: CacheKey.SCRIPT | CacheKey.STYLE | CacheKey.ASSET): Promise<LoadedCache<FileCacheMeta>>;
|
|
609
|
+
loadCache(key: CacheKey.SFC | CacheKey.SCRIPT | CacheKey.STYLE | CacheKey.ASSET): Promise<LoadedCache<Vue2ReactCacheMeta | FileCacheMeta>>;
|
|
610
|
+
createCacheData(key: CacheKey): LoadedCache;
|
|
611
|
+
/**
|
|
612
|
+
* 获取缓存文件路径
|
|
613
|
+
*/
|
|
614
|
+
getCachePath(): string;
|
|
615
|
+
saveCache(data?: LoadedCache): Promise<void>;
|
|
616
|
+
genHash(content: string): string;
|
|
617
|
+
/**
|
|
618
|
+
* 扫描指定目录下的所有文件
|
|
619
|
+
* @param dir 目标目录
|
|
620
|
+
* @param filter 筛选指定的文件后缀名
|
|
621
|
+
*/
|
|
622
|
+
scanFiles(dir: string, filter: (file: string) => boolean): string[];
|
|
623
|
+
getAbsPath(filePath: string): string;
|
|
624
|
+
getFileMeta(filePath: string): Promise<FileMeta>;
|
|
625
|
+
removeOutputFile(filePath: string, resolveOutputPath?: boolean): Promise<void>;
|
|
626
|
+
updateCache(targetFile: string, newData: any, cache: LoadedCache): void;
|
|
627
|
+
/**
|
|
628
|
+
* 获取需要排除编译的文件
|
|
629
|
+
*/
|
|
630
|
+
getExcludes(): string[];
|
|
631
|
+
/**
|
|
632
|
+
* 打印 core 模块执行过程中收集的日志
|
|
633
|
+
*/
|
|
634
|
+
printCoreLogs(): void;
|
|
635
|
+
printCompileInfo(file: string, duration: string): void;
|
|
636
|
+
print(...message: any[]): void;
|
|
637
|
+
/**
|
|
638
|
+
* 读取 package.json 文件内容,并处理成对象返回
|
|
639
|
+
*/
|
|
640
|
+
resolvePackageFile(path: string): Promise<Record<string, any>>;
|
|
641
|
+
/**
|
|
642
|
+
* 获取目录到文件的相对路径
|
|
643
|
+
* @returns 结果路径不包含文件拓展名,并以诸如 ./ 开头
|
|
644
|
+
*/
|
|
645
|
+
resolveRelativePath(from: string, to: string): string;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* 基础编译器类 - Vue 到 React 代码转换的核心实现
|
|
440
650
|
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
* ```
|
|
651
|
+
* 继承自 Helper,提供单文件编译功能,支持插件系统和三阶段编译流程。
|
|
652
|
+
* 主要用于文件系统批量编译和单文件编译场景。
|
|
444
653
|
*/
|
|
445
|
-
declare
|
|
654
|
+
declare class BaseCompiler extends Helper {
|
|
655
|
+
version: string;
|
|
656
|
+
options: CompilerOptions;
|
|
657
|
+
private createContext;
|
|
658
|
+
constructor(options?: CompilerOptions);
|
|
659
|
+
/** 编译 Vue 源代码为 React 代码 */
|
|
660
|
+
compile(source: string, filename: string): CompilationResult;
|
|
661
|
+
private prepareGenerateOptions;
|
|
662
|
+
private resolveMainResult;
|
|
663
|
+
private resolveStyleResult;
|
|
664
|
+
}
|
|
446
665
|
|
|
447
|
-
|
|
448
|
-
|
|
666
|
+
declare class CleanupManager {
|
|
667
|
+
private fileCompiler;
|
|
668
|
+
constructor(fileCompiler: FileCompiler);
|
|
669
|
+
/**
|
|
670
|
+
* Delete the build artifacts and cache corresponding to the specified path.
|
|
671
|
+
*/
|
|
672
|
+
removeOutputPath(targetPath: string, type: CacheKey): Promise<void>;
|
|
673
|
+
/**
|
|
674
|
+
* Delete the build artifacts or asset files and cache corresponding to the specified path.
|
|
675
|
+
*/
|
|
676
|
+
cleanupOldOutput(key: CacheKey, filter: (m: CacheMeta) => boolean): Promise<void>;
|
|
449
677
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
678
|
+
|
|
679
|
+
declare class AssetManager {
|
|
680
|
+
private fileCompiler;
|
|
681
|
+
private cleanupManager;
|
|
682
|
+
pipelineFiles: string[];
|
|
683
|
+
private skippedCount;
|
|
684
|
+
constructor(fileCompiler: FileCompiler, cleanupManager: CleanupManager);
|
|
685
|
+
/**
|
|
686
|
+
* 运行资源文件处理管线
|
|
687
|
+
*/
|
|
688
|
+
runAssetPipeline(): Promise<number>;
|
|
689
|
+
/**
|
|
690
|
+
* Process single asset file, compare with cache and decide whether to copy.
|
|
691
|
+
*/
|
|
692
|
+
processAsset(filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<FileCacheMeta | undefined>;
|
|
693
|
+
/**
|
|
694
|
+
* 更新缓存
|
|
695
|
+
*/
|
|
696
|
+
private updateCache;
|
|
697
|
+
/**
|
|
698
|
+
* 获取跳过的文件数量
|
|
699
|
+
*/
|
|
700
|
+
getSkippedCount(): number;
|
|
701
|
+
/**
|
|
702
|
+
* 重置跳过的文件数量
|
|
703
|
+
*/
|
|
704
|
+
resetSkippedCount(): void;
|
|
454
705
|
}
|
|
455
|
-
/**
|
|
456
|
-
* 将 React 中间表示(IR)生成为可执行的 JSX/TSX 代码。
|
|
457
|
-
*
|
|
458
|
-
* 此函数是代码生成阶段的核心入口,负责将转换后的 React IR 转换为
|
|
459
|
-
* 完整的 AST 并最终生成源代码。生成过程包括 JSX 构建和脚本构建。
|
|
460
|
-
*
|
|
461
|
-
* @param ir - React 中间表示描述符,来自 {@link transform} 函数的返回值
|
|
462
|
-
* @param ctx - 编译上下文对象
|
|
463
|
-
* @param options - 可选的生成选项,包括 Babel 生成器选项和插件
|
|
464
|
-
* @returns 生成结果对象,包含 AST、生成的代码和原始源码引用
|
|
465
|
-
*
|
|
466
|
-
* @remarks
|
|
467
|
-
* - JSX 构建:将模板 IR 转换为 JSX AST 节点
|
|
468
|
-
* - 脚本构建:将脚本 IR 与 JSX 结合,构建完整的程序 AST
|
|
469
|
-
* - 代码生成:使用 Babel 生成器将 AST 转换为源代码字符串
|
|
470
|
-
* - 插件支持:支持通过插件对生成结果进行自定义处理
|
|
471
|
-
*
|
|
472
|
-
* @example
|
|
473
|
-
* ```typescript
|
|
474
|
-
* // 生成示例
|
|
475
|
-
*
|
|
476
|
-
* const ctx: ICompilationContext = {
|
|
477
|
-
* filename: 'MyComponent.vue',
|
|
478
|
-
* source: vueSource,
|
|
479
|
-
* // 其他上下文配置...
|
|
480
|
-
* };
|
|
481
|
-
*
|
|
482
|
-
* // 1. 解析 Vue SFC
|
|
483
|
-
* const parseResult = parse(vueSource, ctx);
|
|
484
|
-
*
|
|
485
|
-
* // 2. 转换为 React IR
|
|
486
|
-
* const reactIR = transform(parseResult, ctx);
|
|
487
|
-
*
|
|
488
|
-
* // 使用可选配置项进行自定义处理
|
|
489
|
-
* const generatorOptions: GeneratorOptions = {
|
|
490
|
-
* // 配置 jsesc 避免 Unicode 转义
|
|
491
|
-
* jsescOption: {
|
|
492
|
-
* minimal: true,
|
|
493
|
-
* quotes: 'single'
|
|
494
|
-
* },
|
|
495
|
-
* minified: true,
|
|
496
|
-
*
|
|
497
|
-
* // 自定义插件
|
|
498
|
-
* plugins: {
|
|
499
|
-
* // 插件1:代码格式化
|
|
500
|
-
* formatCode: (result, ctx) => {
|
|
501
|
-
* // 使用 prettier 格式化生成的代码
|
|
502
|
-
* result.code = prettier.format(result.code, {
|
|
503
|
-
* parser: 'babel',
|
|
504
|
-
* semi: true,
|
|
505
|
-
* singleQuote: true,
|
|
506
|
-
* });
|
|
507
|
-
* },
|
|
508
|
-
*
|
|
509
|
-
* // 插件2:代码质量检查
|
|
510
|
-
* lintGeneratedCode: (result, ctx) => {
|
|
511
|
-
* const issues = eslint.verify(result.code, {
|
|
512
|
-
* rules: {
|
|
513
|
-
* 'react/react-in-jsx-scope': 'off',
|
|
514
|
-
* 'no-unused-vars': 'warn',
|
|
515
|
-
* },
|
|
516
|
-
* });
|
|
517
|
-
*
|
|
518
|
-
* if (issues.length > 0) {
|
|
519
|
-
* result.lintIssues = issues;
|
|
520
|
-
* console.warn(`Found ${issues.length} lint issues in generated code`);
|
|
521
|
-
* }
|
|
522
|
-
* },
|
|
523
|
-
* },
|
|
524
|
-
* };
|
|
525
|
-
*
|
|
526
|
-
* // 3. 生成 React 组件
|
|
527
|
-
* const generated = generateComponent(reactIR, ctx, generatorOptions);
|
|
528
|
-
*
|
|
529
|
-
* // 访问生成结果
|
|
530
|
-
* console.log(generated.ast); // 完整的 Babel AST
|
|
531
|
-
* console.log(generated.code); // 生成的 React 代码
|
|
532
|
-
* console.log(generated.source); // 原始 Vue 源码
|
|
533
|
-
* ```
|
|
534
|
-
*/
|
|
535
|
-
declare function generateComponent(ir: ReactIRDescriptor, ctx: ICompilationContext, options?: GeneratorOptions): GeneratorResult;
|
|
536
706
|
|
|
537
|
-
declare
|
|
707
|
+
declare class CacheManager {
|
|
708
|
+
private fileCompiler;
|
|
709
|
+
private pendingUpdates;
|
|
710
|
+
constructor(fileCompiler: FileCompiler);
|
|
711
|
+
/**
|
|
712
|
+
* 批量更新缓存记录
|
|
713
|
+
*/
|
|
714
|
+
updateCacheIncrementally(unit: CompilationUnit, key: CacheKey): Promise<void>;
|
|
715
|
+
/**
|
|
716
|
+
* 批量保存缓存
|
|
717
|
+
*/
|
|
718
|
+
flushCache(key: CacheKey): Promise<void>;
|
|
719
|
+
/**
|
|
720
|
+
* 更新缓存
|
|
721
|
+
*/
|
|
722
|
+
private updateCache;
|
|
723
|
+
}
|
|
538
724
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
725
|
+
declare class CompilationUnitProcessor {
|
|
726
|
+
private fileCompiler;
|
|
727
|
+
constructor(fileCompiler: FileCompiler);
|
|
728
|
+
/**
|
|
729
|
+
* 处理编译单元,落地成对应代码和文件
|
|
730
|
+
*/
|
|
731
|
+
resolve(unit: CompilationUnit, key: CacheKey): Promise<CompilationUnit>;
|
|
732
|
+
private resolveResult;
|
|
733
|
+
/**
|
|
734
|
+
* 将编译产物写入磁盘
|
|
735
|
+
*/
|
|
736
|
+
saveCompiledFiles(unit: CompilationUnit, key: CacheKey): Promise<void>;
|
|
737
|
+
}
|
|
552
738
|
|
|
553
|
-
|
|
739
|
+
declare class FileProcessor {
|
|
740
|
+
private fileCompiler;
|
|
741
|
+
private compilationUnitProcessor;
|
|
742
|
+
private cacheManager;
|
|
743
|
+
private skippedCount;
|
|
744
|
+
constructor(fileCompiler: FileCompiler, compilationUnitProcessor: CompilationUnitProcessor, cacheManager: CacheManager);
|
|
554
745
|
/**
|
|
555
|
-
*
|
|
556
|
-
* @default process.cwd()
|
|
746
|
+
* Process a single Vue file (this method is called directly in CLI Watch mode)
|
|
557
747
|
*/
|
|
558
|
-
|
|
748
|
+
processSFC(filePath: string, existingCache?: LoadedCache<Vue2ReactCacheMeta>): Promise<SFCUnit | undefined>;
|
|
559
749
|
/**
|
|
560
|
-
*
|
|
561
|
-
* - If it is a file, compile the single file.
|
|
562
|
-
* - If it is a directory, recursively compile all .vue files under the directory.
|
|
563
|
-
*
|
|
564
|
-
* @default
|
|
565
|
-
* 'src/' // The src directory under the root directory
|
|
750
|
+
* Process a single script file (this method is called directly in CLI Watch mode)
|
|
566
751
|
*/
|
|
567
|
-
|
|
752
|
+
processScript(filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<ScriptUnit | undefined>;
|
|
568
753
|
/**
|
|
569
|
-
*
|
|
570
|
-
* @default true
|
|
754
|
+
* Process a single style file (this method is called directly in CLI Watch mode)
|
|
571
755
|
*/
|
|
572
|
-
|
|
573
|
-
output?: {
|
|
574
|
-
/**
|
|
575
|
-
* Output the name of the root directory corresponding to the file's location.
|
|
576
|
-
* @default '.vureact'
|
|
577
|
-
*/
|
|
578
|
-
workspace?: string;
|
|
579
|
-
/**
|
|
580
|
-
* Output directory name, relative to `output.workspace`
|
|
581
|
-
* @default 'dist'
|
|
582
|
-
*/
|
|
583
|
-
outDir?: string;
|
|
584
|
-
/**
|
|
585
|
-
* Whether to automatically call Vite to initialize a standard
|
|
586
|
-
* React project environment before compilation.
|
|
587
|
-
* @default true
|
|
588
|
-
*/
|
|
589
|
-
bootstrapVite?: boolean | {
|
|
590
|
-
/**
|
|
591
|
-
* @default 'react-ts'
|
|
592
|
-
*/
|
|
593
|
-
template: 'react-ts' | 'react';
|
|
594
|
-
};
|
|
595
|
-
/**
|
|
596
|
-
* Specify asset files that do not need to be copied.
|
|
597
|
-
* They can be filenames or paths, using fuzzy matching.
|
|
598
|
-
* @default
|
|
599
|
-
* [
|
|
600
|
-
* 'package.json',
|
|
601
|
-
* 'package-lock.json',
|
|
602
|
-
* 'pnpm-lock.yaml',
|
|
603
|
-
* 'index.html',
|
|
604
|
-
* 'tsconfig.',
|
|
605
|
-
* 'vite.config.',
|
|
606
|
-
* 'eslint.config.',
|
|
607
|
-
* 'readme.',
|
|
608
|
-
* 'vue.',
|
|
609
|
-
* 'vureact.config.js',
|
|
610
|
-
* ]
|
|
611
|
-
*/
|
|
612
|
-
ignoreAssets?: string[];
|
|
613
|
-
};
|
|
756
|
+
processStyle(filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<StyleUnit | undefined>;
|
|
614
757
|
/**
|
|
615
|
-
*
|
|
616
|
-
* @default
|
|
617
|
-
* [
|
|
618
|
-
* 'node_modules/**',
|
|
619
|
-
* 'dist/**',
|
|
620
|
-
* 'build/**',
|
|
621
|
-
* '.git/**',
|
|
622
|
-
* '.vureact/**'
|
|
623
|
-
* ]
|
|
758
|
+
* Process a single vue file
|
|
624
759
|
*/
|
|
625
|
-
|
|
760
|
+
processFile(key: CacheKey.SFC, filePath: string, existingCache?: LoadedCache<Vue2ReactCacheMeta>): Promise<SFCUnit | undefined>;
|
|
626
761
|
/**
|
|
627
|
-
*
|
|
628
|
-
* @default true
|
|
762
|
+
* Process a single script file
|
|
629
763
|
*/
|
|
630
|
-
|
|
764
|
+
processFile(key: CacheKey.SCRIPT, filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<ScriptUnit | undefined>;
|
|
631
765
|
/**
|
|
632
|
-
*
|
|
766
|
+
* Process a single style file
|
|
633
767
|
*/
|
|
634
|
-
|
|
768
|
+
processFile(key: CacheKey.STYLE, filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<StyleUnit | undefined>;
|
|
635
769
|
/**
|
|
636
|
-
*
|
|
637
|
-
* @default false
|
|
770
|
+
* Process a single vue/script/style file
|
|
638
771
|
*/
|
|
639
|
-
|
|
772
|
+
processFile(key: CacheKey, filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<CompilationUnit | undefined>;
|
|
640
773
|
/**
|
|
641
|
-
*
|
|
642
|
-
* @default true
|
|
774
|
+
* 对 package.json 注入路由依赖项
|
|
643
775
|
*/
|
|
644
|
-
|
|
776
|
+
private addRouterToPackageJson;
|
|
645
777
|
/**
|
|
646
|
-
*
|
|
647
|
-
* the parse/transform/codegen/compiled stages respectively.
|
|
648
|
-
*
|
|
649
|
-
* @example
|
|
650
|
-
* ```ts
|
|
651
|
-
* plugins: {
|
|
652
|
-
* // For example, add custom data to the parsing results.
|
|
653
|
-
* parser: {
|
|
654
|
-
* myPlugin: (result, ctx) => {
|
|
655
|
-
* result.metadata = {
|
|
656
|
-
* timestamp: Date.now()
|
|
657
|
-
* }
|
|
658
|
-
* },
|
|
659
|
-
* },
|
|
660
|
-
*
|
|
661
|
-
* // If the key names parse/transform/codegen are not specified,
|
|
662
|
-
* // the plugin will execute upon completion of compilation.
|
|
663
|
-
* yourPlguin: (result) => {
|
|
664
|
-
* console.log(result)
|
|
665
|
-
* }
|
|
666
|
-
* }
|
|
667
|
-
* ```
|
|
778
|
+
* 注入路由提供器到 React 应用的入口文件(如 main.tsx)
|
|
668
779
|
*/
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
*/
|
|
687
|
-
enabled?: boolean;
|
|
688
|
-
/**
|
|
689
|
-
* @default 'prettier'
|
|
690
|
-
*/
|
|
691
|
-
formatter?: 'prettier' | 'builtin';
|
|
692
|
-
/**
|
|
693
|
-
* Configure the formatting options for Prettier,
|
|
694
|
-
* which takes effect only when the formatter is set to 'prettier'.
|
|
695
|
-
*/
|
|
696
|
-
prettierOptions?: Options;
|
|
697
|
-
};
|
|
780
|
+
private updateEntryWithRouterProvider;
|
|
781
|
+
/**
|
|
782
|
+
* 获取跳过的文件数量
|
|
783
|
+
*/
|
|
784
|
+
getSkippedCount(): number;
|
|
785
|
+
/**
|
|
786
|
+
* 重置跳过的文件数量
|
|
787
|
+
*/
|
|
788
|
+
resetSkippedCount(): void;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
declare class PipelineManager {
|
|
792
|
+
private fileCompiler;
|
|
793
|
+
private fileProcessor;
|
|
794
|
+
private skippedCount;
|
|
795
|
+
private cleanupManager;
|
|
796
|
+
constructor(fileCompiler: FileCompiler, fileProcessor: FileProcessor);
|
|
698
797
|
/**
|
|
699
|
-
*
|
|
798
|
+
* 运行 SFC 编译管线
|
|
700
799
|
*/
|
|
701
|
-
|
|
702
|
-
/**
|
|
703
|
-
* @default true
|
|
704
|
-
*/
|
|
705
|
-
enabled?: boolean;
|
|
706
|
-
/** Whether to output warning messages. */
|
|
707
|
-
warnings?: boolean;
|
|
708
|
-
/** Whether to output info messages. */
|
|
709
|
-
info?: boolean;
|
|
710
|
-
/** Whether to output error messages. */
|
|
711
|
-
errors?: boolean;
|
|
712
|
-
};
|
|
800
|
+
runSfcPipeline(): Promise<number>;
|
|
713
801
|
/**
|
|
714
|
-
*
|
|
802
|
+
* 运行 Script 编译管线
|
|
715
803
|
*/
|
|
716
|
-
|
|
804
|
+
runScriptPipeline(): Promise<number>;
|
|
717
805
|
/**
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
* @param event Add or modify file
|
|
721
|
-
* @param unit Current sfc or script file compilation unit
|
|
806
|
+
* 运行 Style 编译管线
|
|
722
807
|
*/
|
|
723
|
-
|
|
808
|
+
runStylePipeline(): Promise<number>;
|
|
809
|
+
/**
|
|
810
|
+
* 核心编译管线
|
|
811
|
+
*/
|
|
812
|
+
private runCorePipeline;
|
|
813
|
+
/**
|
|
814
|
+
* 获取跳过的文件数量
|
|
815
|
+
*/
|
|
816
|
+
getSkippedCount(): number;
|
|
817
|
+
/**
|
|
818
|
+
* 重置跳过的文件数量
|
|
819
|
+
*/
|
|
820
|
+
resetSkippedCount(): void;
|
|
724
821
|
}
|
|
725
|
-
|
|
726
|
-
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Vite 环境初始化管理器
|
|
825
|
+
*/
|
|
826
|
+
declare class ViteBootstrapper {
|
|
827
|
+
private fileCompiler;
|
|
828
|
+
private options;
|
|
829
|
+
private spinner;
|
|
830
|
+
private defaultConfig;
|
|
831
|
+
constructor(fileCompiler: FileCompiler, options: CompilerOptions);
|
|
832
|
+
/**
|
|
833
|
+
* 检查是否需要初始化 Vite 环境
|
|
834
|
+
*/
|
|
835
|
+
private isSingleFile;
|
|
836
|
+
/**
|
|
837
|
+
* 利用 Vite 官方脚手架创建标准 React 环境
|
|
838
|
+
*/
|
|
839
|
+
bootstrapIfNeeded(): Promise<boolean>;
|
|
840
|
+
/**
|
|
841
|
+
* 执行 vite 创建命令
|
|
842
|
+
*/
|
|
843
|
+
private resolveViteCreateApp;
|
|
844
|
+
/**
|
|
845
|
+
* 处理 React 包版本
|
|
846
|
+
* @param ver 版本号
|
|
847
|
+
*/
|
|
848
|
+
private resolveReactVersion;
|
|
727
849
|
}
|
|
728
|
-
|
|
729
|
-
interface
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
file?: string;
|
|
737
|
-
hash?: string;
|
|
738
|
-
code?: string;
|
|
739
|
-
};
|
|
740
|
-
};
|
|
850
|
+
|
|
851
|
+
interface CompilerManager {
|
|
852
|
+
viteBootstrapper: ViteBootstrapper;
|
|
853
|
+
fileProcessor: FileProcessor;
|
|
854
|
+
pipelineManager: PipelineManager;
|
|
855
|
+
assetManager: AssetManager;
|
|
856
|
+
cacheManager: CacheManager;
|
|
857
|
+
cleanupManager: CleanupManager;
|
|
741
858
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* 文件系统编译器 - 将 Vue 项目批量转换为 React 项目
|
|
862
|
+
*
|
|
863
|
+
* 提供完整的文件系统级别编译功能,包括 SFC、脚本、样式编译,
|
|
864
|
+
* 资源拷贝、增量编译、缓存管理和 Vite 环境初始化。
|
|
865
|
+
*/
|
|
866
|
+
declare class FileCompiler extends BaseCompiler {
|
|
867
|
+
manager: CompilerManager;
|
|
868
|
+
private spinner;
|
|
869
|
+
constructor(options?: CompilerOptions);
|
|
870
|
+
/** 执行完整的编译流程 */
|
|
871
|
+
execute(): Promise<void>;
|
|
872
|
+
/** 处理单个 Vue 单文件组件(SFC) */
|
|
873
|
+
processSFC(filePath: string, existingCache?: LoadedCache<Vue2ReactCacheMeta>): Promise<SFCUnit | undefined>;
|
|
874
|
+
/** 处理单个 JavaScript/TypeScript 脚本文件 */
|
|
875
|
+
processScript(filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<ScriptUnit | undefined>;
|
|
876
|
+
/** 处理单个 CSS/LESS/SCSS 样式文件 */
|
|
877
|
+
processStyle(filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<StyleUnit | undefined>;
|
|
878
|
+
/** 处理单个文件(Vue 或 Script) */
|
|
879
|
+
processFile(key: CacheKey, filePath: string, existingCache?: LoadedCache): Promise<CompilationUnit | undefined>;
|
|
880
|
+
/** 处理单个资源文件 */
|
|
881
|
+
processAsset(filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<FileCacheMeta | undefined>;
|
|
882
|
+
/** 批量保存缓存 */
|
|
883
|
+
flushCache(key: CacheKey): Promise<void>;
|
|
884
|
+
/** 删除指定路径对应的输出文件和缓存 */
|
|
885
|
+
removeOutputPath(targetPath: string, type: CacheKey): Promise<void>;
|
|
886
|
+
private runPipelineWithSpinner;
|
|
887
|
+
private showCompileStats;
|
|
888
|
+
private resetSkippedCount;
|
|
749
889
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
890
|
+
|
|
891
|
+
/**
|
|
892
|
+
* Type helper to make it easier to use vureact.config.js
|
|
893
|
+
* accepts a direct {@link UserConfig} object, or a function that returns it.
|
|
894
|
+
*/
|
|
895
|
+
declare function defineConfig(config: CompilerOptions): CompilerOptions;
|
|
896
|
+
declare function defineConfig(config: UserConfigFnObject): CompilerOptions;
|
|
897
|
+
type UserConfigFnObject = () => CompilerOptions;
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* Next Vue to React compiler, compiles Vue 3 syntax into runnable React 18+ code.
|
|
901
|
+
*
|
|
902
|
+
* @extends FileCompiler
|
|
903
|
+
*
|
|
904
|
+
* @see {@link FileCompiler}
|
|
905
|
+
* @see https://vureact.top
|
|
906
|
+
*/
|
|
907
|
+
declare class VuReact extends FileCompiler {
|
|
758
908
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
909
|
+
|
|
910
|
+
interface ParseResult {
|
|
911
|
+
template: BlockIR<SFCTemplateBlock, RootNode>;
|
|
912
|
+
script: BlockIR<SFCScriptBlock, ParseResult$1>;
|
|
913
|
+
style: BlockIR<SFCStyleBlock, undefined>;
|
|
762
914
|
}
|
|
763
|
-
type
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
};
|
|
915
|
+
type BlockIR<S, T> = {
|
|
916
|
+
source?: S;
|
|
917
|
+
ast: T;
|
|
918
|
+
} | null;
|
|
919
|
+
interface ParserOptions {
|
|
920
|
+
plugins?: PluginRegister<ParseResult>;
|
|
770
921
|
}
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
922
|
+
/**
|
|
923
|
+
* 解析 Vue 单文件组件(SFC)源码,生成结构化解析结果。
|
|
924
|
+
*
|
|
925
|
+
* 此函数是解析阶段的核心入口,
|
|
926
|
+
* 负责将 Vue SFC 源码解析为包含模板、脚本、样式等各个块的结构化数据。
|
|
927
|
+
*
|
|
928
|
+
* @param source - Vue 单文件组件的源码字符串
|
|
929
|
+
* @param ctx - 编译上下文对象
|
|
930
|
+
* @param plugins - 可选的插件注册表,用于对解析结果进行自定义处理和增强
|
|
931
|
+
* @returns 解析结果对象,包含模板、脚本、样式块的解析信息
|
|
932
|
+
* @throws 不会直接抛出异常,错误信息会通过日志系统记录
|
|
933
|
+
*
|
|
934
|
+
* @remarks
|
|
935
|
+
* - 函数内部使用 Vue 官方的 `@vue/compiler-sfc` 进行基础解析
|
|
936
|
+
* - 解析结果会经过后处理阶段,包括脚本元数据扫描
|
|
937
|
+
* - 插件按照注册顺序依次执行,可以对解析结果进行修改或增强
|
|
938
|
+
* - 错误处理:语法错误和编译错误会通过日志系统记录,不会中断执行
|
|
939
|
+
*
|
|
940
|
+
* @example
|
|
941
|
+
* ```typescript
|
|
942
|
+
* // 基础用法:解析一个简单的 Vue 组件
|
|
943
|
+
*
|
|
944
|
+
* const vueSource = `
|
|
945
|
+
* <template>
|
|
946
|
+
* <div class="greeting">
|
|
947
|
+
* Hello, {{ name }}!
|
|
948
|
+
* </div>
|
|
949
|
+
* </template>
|
|
950
|
+
*
|
|
951
|
+
* <script setup lang="ts">
|
|
952
|
+
* import { ref } from 'vue'
|
|
953
|
+
*
|
|
954
|
+
* const name = ref('World')
|
|
955
|
+
* const count = ref(0)
|
|
956
|
+
*
|
|
957
|
+
* function increment() {
|
|
958
|
+
* count.value++
|
|
959
|
+
* }
|
|
960
|
+
* </script>
|
|
961
|
+
*
|
|
962
|
+
* <style scoped>
|
|
963
|
+
* .greeting {
|
|
964
|
+
* color: #42b983;
|
|
965
|
+
* font-size: 1.5rem;
|
|
966
|
+
* }
|
|
967
|
+
* </style>
|
|
968
|
+
* `;
|
|
969
|
+
*
|
|
970
|
+
* const ctx: ICompilationContext = {
|
|
971
|
+
* filename: 'MyComponent.vue',
|
|
972
|
+
* // 其他上下文配置...
|
|
973
|
+
* };
|
|
974
|
+
*
|
|
975
|
+
* const result = parseSFC(vueSource, ctx);
|
|
976
|
+
*
|
|
977
|
+
* // 访问解析结果
|
|
978
|
+
* console.log(result.template?.ast); // 模板的 AST 节点
|
|
979
|
+
* console.log(result.script?.ast); // 脚本的 Babel 解析结果
|
|
980
|
+
* console.log(result.style?.source); // 样式块原始信息
|
|
981
|
+
*
|
|
982
|
+
* // 使用可选插件配置,进行自定义处理
|
|
983
|
+
* const options: ParserOptions = {
|
|
984
|
+
* plugins: {
|
|
985
|
+
* myPlugin: (result, ctx) => {
|
|
986
|
+
* // 提取组件元数据
|
|
987
|
+
* const componentName = extractComponentName(result);
|
|
988
|
+
* // 添加自定义分析结果
|
|
989
|
+
* result.metadata = {
|
|
990
|
+
* name: componentName,
|
|
991
|
+
* analyzedAt: new Date().toISOString()
|
|
992
|
+
* };
|
|
993
|
+
* }
|
|
994
|
+
* }
|
|
995
|
+
* };
|
|
996
|
+
*
|
|
997
|
+
* const resultWithPlugin = parseSFC(vueSource, compilationContext, options);
|
|
998
|
+
* ```
|
|
999
|
+
*/
|
|
1000
|
+
declare function parseSFC(source: string, ctx: ICompilationContext, options?: ParserOptions): ParseResult;
|
|
1001
|
+
|
|
1002
|
+
/**
|
|
1003
|
+
* 仅用于解析 script 文件,参数与 parseSFC 一致
|
|
1004
|
+
*/
|
|
1005
|
+
declare function parseOnlyScript(source: string, ctx: ICompilationContext, options?: ParserOptions): ParseResult;
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* 解析 Vue 组件源码的统一入口函数。
|
|
1009
|
+
*
|
|
1010
|
+
* 根据输入类型自动选择解析器:
|
|
1011
|
+
* - `sfc`: 解析 Vue 单文件组件(包含 template/script/style)
|
|
1012
|
+
* - `script-*`: 仅解析脚本文件(如 .js、.ts)
|
|
1013
|
+
*
|
|
1014
|
+
* @param source - 源码字符串
|
|
1015
|
+
* @param ctx - 编译上下文,包含输入类型、文件名等信息
|
|
1016
|
+
* @param options - 可选的解析器配置,如插件
|
|
1017
|
+
* @returns 解析结果对象,包含模板、脚本、样式的结构化数据
|
|
1018
|
+
*/
|
|
1019
|
+
declare function parse(source: string, ctx: ICompilationContext, options?: ParserOptions): ParseResult;
|
|
1020
|
+
|
|
1021
|
+
interface ScriptBlockIR {
|
|
1022
|
+
/** Transformed full script AST (used for script-only input). */
|
|
1023
|
+
scriptAST?: ParseResult$1;
|
|
1024
|
+
imports: t.ImportDeclaration[];
|
|
1025
|
+
exports: t.ExportDeclaration[];
|
|
1026
|
+
tsTypes: t.TypeScript[];
|
|
1027
|
+
/** Executable statements extracted from script block. */
|
|
1028
|
+
statement: {
|
|
1029
|
+
/** Statements hoisted outside component function. */
|
|
1030
|
+
global: t.Node[];
|
|
1031
|
+
/** Statements kept inside component function. */
|
|
1032
|
+
local: ParseResult$1<t.File> | null;
|
|
775
1033
|
};
|
|
776
1034
|
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
1035
|
+
|
|
1036
|
+
declare const enum NodeTypes {
|
|
1037
|
+
FRAGMENT = 0,
|
|
1038
|
+
ELEMENT = 1,
|
|
1039
|
+
TEXT = 2,
|
|
1040
|
+
COMMENT = 3,
|
|
1041
|
+
JSX_INTERPOLATION = 4
|
|
782
1042
|
}
|
|
783
|
-
|
|
784
|
-
|
|
1043
|
+
declare const enum PropTypes {
|
|
1044
|
+
ATTRIBUTE = 1,
|
|
1045
|
+
SLOT = 2,
|
|
1046
|
+
EVENT = 3,
|
|
1047
|
+
DYNAMIC_ATTRIBUTE = 4
|
|
785
1048
|
}
|
|
786
|
-
interface
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
source: string;
|
|
790
|
-
hasRoute?: boolean;
|
|
1049
|
+
interface BabelExp<T = Expression> {
|
|
1050
|
+
content: string;
|
|
1051
|
+
ast: T;
|
|
791
1052
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
1053
|
+
|
|
1054
|
+
interface BaseSimpleNodeIR {
|
|
1055
|
+
type: NodeTypes;
|
|
1056
|
+
content: string;
|
|
1057
|
+
babelExp: Expression;
|
|
795
1058
|
}
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
source: CacheList;
|
|
800
|
-
};
|
|
801
|
-
type CacheMeta = Vue2ReactCacheMeta | FileCacheMeta;
|
|
802
|
-
declare enum CacheKey {
|
|
803
|
-
SFC = "sfc",
|
|
804
|
-
SCRIPT = "script",
|
|
805
|
-
STYLE = "style",
|
|
806
|
-
ASSET = "copied"
|
|
1059
|
+
interface FragmentNodeIR {
|
|
1060
|
+
type: NodeTypes;
|
|
1061
|
+
children: TemplateChildNodeIR[];
|
|
807
1062
|
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
1063
|
+
|
|
1064
|
+
interface ElementNodeIR extends BaseElementNodeIR {
|
|
1065
|
+
type: NodeTypes;
|
|
1066
|
+
props: (PropsIR | SlotPropsIR)[];
|
|
1067
|
+
children: TemplateChildNodeIR[];
|
|
1068
|
+
meta: Partial<ElementNodeIRMeta>;
|
|
1069
|
+
conditionIsHandled: boolean;
|
|
1070
|
+
isBuiltIn?: boolean;
|
|
1071
|
+
isRoute?: boolean;
|
|
813
1072
|
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
1073
|
+
interface BaseElementNodeIR {
|
|
1074
|
+
tag: string;
|
|
1075
|
+
isComponent?: boolean;
|
|
1076
|
+
isSelfClosing?: boolean;
|
|
1077
|
+
ref?: string;
|
|
1078
|
+
loc?: SourceLocation;
|
|
817
1079
|
}
|
|
818
|
-
interface
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
1080
|
+
interface ElementNodeIRMeta {
|
|
1081
|
+
condition: ConditionMeta;
|
|
1082
|
+
loop: LoopMeta;
|
|
1083
|
+
memo: MemoMeta;
|
|
1084
|
+
show: ShowMeta;
|
|
822
1085
|
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
1086
|
+
type ConditionMeta = {
|
|
1087
|
+
if?: boolean;
|
|
1088
|
+
elseIf?: boolean;
|
|
1089
|
+
else?: boolean;
|
|
1090
|
+
value: string;
|
|
1091
|
+
babelExp: BabelExp;
|
|
1092
|
+
next?: ElementNodeIR;
|
|
1093
|
+
isHandled: boolean;
|
|
1094
|
+
};
|
|
1095
|
+
type LoopMeta = {
|
|
1096
|
+
isLoop?: boolean;
|
|
1097
|
+
value: {
|
|
1098
|
+
source: string;
|
|
1099
|
+
value: string;
|
|
1100
|
+
key?: string;
|
|
1101
|
+
index?: string;
|
|
1102
|
+
};
|
|
1103
|
+
isHandled: boolean;
|
|
1104
|
+
};
|
|
1105
|
+
type MemoMeta = {
|
|
1106
|
+
isMemo?: boolean;
|
|
1107
|
+
value: string;
|
|
1108
|
+
babelExp: BabelExp<ArrayExpression>;
|
|
1109
|
+
isHandled: boolean;
|
|
1110
|
+
};
|
|
1111
|
+
type ShowMeta = {
|
|
1112
|
+
isShow?: boolean;
|
|
1113
|
+
value: string;
|
|
1114
|
+
babelExp: BabelExp;
|
|
1115
|
+
};
|
|
1116
|
+
|
|
1117
|
+
interface PropsIR {
|
|
1118
|
+
type: PropTypes;
|
|
1119
|
+
rawName?: string;
|
|
1120
|
+
name: string;
|
|
1121
|
+
isStatic?: boolean;
|
|
1122
|
+
modifiers?: string[];
|
|
1123
|
+
value: PropIRValue;
|
|
1124
|
+
isKeyLessVBind?: boolean;
|
|
1125
|
+
babelExp: BabelExp<JSXIdentifier | Expression>;
|
|
826
1126
|
}
|
|
1127
|
+
type PropIRValue = {
|
|
1128
|
+
content: string;
|
|
1129
|
+
isStringLiteral?: boolean;
|
|
1130
|
+
merge?: string[];
|
|
1131
|
+
babelExp: BabelExp;
|
|
1132
|
+
};
|
|
827
1133
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
* 检查 input 路径是否是单个文件
|
|
844
|
-
*/
|
|
845
|
-
isSingleFile(): boolean;
|
|
846
|
-
/**
|
|
847
|
-
* 获取输出文件的路径。如:'[root]/.vureact/dist/'
|
|
848
|
-
*/
|
|
849
|
-
getOuputPath(): string;
|
|
850
|
-
getOutDirName(): string;
|
|
851
|
-
getWorkspaceDir(): string;
|
|
852
|
-
/**
|
|
853
|
-
* 根据相对输出路径反推源文件路径
|
|
854
|
-
*/
|
|
855
|
-
getSourcePath(outputPath: string): string;
|
|
856
|
-
getIgnoreAssets(): Set<string>;
|
|
857
|
-
getIsCache(): boolean;
|
|
858
|
-
/**
|
|
859
|
-
* 返回原始目录下的 package.json 路径
|
|
860
|
-
*/
|
|
861
|
-
getRootPkgPath(): string;
|
|
862
|
-
/**
|
|
863
|
-
* 返回 output 的 package.json 路径
|
|
864
|
-
*/
|
|
865
|
-
getOutputPkgPath(): string;
|
|
866
|
-
/**
|
|
867
|
-
* 返回文件相对工作区的路径
|
|
868
|
-
*/
|
|
869
|
-
relativePath(filePath: string): string;
|
|
870
|
-
/**
|
|
871
|
-
* 替换 .vue 文件名后缀为 .jsx/.tsx
|
|
872
|
-
* @param filePath 文件完整路径
|
|
873
|
-
* @param ext 文件拓展名
|
|
874
|
-
* @returns 返回文件的相对路径,不包含当前工作区路径
|
|
875
|
-
*/
|
|
876
|
-
replaceVueFileExt(filePath: string, ext: string): string;
|
|
877
|
-
/**
|
|
878
|
-
* 判断是否应该跳过不需要进行文件搜索的路径
|
|
879
|
-
*/
|
|
880
|
-
shouldSkipPath(filePath: string): boolean;
|
|
881
|
-
/**
|
|
882
|
-
* 自动根据项目结构推导 react-app 目录下的对应位置
|
|
883
|
-
*/
|
|
884
|
-
resolveOutputPath(filePath: string, extname?: string): string;
|
|
885
|
-
/**
|
|
886
|
-
* 格式化代码
|
|
887
|
-
*/
|
|
888
|
-
formatCode({ code, fileInfo }: CompilationResult): Promise<string>;
|
|
889
|
-
/**
|
|
890
|
-
* 通用的缓存校验工具函数
|
|
891
|
-
* @param current 当前文件元数据
|
|
892
|
-
* @param cached 缓存中的旧数据
|
|
893
|
-
* @param getSource 获取文件内容的函数(仅在元数据不一致时才调用,避免多余 I/O)
|
|
894
|
-
*/
|
|
895
|
-
checkCacheStatus(current: FileMeta, cached: CacheMeta | undefined, getSource: () => Promise<string>): Promise<CacheCheckResult>;
|
|
896
|
-
/**
|
|
897
|
-
* 对比相同两个文件的基础元数据
|
|
898
|
-
*/
|
|
899
|
-
compareFileMeta(a: FileMeta, b: FileMeta): boolean;
|
|
900
|
-
/**
|
|
901
|
-
* 统一的写文件方法,包含自动创建目录
|
|
902
|
-
*/
|
|
903
|
-
writeFileWithDir(filePath: string, content: string): Promise<void>;
|
|
904
|
-
/**
|
|
905
|
-
* 加载指定文件的缓存内容
|
|
906
|
-
* @param key 缓存键
|
|
907
|
-
*/
|
|
908
|
-
loadCache(key: CacheKey.SFC): Promise<LoadedCache<Vue2ReactCacheMeta>>;
|
|
909
|
-
loadCache(key: CacheKey.SCRIPT | CacheKey.STYLE | CacheKey.ASSET): Promise<LoadedCache<FileCacheMeta>>;
|
|
910
|
-
loadCache(key: CacheKey.SFC | CacheKey.SCRIPT | CacheKey.STYLE | CacheKey.ASSET): Promise<LoadedCache<Vue2ReactCacheMeta | FileCacheMeta>>;
|
|
911
|
-
createCacheData(key: CacheKey): LoadedCache;
|
|
912
|
-
/**
|
|
913
|
-
* 获取缓存文件路径
|
|
914
|
-
*/
|
|
915
|
-
getCachePath(): string;
|
|
916
|
-
saveCache(data?: LoadedCache): Promise<void>;
|
|
917
|
-
genHash(content: string): string;
|
|
918
|
-
/**
|
|
919
|
-
* 扫描指定目录下的所有文件
|
|
920
|
-
* @param dir 目标目录
|
|
921
|
-
* @param filter 筛选指定的文件后缀名
|
|
922
|
-
*/
|
|
923
|
-
scanFiles(dir: string, filter: (file: string) => boolean): string[];
|
|
924
|
-
getAbsPath(filePath: string): string;
|
|
925
|
-
getFileMeta(filePath: string): Promise<FileMeta>;
|
|
926
|
-
removeOutputFile(filePath: string, resolveOutputPath?: boolean): Promise<void>;
|
|
927
|
-
updateCache(targetFile: string, newData: any, cache: LoadedCache): void;
|
|
928
|
-
resolveViteCreateApp(): void;
|
|
929
|
-
/**
|
|
930
|
-
* 获取需要排除编译的文件
|
|
931
|
-
*/
|
|
932
|
-
getExcludes(): string[];
|
|
933
|
-
/**
|
|
934
|
-
* 打印 core 模块执行过程中收集的日志
|
|
935
|
-
*/
|
|
936
|
-
printCoreLogs(): void;
|
|
937
|
-
printCompileInfo(file: string, duration: string): void;
|
|
938
|
-
print(...message: any[]): void;
|
|
939
|
-
/**
|
|
940
|
-
* 读取 package.json 文件内容,并处理成对象返回
|
|
941
|
-
*/
|
|
942
|
-
resolvePackageFile(path: string): Promise<Record<string, any>>;
|
|
1134
|
+
interface SlotPropsIR {
|
|
1135
|
+
type: PropTypes.SLOT;
|
|
1136
|
+
name: string;
|
|
1137
|
+
rawName: string;
|
|
1138
|
+
isStatic: boolean;
|
|
1139
|
+
isScoped: boolean;
|
|
1140
|
+
content?: TemplateChildNodeIR[];
|
|
1141
|
+
callback?: {
|
|
1142
|
+
arg: string;
|
|
1143
|
+
exp: TemplateChildNodeIR[];
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
interface TemplateBlockIR {
|
|
1148
|
+
children: TemplateChildNodeIR[];
|
|
943
1149
|
}
|
|
1150
|
+
type TemplateChildNodeIR = ElementNodeIR | BaseSimpleNodeIR | FragmentNodeIR;
|
|
944
1151
|
|
|
1152
|
+
interface ReactIRDescriptor {
|
|
1153
|
+
template: TemplateBlockIR;
|
|
1154
|
+
script: ScriptBlockIR;
|
|
1155
|
+
style?: string;
|
|
1156
|
+
}
|
|
1157
|
+
interface TransformerOptions {
|
|
1158
|
+
plugins?: PluginRegister<ReactIRDescriptor>;
|
|
1159
|
+
}
|
|
945
1160
|
/**
|
|
946
|
-
*
|
|
1161
|
+
* 将 Vue SFC 解析结果转换为 React 中间表示(IR)。
|
|
1162
|
+
*
|
|
1163
|
+
* 此函数是转换阶段的核心入口,负责将 Vue 组件的解析结果(AST)转换为
|
|
1164
|
+
* 适合生成 React 代码的中间表示形式。转换过程包括模板转换和脚本转换。
|
|
1165
|
+
*
|
|
1166
|
+
* @param ast - Vue SFC 的解析结果,来自 {@link parse} 函数的返回值
|
|
1167
|
+
* @param ctx - 编译上下文对象
|
|
1168
|
+
* @param plugins - 可选的插件注册表,用于对转换结果进行自定义处理和增强
|
|
1169
|
+
* @returns React 中间表示描述符,包含模板、脚本和样式的转换结果
|
|
1170
|
+
*
|
|
1171
|
+
* @remarks
|
|
1172
|
+
* - 模板转换:将 Vue 模板 AST 转换为 React 可用的模板 IR
|
|
1173
|
+
* - 脚本转换:将 Vue 脚本 AST 转换为 React 可用的脚本 IR
|
|
1174
|
+
* - 样式处理:提取样式块内容,保留原始 CSS 字符串
|
|
1175
|
+
* - 插件支持:支持通过插件对转换结果进行自定义处理
|
|
1176
|
+
*
|
|
1177
|
+
* @example
|
|
1178
|
+
* ```typescript
|
|
1179
|
+
* // 转换示例
|
|
947
1180
|
*
|
|
948
|
-
*
|
|
949
|
-
*
|
|
950
|
-
*
|
|
951
|
-
*
|
|
952
|
-
* 4. 插件系统集成:支持解析、转换、生成各阶段的插件扩展
|
|
953
|
-
* 5. 错误处理和日志记录:通过日志系统记录编译过程中的信息
|
|
1181
|
+
* const ctx: ICompilationContext = {
|
|
1182
|
+
* filename: 'MyComponent.vue',
|
|
1183
|
+
* // 其他上下文配置...
|
|
1184
|
+
* };
|
|
954
1185
|
*
|
|
955
|
-
*
|
|
956
|
-
*
|
|
957
|
-
* - 直接实例化用于单文件编译,适合集成到其他工具链中
|
|
1186
|
+
* // 1. 首先解析 Vue SFC
|
|
1187
|
+
* const parseResult = parse(vueSource, ctx);
|
|
958
1188
|
*
|
|
959
|
-
*
|
|
960
|
-
*
|
|
961
|
-
* - 插件化架构:支持在编译各阶段插入自定义逻辑
|
|
962
|
-
* - 上下文隔离:每次编译创建独立上下文,避免状态污染
|
|
963
|
-
* - 资源感知:自动处理样式预处理和路由依赖检测
|
|
964
|
-
* - 错误恢复:编译错误通过日志记录,不会中断整个流程
|
|
1189
|
+
* // 2. 将解析结果转换为 React IR
|
|
1190
|
+
* const reactIR = transform(parseResult, ctx);
|
|
965
1191
|
*
|
|
966
|
-
*
|
|
967
|
-
*
|
|
968
|
-
*
|
|
969
|
-
*
|
|
970
|
-
* 4. 插件执行:在各阶段执行注册的插件,支持自定义扩展
|
|
1192
|
+
* // 访问转换结果
|
|
1193
|
+
* console.log(reactIR.template); // 模板转换结果
|
|
1194
|
+
* console.log(reactIR.script); // 脚本转换结果
|
|
1195
|
+
* console.log(reactIR.style); // 样式内容字符串
|
|
971
1196
|
*
|
|
972
|
-
*
|
|
973
|
-
*
|
|
974
|
-
* // 创建基础编译器实例
|
|
975
|
-
* const compiler = new BaseCompiler({
|
|
976
|
-
* cache: true,
|
|
977
|
-
* preprocessStyles: true,
|
|
1197
|
+
* // 使用可选插件配置,进行自定义处理
|
|
1198
|
+
* const options: TransformerOptions = {
|
|
978
1199
|
* plugins: {
|
|
979
|
-
*
|
|
980
|
-
*
|
|
981
|
-
*
|
|
982
|
-
*
|
|
1200
|
+
* extractMetadata: (result, ctx) => {
|
|
1201
|
+
* const componentName = extractComponentNameFromScript(result.script);
|
|
1202
|
+
* const propsCount = countProps(result.script);
|
|
1203
|
+
*
|
|
1204
|
+
* result.metadata = {
|
|
1205
|
+
* name: componentName,
|
|
1206
|
+
* propsCount,
|
|
1207
|
+
* hasStyle: !!result.style,
|
|
1208
|
+
* convertedAt: new Date().toISOString(),
|
|
1209
|
+
* };
|
|
983
1210
|
* },
|
|
984
|
-
*
|
|
985
|
-
*
|
|
986
|
-
*
|
|
1211
|
+
*
|
|
1212
|
+
* // 插2:样式预处理
|
|
1213
|
+
* preprocessStyles: (result, ctx) => {
|
|
1214
|
+
* if (result.style) {
|
|
1215
|
+
* // 对样式进行预处理,如添加前缀等
|
|
1216
|
+
* result.style = addVendorPrefixes(result.style);
|
|
1217
|
+
* result.style = minifyCSS(result.style);
|
|
987
1218
|
* }
|
|
988
|
-
* }
|
|
1219
|
+
* },
|
|
989
1220
|
* }
|
|
990
|
-
* }
|
|
1221
|
+
* }
|
|
991
1222
|
*
|
|
992
|
-
* //
|
|
993
|
-
* const
|
|
1223
|
+
* // 使用多个插件进行转换
|
|
1224
|
+
* const reactIRWithPlugins = transform(parseResult, ctx, plugins);
|
|
994
1225
|
*
|
|
995
|
-
* //
|
|
996
|
-
* console.log(
|
|
997
|
-
* console.log(result.code); // 生成的 React 代码
|
|
1226
|
+
* // 插件处理后的结果包含自定义数据
|
|
1227
|
+
* console.log(reactIRWithPlugins.metadata);
|
|
998
1228
|
* ```
|
|
999
|
-
*
|
|
1000
|
-
* @remarks
|
|
1001
|
-
* - 上下文管理:使用 {@link CompilationAdapter.createContext} 创建编译上下文
|
|
1002
|
-
* - 错误处理:编译过程中的错误通过 {@link logger} 记录,不会抛出异常
|
|
1003
|
-
* - 配置继承:继承 {@link Helper} 类的文件路径处理、缓存管理、格式化等工具方法
|
|
1004
|
-
* - 版本管理:自动读取 package.json 中的版本号,便于调试和日志记录
|
|
1005
|
-
*
|
|
1006
|
-
* @see {@link FileCompiler} 用于文件系统级别的批量编译和增量构建
|
|
1007
|
-
* @see {@link Helper} 提供基础的文件路径处理、缓存管理和格式化工具
|
|
1008
|
-
* @see {@link CompilerOptions} 查看完整的编译器配置选项
|
|
1009
|
-
* @see {@link CompilationResult} 编译结果的数据结构
|
|
1010
1229
|
*/
|
|
1011
|
-
declare
|
|
1012
|
-
version: string;
|
|
1013
|
-
options: CompilerOptions;
|
|
1014
|
-
private createContext;
|
|
1015
|
-
/**
|
|
1016
|
-
* 创建基础编译器实例
|
|
1017
|
-
*
|
|
1018
|
-
* @param options - 编译器配置选项,包括缓存设置、插件配置、样式预处理等,
|
|
1019
|
-
* 所有选项都会传递给父类 {@link Helper} 进行初始化
|
|
1020
|
-
*
|
|
1021
|
-
* @see {@link CompilerOptions} 查看完整的配置选项说明
|
|
1022
|
-
*/
|
|
1023
|
-
constructor(options?: CompilerOptions);
|
|
1024
|
-
/**
|
|
1025
|
-
* 编译 Vue 源代码为 React 代码
|
|
1026
|
-
*
|
|
1027
|
-
* 该方法执行完整的编译流程,包括:
|
|
1028
|
-
* 1. 上下文初始化:创建独立的编译上下文
|
|
1029
|
-
* 2. 解析阶段:将 Vue 源代码解析为抽象语法树(AST)
|
|
1030
|
-
* 3. 转换阶段:将 Vue AST 转换为 React 中间表示(IR)
|
|
1031
|
-
* 4. 生成阶段:将 React IR 生成为目标代码
|
|
1032
|
-
* 5. 插件执行:在各阶段执行注册的插件
|
|
1033
|
-
* 6. 结果处理:整理编译结果并返回
|
|
1034
|
-
*
|
|
1035
|
-
* 编译过程使用 try-finally 确保上下文资源被正确清理,
|
|
1036
|
-
* 即使编译过程中发生错误也不会导致资源泄漏。
|
|
1037
|
-
*
|
|
1038
|
-
* @param source - Vue 源代码字符串
|
|
1039
|
-
* @param filename - 源文件名,用于生成文件ID和输出路径
|
|
1040
|
-
* @returns {CompilationResult} 编译结果,包含生成的代码和文件信息
|
|
1041
|
-
*
|
|
1042
|
-
* @example
|
|
1043
|
-
* ```typescript
|
|
1044
|
-
* const vueCode = `
|
|
1045
|
-
* <template>
|
|
1046
|
-
* <div class="container">{{ message }}</div>
|
|
1047
|
-
* </template>
|
|
1048
|
-
*
|
|
1049
|
-
* <script setup lang="ts">
|
|
1050
|
-
* import { ref } from 'vue;
|
|
1051
|
-
* const message = ref('Hello Vue')
|
|
1052
|
-
* </script>
|
|
1053
|
-
*
|
|
1054
|
-
* <style scoped>
|
|
1055
|
-
* .container {
|
|
1056
|
-
* padding: 20px;
|
|
1057
|
-
* }
|
|
1058
|
-
* </style>
|
|
1059
|
-
* `;
|
|
1060
|
-
*
|
|
1061
|
-
* const result = compiler.compile(vueCode, 'MyComponent.vue');
|
|
1062
|
-
* console.log(result);
|
|
1063
|
-
* ```
|
|
1064
|
-
*
|
|
1065
|
-
* @throws 不会直接抛出异常,错误通过日志系统记录
|
|
1066
|
-
* @see {@link parse} 解析函数
|
|
1067
|
-
* @see {@link transform} 转换函数
|
|
1068
|
-
* @see {@link generate} 生成函数
|
|
1069
|
-
* @see {@link executePlugins} 插件执行函数
|
|
1070
|
-
*/
|
|
1071
|
-
compile(source: string, filename: string): CompilationResult;
|
|
1072
|
-
/**
|
|
1073
|
-
* 初始化 Babel 代码生成选项
|
|
1074
|
-
*
|
|
1075
|
-
* 合并用户自定义的生成选项与默认选项,确保代码生成的一致性和正确性。
|
|
1076
|
-
* 默认配置优化了代码的可读性和性能:
|
|
1077
|
-
* 1. 最小化 Unicode 转义:只转义必要的字符,保持代码可读性
|
|
1078
|
-
* 2. 统一引号风格:使用单引号,符合 JavaScript 社区常见约定
|
|
1079
|
-
* 3. 代码压缩:启用最小化,移除不必要的空白字符
|
|
1080
|
-
*
|
|
1081
|
-
* 如果用户提供了自定义选项,会与默认选项进行深度合并,
|
|
1082
|
-
* 用户选项的优先级高于默认选项。
|
|
1083
|
-
*
|
|
1084
|
-
* @private
|
|
1085
|
-
* @param filename - 可选的文件名,用于源码映射配置
|
|
1086
|
-
* @returns {GeneratorOptions} 合并后的 Babel 生成选项
|
|
1087
|
-
*
|
|
1088
|
-
* @remarks
|
|
1089
|
-
* - 源码映射支持:如果启用了 sourceMaps 且提供了文件名,会自动设置 sourceFileName
|
|
1090
|
-
* - 选项合并策略:用户选项会覆盖默认选项,实现灵活的配置
|
|
1091
|
-
* - 性能优化:默认启用 minified 以减少生成代码的体积
|
|
1092
|
-
* - 编码安全:使用 jsesc 确保特殊字符的正确转义
|
|
1093
|
-
*
|
|
1094
|
-
* @example
|
|
1095
|
-
* ```typescript
|
|
1096
|
-
* // 默认选项
|
|
1097
|
-
* const defaultOptions = {
|
|
1098
|
-
* jsescOption: { minimal: true, quotes: 'single' },
|
|
1099
|
-
* minified: true
|
|
1100
|
-
* };
|
|
1101
|
-
*
|
|
1102
|
-
* // 用户自定义选项
|
|
1103
|
-
* const userOptions = {
|
|
1104
|
-
* minified: false, // 覆盖默认值
|
|
1105
|
-
* sourceMaps: true // 新增选项
|
|
1106
|
-
* };
|
|
1107
|
-
*
|
|
1108
|
-
* // 合并结果
|
|
1109
|
-
* const merged = {
|
|
1110
|
-
* jsescOption: { minimal: true, quotes: 'single' },
|
|
1111
|
-
* minified: false, // 用户值
|
|
1112
|
-
* sourceMaps: true // 用户值
|
|
1113
|
-
* };
|
|
1114
|
-
* ```
|
|
1115
|
-
*
|
|
1116
|
-
* @see {@link GeneratorOptions} Babel 生成选项类型定义
|
|
1117
|
-
*/
|
|
1118
|
-
private prepareGenerateOptions;
|
|
1119
|
-
/**
|
|
1120
|
-
* 处理 SFC 和 Script 文件的编译结果
|
|
1121
|
-
*
|
|
1122
|
-
* 根据编译上下文中的输入类型(SFC 或 Script),整理并返回相应的编译结果。
|
|
1123
|
-
* 对于 SFC 文件,返回包含 JSX 和 CSS 信息的完整结果;
|
|
1124
|
-
* 对于 Script 文件,返回仅包含脚本信息的结果。
|
|
1125
|
-
*
|
|
1126
|
-
* 关键处理逻辑:
|
|
1127
|
-
* 1. 构建基础结果:包含文件ID、路由信息和生成的代码
|
|
1128
|
-
* 2. 确定输出路径:根据源文件路径和语言类型生成输出文件路径
|
|
1129
|
-
* 3. 区分文件类型:
|
|
1130
|
-
* - SFC 文件:生成 .tsx 扩展名,包含样式信息
|
|
1131
|
-
* - Script 文件:保持原扩展名,不包含样式信息
|
|
1132
|
-
* 4. 样式处理:提取样式文件路径、作用域ID和样式代码
|
|
1133
|
-
*
|
|
1134
|
-
* @private
|
|
1135
|
-
* @param ir - React 中间表示(IR)描述符,包含转换后的组件信息
|
|
1136
|
-
* @param gen - 代码生成结果,包含生成的代码和源码映射
|
|
1137
|
-
* @param ctxData - 编译上下文数据,包含文件信息和编译状态
|
|
1138
|
-
* @returns {CompilationResult} 整理后的编译结果
|
|
1139
|
-
*
|
|
1140
|
-
* @remarks
|
|
1141
|
-
* - 文件扩展名处理:Vue SFC 文件会转换为 .tsx 或 .jsx 文件
|
|
1142
|
-
* - 样式分离:SFC 中的样式会被提取到独立的 CSS 文件中
|
|
1143
|
-
* - 路由检测:自动检测组件是否使用路由,用于依赖注入
|
|
1144
|
-
* - 作用域样式:为 Scoped CSS 生成唯一的作用域ID
|
|
1145
|
-
*
|
|
1146
|
-
* @see {@link SFCCompilationResult} SFC 编译结果类型
|
|
1147
|
-
* @see {@link ScriptCompilationResult} Script 编译结果类型
|
|
1148
|
-
*/
|
|
1149
|
-
private resolveMainResult;
|
|
1150
|
-
/**
|
|
1151
|
-
* 处理 Style 文件的编译结果
|
|
1152
|
-
* @param data style 文件解析结果
|
|
1153
|
-
* @param ctxData 上下文数据
|
|
1154
|
-
*/
|
|
1155
|
-
private resolveStyleResult;
|
|
1156
|
-
}
|
|
1230
|
+
declare function transform(ast: ParseResult, ctx: ICompilationContext, options?: TransformerOptions): ReactIRDescriptor;
|
|
1157
1231
|
|
|
1232
|
+
interface GeneratorOptions extends GeneratorOptions$1 {
|
|
1233
|
+
plugins?: PluginRegister<GeneratorResult>;
|
|
1234
|
+
}
|
|
1235
|
+
interface GeneratorResult {
|
|
1236
|
+
ast: t.Program | ParseResult$1;
|
|
1237
|
+
code: string;
|
|
1238
|
+
source: string;
|
|
1239
|
+
}
|
|
1158
1240
|
/**
|
|
1159
|
-
*
|
|
1241
|
+
* 将 React 中间表示(IR)生成为可执行的 JSX/TSX 代码。
|
|
1160
1242
|
*
|
|
1161
|
-
*
|
|
1162
|
-
*
|
|
1163
|
-
* 2. 处理 JavaScript/TypeScript 脚本文件
|
|
1164
|
-
* 3. 资源文件(图片、样式、字体等)的智能拷贝
|
|
1165
|
-
* 4. 增量编译和高效的缓存管理
|
|
1166
|
-
* 5. 文件系统监控和自动清理
|
|
1167
|
-
* 6. Vite 项目环境自动初始化
|
|
1243
|
+
* 此函数是代码生成阶段的核心入口,负责将转换后的 React IR 转换为
|
|
1244
|
+
* 完整的 AST 并最终生成源代码。生成过程包括 JSX 构建和脚本构建。
|
|
1168
1245
|
*
|
|
1169
|
-
*
|
|
1170
|
-
* -
|
|
1171
|
-
* -
|
|
1172
|
-
*
|
|
1173
|
-
* - 错误隔离:单个文件编译失败不影响其他文件处理
|
|
1174
|
-
* - 并发处理:支持 Promise.all 并发处理多个文件,提升编译速度
|
|
1175
|
-
* - 路由感知:自动检测并注入 Vue Router 到 React Router 的转换依赖
|
|
1246
|
+
* @param ir - React 中间表示描述符,来自 {@link transform} 函数的返回值
|
|
1247
|
+
* @param ctx - 编译上下文对象
|
|
1248
|
+
* @param options - 可选的生成选项,包括 Babel 生成器选项和插件
|
|
1249
|
+
* @returns 生成结果对象,包含 AST、生成的代码和原始源码引用
|
|
1176
1250
|
*
|
|
1177
|
-
*
|
|
1178
|
-
*
|
|
1179
|
-
* -
|
|
1180
|
-
* -
|
|
1181
|
-
* -
|
|
1182
|
-
* - {@link AssetManager}: 处理资源文件拷贝
|
|
1183
|
-
* - {@link CleanupManager}: 清理过期文件和缓存
|
|
1184
|
-
* - {@link ViteBootstrapper}: 初始化 Vite React 项目环境
|
|
1251
|
+
* @remarks
|
|
1252
|
+
* - JSX 构建:将模板 IR 转换为 JSX AST 节点
|
|
1253
|
+
* - 脚本构建:将脚本 IR 与 JSX 结合,构建完整的程序 AST
|
|
1254
|
+
* - 代码生成:使用 Babel 生成器将 AST 转换为源代码字符串
|
|
1255
|
+
* - 插件支持:支持通过插件对生成结果进行自定义处理
|
|
1185
1256
|
*
|
|
1186
1257
|
* @example
|
|
1187
1258
|
* ```typescript
|
|
1188
|
-
* //
|
|
1189
|
-
*
|
|
1190
|
-
*
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
*
|
|
1194
|
-
*
|
|
1195
|
-
*
|
|
1196
|
-
*
|
|
1197
|
-
*
|
|
1198
|
-
* watch: false
|
|
1199
|
-
* });
|
|
1259
|
+
* // 生成示例
|
|
1260
|
+
*
|
|
1261
|
+
* const ctx: ICompilationContext = {
|
|
1262
|
+
* filename: 'MyComponent.vue',
|
|
1263
|
+
* source: vueSource,
|
|
1264
|
+
* // 其他上下文配置...
|
|
1265
|
+
* };
|
|
1266
|
+
*
|
|
1267
|
+
* // 1. 解析 Vue SFC
|
|
1268
|
+
* const parseResult = parse(vueSource, ctx);
|
|
1200
1269
|
*
|
|
1201
|
-
* //
|
|
1202
|
-
*
|
|
1270
|
+
* // 2. 转换为 React IR
|
|
1271
|
+
* const reactIR = transform(parseResult, ctx);
|
|
1203
1272
|
*
|
|
1204
|
-
* //
|
|
1205
|
-
*
|
|
1273
|
+
* // 使用可选配置项进行自定义处理
|
|
1274
|
+
* const generatorOptions: GeneratorOptions = {
|
|
1275
|
+
* // 配置 jsesc 避免 Unicode 转义
|
|
1276
|
+
* jsescOption: {
|
|
1277
|
+
* minimal: true,
|
|
1278
|
+
* quotes: 'single'
|
|
1279
|
+
* },
|
|
1280
|
+
* minified: true,
|
|
1206
1281
|
*
|
|
1207
|
-
*
|
|
1208
|
-
*
|
|
1282
|
+
* // 自定义插件
|
|
1283
|
+
* plugins: {
|
|
1284
|
+
* // 插件1:代码格式化
|
|
1285
|
+
* formatCode: (result, ctx) => {
|
|
1286
|
+
* // 使用 prettier 格式化生成的代码
|
|
1287
|
+
* result.code = prettier.format(result.code, {
|
|
1288
|
+
* parser: 'babel',
|
|
1289
|
+
* semi: true,
|
|
1290
|
+
* singleQuote: true,
|
|
1291
|
+
* });
|
|
1292
|
+
* },
|
|
1209
1293
|
*
|
|
1210
|
-
*
|
|
1211
|
-
*
|
|
1294
|
+
* // 插件2:代码质量检查
|
|
1295
|
+
* lintGeneratedCode: (result, ctx) => {
|
|
1296
|
+
* const issues = eslint.verify(result.code, {
|
|
1297
|
+
* rules: {
|
|
1298
|
+
* 'react/react-in-jsx-scope': 'off',
|
|
1299
|
+
* 'no-unused-vars': 'warn',
|
|
1300
|
+
* },
|
|
1301
|
+
* });
|
|
1212
1302
|
*
|
|
1213
|
-
*
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
1303
|
+
* if (issues.length > 0) {
|
|
1304
|
+
* result.lintIssues = issues;
|
|
1305
|
+
* console.warn(`Found ${issues.length} lint issues in generated code`);
|
|
1306
|
+
* }
|
|
1307
|
+
* },
|
|
1308
|
+
* },
|
|
1309
|
+
* };
|
|
1216
1310
|
*
|
|
1217
|
-
*
|
|
1218
|
-
*
|
|
1219
|
-
* - 缓存机制:使用文件哈希、大小和修改时间三重验证确保准确性
|
|
1220
|
-
* - 目录结构:保持输入目录结构到输出目录,便于项目迁移
|
|
1221
|
-
* - 错误处理:编译错误会记录到日志系统,但不会中断整个编译流程
|
|
1222
|
-
* - 性能优化:支持并发处理和增量编译,大幅提升大型项目编译速度
|
|
1311
|
+
* // 3. 生成 React 组件
|
|
1312
|
+
* const generated = generateComponent(reactIR, ctx, generatorOptions);
|
|
1223
1313
|
*
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
1226
|
-
*
|
|
1314
|
+
* // 访问生成结果
|
|
1315
|
+
* console.log(generated.ast); // 完整的 Babel AST
|
|
1316
|
+
* console.log(generated.code); // 生成的 React 代码
|
|
1317
|
+
* console.log(generated.source); // 原始 Vue 源码
|
|
1318
|
+
* ```
|
|
1227
1319
|
*/
|
|
1228
|
-
declare
|
|
1229
|
-
private skippedCount;
|
|
1230
|
-
private spinner;
|
|
1231
|
-
private viteBootstrapper;
|
|
1232
|
-
private pipelineManager;
|
|
1233
|
-
private fileProcessor;
|
|
1234
|
-
private compilationUnitProcessor;
|
|
1235
|
-
private cacheManager;
|
|
1236
|
-
private assetManager;
|
|
1237
|
-
private cleanupManager;
|
|
1238
|
-
/**
|
|
1239
|
-
* 创建文件系统编译器实例
|
|
1240
|
-
*
|
|
1241
|
-
* @param options - 编译器配置选项,继承自 BaseCompiler 的选项
|
|
1242
|
-
* 包括输入路径、输出配置、缓存设置、排除模式等
|
|
1243
|
-
* @see {@link CompilerOptions} 查看完整的选项说明
|
|
1244
|
-
*/
|
|
1245
|
-
constructor(options?: CompilerOptions);
|
|
1246
|
-
/**
|
|
1247
|
-
* 初始化所有管理器实例
|
|
1248
|
-
*
|
|
1249
|
-
* 按照依赖关系顺序创建各个管理器:
|
|
1250
|
-
* 1. 基础管理器(无依赖)
|
|
1251
|
-
* 2. 依赖基础管理器的管理器
|
|
1252
|
-
* 3. 依赖其他管理器的管理器
|
|
1253
|
-
*
|
|
1254
|
-
* @private
|
|
1255
|
-
*/
|
|
1256
|
-
private initializeManagers;
|
|
1257
|
-
/**
|
|
1258
|
-
* 执行完整的编译流程
|
|
1259
|
-
*
|
|
1260
|
-
* 该方法执行以下步骤:
|
|
1261
|
-
* 1. 环境初始化:清理旧输出(如果禁用缓存)并初始化 Vite 项目环境
|
|
1262
|
-
* 2. Vue 文件编译:批量处理所有 .vue 文件
|
|
1263
|
-
* 3. Script 文件编译:批量处理所有 .js/.ts 文件
|
|
1264
|
-
* 4. 资源文件拷贝:处理剩余的非编译文件
|
|
1265
|
-
* 5. 统计输出:显示编译结果和性能统计
|
|
1266
|
-
*
|
|
1267
|
-
* @async
|
|
1268
|
-
* @throws {Error} 当编译过程中发生致命错误时抛出
|
|
1269
|
-
* @returns {Promise<void>}
|
|
1270
|
-
*/
|
|
1271
|
-
execute(): Promise<void>;
|
|
1272
|
-
/**
|
|
1273
|
-
* 处理单个 Vue 单文件组件(SFC)
|
|
1274
|
-
*
|
|
1275
|
-
* 此方法主要用于 CLI 的 watch 模式,当检测到文件变更时调用。
|
|
1276
|
-
* 支持增量编译,如果文件未变更则跳过编译。
|
|
1277
|
-
*
|
|
1278
|
-
* @async
|
|
1279
|
-
* @param filePath - Vue 文件的绝对路径
|
|
1280
|
-
* @param existingCache - 可选的预加载缓存对象,用于增量编译
|
|
1281
|
-
* @returns {Promise<SFCUnit | undefined>} 编译单元对象,如果跳过编译则返回 undefined
|
|
1282
|
-
* @see {@link FileProcessor.processSFC}
|
|
1283
|
-
*/
|
|
1284
|
-
processSFC(filePath: string, existingCache?: LoadedCache<Vue2ReactCacheMeta>): Promise<SFCUnit | undefined>;
|
|
1285
|
-
/**
|
|
1286
|
-
* 处理单个 JavaScript/TypeScript 脚本文件
|
|
1287
|
-
*
|
|
1288
|
-
* 此方法主要用于 CLI 的 watch 模式,当检测到文件变更时调用。
|
|
1289
|
-
* 支持增量编译,如果文件未变更则跳过编译。
|
|
1290
|
-
*
|
|
1291
|
-
* @async
|
|
1292
|
-
* @param filePath - 脚本文件的绝对路径
|
|
1293
|
-
* @param existingCache - 可选的预加载缓存对象,用于增量编译
|
|
1294
|
-
* @returns {Promise<ScriptUnit | undefined>} 编译单元对象,如果跳过编译则返回 undefined
|
|
1295
|
-
* @see {@link FileProcessor.processScript}
|
|
1296
|
-
*/
|
|
1297
|
-
processScript(filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<ScriptUnit | undefined>;
|
|
1298
|
-
/**
|
|
1299
|
-
* 处理单个 CSS/LESS/SCSS 样式文件
|
|
1300
|
-
*
|
|
1301
|
-
* 此方法主要用于 CLI 的 watch 模式,当检测到文件变更时调用。
|
|
1302
|
-
* 支持增量编译,如果文件未变更则跳过编译。
|
|
1303
|
-
*
|
|
1304
|
-
* @async
|
|
1305
|
-
* @param filePath - style 文件的绝对路径
|
|
1306
|
-
* @param existingCache - 可选的预加载缓存对象,用于增量编译
|
|
1307
|
-
* @returns {Promise<ScriptUnit | undefined>} 编译单元对象,如果跳过编译则返回 undefined
|
|
1308
|
-
* @see {@link FileProcessor.processStyle}
|
|
1309
|
-
*/
|
|
1310
|
-
processStyle(filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<StyleUnit | undefined>;
|
|
1311
|
-
/**
|
|
1312
|
-
* 处理单个文件(Vue 或 Script)
|
|
1313
|
-
*
|
|
1314
|
-
* 通用的文件处理方法,根据 CacheKey 类型自动选择处理逻辑。
|
|
1315
|
-
* 主要用于内部调用和统一的文件处理接口。
|
|
1316
|
-
*
|
|
1317
|
-
* @async
|
|
1318
|
-
* @param key - 文件类型标识(SFC 或 SCRIPT)
|
|
1319
|
-
* @param filePath - 文件的绝对路径
|
|
1320
|
-
* @param existingCache - 可选的预加载缓存对象
|
|
1321
|
-
* @returns {Promise<SFCUnit | ScriptUnit | undefined>} 编译单元对象
|
|
1322
|
-
* @see {@link FileProcessor.processFile}
|
|
1323
|
-
*/
|
|
1324
|
-
processFile(key: CacheKey, filePath: string, existingCache?: LoadedCache): Promise<CompilationUnit | undefined>;
|
|
1325
|
-
/**
|
|
1326
|
-
* 处理单个资源文件
|
|
1327
|
-
*
|
|
1328
|
-
* 比较文件与缓存,决定是否需要拷贝。
|
|
1329
|
-
* 资源文件包括图片、字体、样式文件等非编译文件。
|
|
1330
|
-
*
|
|
1331
|
-
* @async
|
|
1332
|
-
* @param filePath - 资源文件的绝对路径
|
|
1333
|
-
* @param existingCache - 可选的预加载缓存对象
|
|
1334
|
-
* @returns {Promise<FileCacheMeta>} 资源文件的缓存元数据
|
|
1335
|
-
* @see {@link AssetManager.processAsset}
|
|
1336
|
-
*/
|
|
1337
|
-
processAsset(filePath: string, existingCache?: LoadedCache<FileCacheMeta>): Promise<FileCacheMeta>;
|
|
1338
|
-
/**
|
|
1339
|
-
* 删除指定路径对应的输出文件和缓存
|
|
1340
|
-
*
|
|
1341
|
-
* 当源文件被删除或重命名时,需要清理对应的输出文件。
|
|
1342
|
-
* 主要用于 watch 模式下的文件删除处理。
|
|
1343
|
-
*
|
|
1344
|
-
* @async
|
|
1345
|
-
* @param targetPath - 源代码的路径(文件或文件夹)
|
|
1346
|
-
* @param type - 清理类型,指定是 SFC、SCRIPT 还是 ASSET
|
|
1347
|
-
* @returns {Promise<void>}
|
|
1348
|
-
* @see {@link CleanupManager.removeOutputPath}
|
|
1349
|
-
*/
|
|
1350
|
-
removeOutputPath(targetPath: string, type: CacheKey): Promise<void>;
|
|
1351
|
-
/**
|
|
1352
|
-
* 获取跳过的文件数量
|
|
1353
|
-
*
|
|
1354
|
-
* 在增量编译中,未变更的文件会被跳过。
|
|
1355
|
-
* 此方法返回当前编译会话中跳过的文件数量。
|
|
1356
|
-
*
|
|
1357
|
-
* @returns {number} 跳过的文件数量
|
|
1358
|
-
*/
|
|
1359
|
-
getSkippedCount(): number;
|
|
1360
|
-
/**
|
|
1361
|
-
* 重置跳过的文件数量
|
|
1362
|
-
*
|
|
1363
|
-
* 在每次新的编译会话开始时调用,重置计数器。
|
|
1364
|
-
*/
|
|
1365
|
-
resetSkippedCount(): void;
|
|
1366
|
-
/**
|
|
1367
|
-
* 显示编译统计信息
|
|
1368
|
-
*
|
|
1369
|
-
* 在编译完成后调用,显示以下信息:
|
|
1370
|
-
* 1. 编译耗时
|
|
1371
|
-
* 2. 输出目录
|
|
1372
|
-
* 3. 跳过的文件数量
|
|
1373
|
-
* 4. 处理的文件分类统计
|
|
1374
|
-
*
|
|
1375
|
-
* @private
|
|
1376
|
-
* @param endTime - 格式化后的编译耗时字符串
|
|
1377
|
-
* @param sfcCount - 处理的 Vue 文件数量
|
|
1378
|
-
* @param scriptCount - 处理的脚本文件数量
|
|
1379
|
-
* @param assetCount - 处理的资源文件数量
|
|
1380
|
-
*/
|
|
1381
|
-
private showCompileStats;
|
|
1382
|
-
}
|
|
1320
|
+
declare function generateComponent(ir: ReactIRDescriptor, ctx: ICompilationContext, options?: GeneratorOptions): GeneratorResult;
|
|
1383
1321
|
|
|
1384
|
-
|
|
1385
|
-
* @see {@link CompilerOptions}
|
|
1386
|
-
*/
|
|
1387
|
-
declare function defineConfig(options: CompilerOptions): CompilerOptions;
|
|
1322
|
+
declare function generateOnlyScript(ir: ReactIRDescriptor, ctx: ICompilationContext, options?: GeneratorOptions): GeneratorResult;
|
|
1388
1323
|
|
|
1389
1324
|
/**
|
|
1390
|
-
*
|
|
1325
|
+
* 代码生成的统一入口函数。
|
|
1391
1326
|
*
|
|
1392
|
-
*
|
|
1327
|
+
* 根据输入类型自动选择生成器:
|
|
1328
|
+
* - `sfc`: 生成完整的 React 组件(包含 JSX 和脚本)
|
|
1329
|
+
* - `script-*`: 仅生成脚本代码(如 .js、.ts)
|
|
1393
1330
|
*
|
|
1394
|
-
* @
|
|
1395
|
-
* @
|
|
1331
|
+
* @param ir - React 中间表示描述符,来自转换阶段的结果
|
|
1332
|
+
* @param ctx - 编译上下文,包含输入类型、源码等信息
|
|
1333
|
+
* @param options - 可选的生成器配置,如 Babel 生成选项和插件
|
|
1334
|
+
* @returns 生成结果对象,包含 AST、生成的代码和原始源码
|
|
1396
1335
|
*/
|
|
1397
|
-
declare
|
|
1398
|
-
}
|
|
1336
|
+
declare function generate(ir: ReactIRDescriptor, ctx: ICompilationContext, options?: GeneratorOptions): GeneratorResult;
|
|
1399
1337
|
|
|
1400
|
-
export { type AssetUnit, type BaseCompilationResult, BaseCompiler, type BaseUnit, type CacheCheckResult, CacheKey, type CacheList, type CacheMeta, type CompilationResult, type CompilationUnit, type CompilerOptions, type FileCacheMeta, FileCompiler, type FileMeta, type GeneratorOptions, type GeneratorResult, Helper, type LoadedCache, type ParseResult, type ParserOptions, type PluginRegister, type ReactIRDescriptor, type SFCCompilationResult, type SFCUnit, type ScriptCompilationResult, type ScriptUnit, type StyleCompilationResult, type StyleUnit, type TransformerOptions, VuReact, type Vue2ReactCacheMeta, defineConfig, generate, generateComponent, generateOnlyScript, parse, parseOnlyScript, parseSFC, transform };
|
|
1338
|
+
export { type AssetUnit, type BaseCompilationResult, BaseCompiler, type BaseUnit, type CacheCheckResult, CacheKey, type CacheList, type CacheMeta, type CompilationResult, type CompilationUnit, type CompilerOptions, type CompilerPlugins, type FileCacheMeta, FileCompiler, type FileMeta, type FormatConfig, type GeneratorOptions, type GeneratorResult, Helper, type LoadedCache, type LoggingConfig, type OutputConfig, type ParseResult, type ParserOptions, type PluginRegister, type ReactIRDescriptor, type RouterConfig, type SFCCompilationResult, type SFCUnit, type ScriptCacheMeta, type ScriptCompilationResult, type ScriptUnit, type StyleCacheMeta, type StyleCompilationResult, type StyleUnit, type TransformerOptions, type UserConfigFnObject, VuReact, type Vue2ReactCacheMeta, defineConfig, generate, generateComponent, generateOnlyScript, parse, parseOnlyScript, parseSFC, transform };
|