@vureact/compiler-core 1.4.0 → 1.5.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.en.md +286 -0
- package/README.md +76 -74
- package/lib/{chunk-NF5BSPYE.esm.js → chunk-IGLKQRRZ.esm.js} +296 -110
- package/lib/{chunk-IVRFEV6H.js → chunk-TSGO73AO.js} +419 -233
- package/lib/cli.esm.js +2 -2
- package/lib/cli.js +10 -10
- package/lib/compiler-core.d.cts +21 -195
- package/lib/compiler-core.d.ts +21 -195
- package/lib/compiler-core.esm.js +2 -2
- package/lib/compiler-core.js +3 -3
- package/package.json +99 -99
- package/README.zh.md +0 -284
package/lib/cli.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @vureact/compiler-core v1.
|
|
3
|
+
* @vureact/compiler-core v1.5.0
|
|
4
4
|
* (c) 2025-present Ruihong Zhong (Ryan John)
|
|
5
5
|
* @license MIT
|
|
6
6
|
*/
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getDirname,
|
|
14
14
|
normalizePath,
|
|
15
15
|
version
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-IGLKQRRZ.esm.js";
|
|
17
17
|
|
|
18
18
|
// src/cli/index.ts
|
|
19
19
|
import { cac } from "cac";
|
package/lib/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict"; function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
|
|
3
|
-
* @vureact/compiler-core v1.
|
|
3
|
+
* @vureact/compiler-core v1.5.0
|
|
4
4
|
* (c) 2025-present Ruihong Zhong (Ryan John)
|
|
5
5
|
* @license MIT
|
|
6
6
|
*/
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
var
|
|
16
|
+
var _chunkTSGO73AOjs = require('./chunk-TSGO73AO.js');
|
|
17
17
|
|
|
18
18
|
// src/cli/index.ts
|
|
19
19
|
var _cac = require('cac');
|
|
@@ -76,7 +76,7 @@ var _ora = require('ora'); var _ora2 = _interopRequireDefault(_ora);
|
|
|
76
76
|
|
|
77
77
|
function setupWatcher(compiler, config) {
|
|
78
78
|
const spinner = _ora2.default.call(void 0, );
|
|
79
|
-
const cmpHelper = new (0,
|
|
79
|
+
const cmpHelper = new (0, _chunkTSGO73AOjs.Helper)(config);
|
|
80
80
|
const watcher = _chokidar2.default.watch(cmpHelper.getInputPath(), {
|
|
81
81
|
ignored: cmpHelper.getExcludes(),
|
|
82
82
|
persistent: true,
|
|
@@ -111,7 +111,7 @@ function setupWatcher(compiler, config) {
|
|
|
111
111
|
const fn = processors[ext];
|
|
112
112
|
const unit = await fn(filePath);
|
|
113
113
|
cmpHelper.printCoreLogs();
|
|
114
|
-
cmpHelper.printCompileInfo(filePath,
|
|
114
|
+
cmpHelper.printCompileInfo(filePath, _chunkTSGO73AOjs.calcElapsedTime.call(void 0, startTime));
|
|
115
115
|
if (unit) {
|
|
116
116
|
await _optionalChain([config, 'access', _5 => _5.onChange, 'optionalCall', _6 => _6(event, unit)]);
|
|
117
117
|
}
|
|
@@ -120,7 +120,7 @@ function setupWatcher(compiler, config) {
|
|
|
120
120
|
await compiler.processAsset(filePath);
|
|
121
121
|
cmpHelper.print(
|
|
122
122
|
_kleur2.default.blue("Copied Asset"),
|
|
123
|
-
_kleur2.default.dim(
|
|
123
|
+
_kleur2.default.dim(_chunkTSGO73AOjs.normalizePath.call(void 0, cmpHelper.relativePath(filePath)))
|
|
124
124
|
);
|
|
125
125
|
}
|
|
126
126
|
spinner.stop();
|
|
@@ -133,7 +133,7 @@ function setupWatcher(compiler, config) {
|
|
|
133
133
|
await compiler.removeOutputPath(filePath, type2);
|
|
134
134
|
cmpHelper.print(
|
|
135
135
|
_kleur2.default.yellow("Removed"),
|
|
136
|
-
_kleur2.default.dim(
|
|
136
|
+
_kleur2.default.dim(_chunkTSGO73AOjs.normalizePath.call(void 0, cmpHelper.relativePath(filePath)))
|
|
137
137
|
);
|
|
138
138
|
};
|
|
139
139
|
if (type === "unlink") {
|
|
@@ -166,7 +166,7 @@ async function resolveAction(root, options) {
|
|
|
166
166
|
const projectRoot = root ? _path2.default.resolve(process.cwd(), root) : process.cwd();
|
|
167
167
|
const userConfig = await loadUserConfig(projectRoot);
|
|
168
168
|
const finalConfig = mergeConfig(projectRoot, options, userConfig);
|
|
169
|
-
const compiler = new (0,
|
|
169
|
+
const compiler = new (0, _chunkTSGO73AOjs.VuReact)(finalConfig);
|
|
170
170
|
await compiler.execute();
|
|
171
171
|
if (finalConfig.watch) {
|
|
172
172
|
setupWatcher(compiler, finalConfig);
|
|
@@ -189,7 +189,7 @@ function resolveOptions(command) {
|
|
|
189
189
|
|
|
190
190
|
|
|
191
191
|
var _updatenotifier = require('update-notifier'); var _updatenotifier2 = _interopRequireDefault(_updatenotifier);
|
|
192
|
-
var __dirname =
|
|
192
|
+
var __dirname = _chunkTSGO73AOjs.getDirname.call(void 0, import.meta.url);
|
|
193
193
|
function checkForUpdates() {
|
|
194
194
|
try {
|
|
195
195
|
const possiblePaths = [
|
|
@@ -229,7 +229,7 @@ function checkForUpdates() {
|
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
// src/cli/index.ts
|
|
232
|
-
var [programName] = Object.keys(
|
|
232
|
+
var [programName] = Object.keys(_chunkTSGO73AOjs.bin);
|
|
233
233
|
var cli = _cac.cac.call(void 0, programName);
|
|
234
234
|
checkForUpdates();
|
|
235
235
|
var buildCommand = cli.command("build [root]", "Compile Vue3 to React (one-time)");
|
|
@@ -240,4 +240,4 @@ var watchCommand = cli.command("watch [root]", "Compile Vue3 to React and watch
|
|
|
240
240
|
resolveOptions(watchCommand).action((root, options) => {
|
|
241
241
|
resolveAction(root, { ...options, watch: true });
|
|
242
242
|
});
|
|
243
|
-
cli.help().version(
|
|
243
|
+
cli.help().version(_chunkTSGO73AOjs.version).parse();
|
package/lib/compiler-core.d.cts
CHANGED
|
@@ -472,6 +472,23 @@ interface OutputConfig {
|
|
|
472
472
|
* ]
|
|
473
473
|
*/
|
|
474
474
|
ignoreAssets?: string[];
|
|
475
|
+
/**
|
|
476
|
+
* Customize the generated package.json file.
|
|
477
|
+
* This function receives the default package.json object
|
|
478
|
+
* and should return the modified version.
|
|
479
|
+
*
|
|
480
|
+
* @note This option only takes effect when `bootstrapVite` is enabled.
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* ```js
|
|
484
|
+
* packageJson: (defaultPkg) => {
|
|
485
|
+
* // Modify and return the copy
|
|
486
|
+
* defaultPkg.dependencies['my-library'] = '^1.0.0';
|
|
487
|
+
* return defaultPkg;
|
|
488
|
+
* }
|
|
489
|
+
* ```
|
|
490
|
+
*/
|
|
491
|
+
packageJson?: (defaultPkg: Record<string, any>) => Record<string, any>;
|
|
475
492
|
}
|
|
476
493
|
interface RouterConfig {
|
|
477
494
|
/**
|
|
@@ -836,7 +853,7 @@ declare class ViteBootstrapper {
|
|
|
836
853
|
/**
|
|
837
854
|
* 利用 Vite 官方脚手架创建标准 React 环境
|
|
838
855
|
*/
|
|
839
|
-
bootstrapIfNeeded(): Promise<boolean>;
|
|
856
|
+
bootstrapIfNeeded(): Promise<boolean | undefined>;
|
|
840
857
|
/**
|
|
841
858
|
* 执行 vite 创建命令
|
|
842
859
|
*/
|
|
@@ -928,74 +945,9 @@ interface ParserOptions {
|
|
|
928
945
|
* @param source - Vue 单文件组件的源码字符串
|
|
929
946
|
* @param ctx - 编译上下文对象
|
|
930
947
|
* @param plugins - 可选的插件注册表,用于对解析结果进行自定义处理和增强
|
|
948
|
+
*
|
|
931
949
|
* @returns 解析结果对象,包含模板、脚本、样式块的解析信息
|
|
932
950
|
* @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
951
|
*/
|
|
1000
952
|
declare function parseSFC(source: string, ctx: ICompilationContext, options?: ParserOptions): ParseResult;
|
|
1001
953
|
|
|
@@ -1166,66 +1118,8 @@ interface TransformerOptions {
|
|
|
1166
1118
|
* @param ast - Vue SFC 的解析结果,来自 {@link parse} 函数的返回值
|
|
1167
1119
|
* @param ctx - 编译上下文对象
|
|
1168
1120
|
* @param plugins - 可选的插件注册表,用于对转换结果进行自定义处理和增强
|
|
1169
|
-
* @returns React 中间表示描述符,包含模板、脚本和样式的转换结果
|
|
1170
|
-
*
|
|
1171
|
-
* @remarks
|
|
1172
|
-
* - 模板转换:将 Vue 模板 AST 转换为 React 可用的模板 IR
|
|
1173
|
-
* - 脚本转换:将 Vue 脚本 AST 转换为 React 可用的脚本 IR
|
|
1174
|
-
* - 样式处理:提取样式块内容,保留原始 CSS 字符串
|
|
1175
|
-
* - 插件支持:支持通过插件对转换结果进行自定义处理
|
|
1176
1121
|
*
|
|
1177
|
-
* @
|
|
1178
|
-
* ```typescript
|
|
1179
|
-
* // 转换示例
|
|
1180
|
-
*
|
|
1181
|
-
* const ctx: ICompilationContext = {
|
|
1182
|
-
* filename: 'MyComponent.vue',
|
|
1183
|
-
* // 其他上下文配置...
|
|
1184
|
-
* };
|
|
1185
|
-
*
|
|
1186
|
-
* // 1. 首先解析 Vue SFC
|
|
1187
|
-
* const parseResult = parse(vueSource, ctx);
|
|
1188
|
-
*
|
|
1189
|
-
* // 2. 将解析结果转换为 React IR
|
|
1190
|
-
* const reactIR = transform(parseResult, ctx);
|
|
1191
|
-
*
|
|
1192
|
-
* // 访问转换结果
|
|
1193
|
-
* console.log(reactIR.template); // 模板转换结果
|
|
1194
|
-
* console.log(reactIR.script); // 脚本转换结果
|
|
1195
|
-
* console.log(reactIR.style); // 样式内容字符串
|
|
1196
|
-
*
|
|
1197
|
-
* // 使用可选插件配置,进行自定义处理
|
|
1198
|
-
* const options: TransformerOptions = {
|
|
1199
|
-
* plugins: {
|
|
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
|
-
* };
|
|
1210
|
-
* },
|
|
1211
|
-
*
|
|
1212
|
-
* // 插2:样式预处理
|
|
1213
|
-
* preprocessStyles: (result, ctx) => {
|
|
1214
|
-
* if (result.style) {
|
|
1215
|
-
* // 对样式进行预处理,如添加前缀等
|
|
1216
|
-
* result.style = addVendorPrefixes(result.style);
|
|
1217
|
-
* result.style = minifyCSS(result.style);
|
|
1218
|
-
* }
|
|
1219
|
-
* },
|
|
1220
|
-
* }
|
|
1221
|
-
* }
|
|
1222
|
-
*
|
|
1223
|
-
* // 使用多个插件进行转换
|
|
1224
|
-
* const reactIRWithPlugins = transform(parseResult, ctx, plugins);
|
|
1225
|
-
*
|
|
1226
|
-
* // 插件处理后的结果包含自定义数据
|
|
1227
|
-
* console.log(reactIRWithPlugins.metadata);
|
|
1228
|
-
* ```
|
|
1122
|
+
* @returns React 中间表示描述符,包含模板、脚本和样式的转换结果
|
|
1229
1123
|
*/
|
|
1230
1124
|
declare function transform(ast: ParseResult, ctx: ICompilationContext, options?: TransformerOptions): ReactIRDescriptor;
|
|
1231
1125
|
|
|
@@ -1246,76 +1140,8 @@ interface GeneratorResult {
|
|
|
1246
1140
|
* @param ir - React 中间表示描述符,来自 {@link transform} 函数的返回值
|
|
1247
1141
|
* @param ctx - 编译上下文对象
|
|
1248
1142
|
* @param options - 可选的生成选项,包括 Babel 生成器选项和插件
|
|
1249
|
-
* @returns 生成结果对象,包含 AST、生成的代码和原始源码引用
|
|
1250
1143
|
*
|
|
1251
|
-
* @
|
|
1252
|
-
* - JSX 构建:将模板 IR 转换为 JSX AST 节点
|
|
1253
|
-
* - 脚本构建:将脚本 IR 与 JSX 结合,构建完整的程序 AST
|
|
1254
|
-
* - 代码生成:使用 Babel 生成器将 AST 转换为源代码字符串
|
|
1255
|
-
* - 插件支持:支持通过插件对生成结果进行自定义处理
|
|
1256
|
-
*
|
|
1257
|
-
* @example
|
|
1258
|
-
* ```typescript
|
|
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);
|
|
1269
|
-
*
|
|
1270
|
-
* // 2. 转换为 React IR
|
|
1271
|
-
* const reactIR = transform(parseResult, ctx);
|
|
1272
|
-
*
|
|
1273
|
-
* // 使用可选配置项进行自定义处理
|
|
1274
|
-
* const generatorOptions: GeneratorOptions = {
|
|
1275
|
-
* // 配置 jsesc 避免 Unicode 转义
|
|
1276
|
-
* jsescOption: {
|
|
1277
|
-
* minimal: true,
|
|
1278
|
-
* quotes: 'single'
|
|
1279
|
-
* },
|
|
1280
|
-
* minified: true,
|
|
1281
|
-
*
|
|
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
|
-
* },
|
|
1293
|
-
*
|
|
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
|
-
* });
|
|
1302
|
-
*
|
|
1303
|
-
* if (issues.length > 0) {
|
|
1304
|
-
* result.lintIssues = issues;
|
|
1305
|
-
* console.warn(`Found ${issues.length} lint issues in generated code`);
|
|
1306
|
-
* }
|
|
1307
|
-
* },
|
|
1308
|
-
* },
|
|
1309
|
-
* };
|
|
1310
|
-
*
|
|
1311
|
-
* // 3. 生成 React 组件
|
|
1312
|
-
* const generated = generateComponent(reactIR, ctx, generatorOptions);
|
|
1313
|
-
*
|
|
1314
|
-
* // 访问生成结果
|
|
1315
|
-
* console.log(generated.ast); // 完整的 Babel AST
|
|
1316
|
-
* console.log(generated.code); // 生成的 React 代码
|
|
1317
|
-
* console.log(generated.source); // 原始 Vue 源码
|
|
1318
|
-
* ```
|
|
1144
|
+
* @returns 生成结果对象,包含 AST、生成的代码和原始源码引用
|
|
1319
1145
|
*/
|
|
1320
1146
|
declare function generateComponent(ir: ReactIRDescriptor, ctx: ICompilationContext, options?: GeneratorOptions): GeneratorResult;
|
|
1321
1147
|
|
package/lib/compiler-core.d.ts
CHANGED
|
@@ -472,6 +472,23 @@ interface OutputConfig {
|
|
|
472
472
|
* ]
|
|
473
473
|
*/
|
|
474
474
|
ignoreAssets?: string[];
|
|
475
|
+
/**
|
|
476
|
+
* Customize the generated package.json file.
|
|
477
|
+
* This function receives the default package.json object
|
|
478
|
+
* and should return the modified version.
|
|
479
|
+
*
|
|
480
|
+
* @note This option only takes effect when `bootstrapVite` is enabled.
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* ```js
|
|
484
|
+
* packageJson: (defaultPkg) => {
|
|
485
|
+
* // Modify and return the copy
|
|
486
|
+
* defaultPkg.dependencies['my-library'] = '^1.0.0';
|
|
487
|
+
* return defaultPkg;
|
|
488
|
+
* }
|
|
489
|
+
* ```
|
|
490
|
+
*/
|
|
491
|
+
packageJson?: (defaultPkg: Record<string, any>) => Record<string, any>;
|
|
475
492
|
}
|
|
476
493
|
interface RouterConfig {
|
|
477
494
|
/**
|
|
@@ -836,7 +853,7 @@ declare class ViteBootstrapper {
|
|
|
836
853
|
/**
|
|
837
854
|
* 利用 Vite 官方脚手架创建标准 React 环境
|
|
838
855
|
*/
|
|
839
|
-
bootstrapIfNeeded(): Promise<boolean>;
|
|
856
|
+
bootstrapIfNeeded(): Promise<boolean | undefined>;
|
|
840
857
|
/**
|
|
841
858
|
* 执行 vite 创建命令
|
|
842
859
|
*/
|
|
@@ -928,74 +945,9 @@ interface ParserOptions {
|
|
|
928
945
|
* @param source - Vue 单文件组件的源码字符串
|
|
929
946
|
* @param ctx - 编译上下文对象
|
|
930
947
|
* @param plugins - 可选的插件注册表,用于对解析结果进行自定义处理和增强
|
|
948
|
+
*
|
|
931
949
|
* @returns 解析结果对象,包含模板、脚本、样式块的解析信息
|
|
932
950
|
* @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
951
|
*/
|
|
1000
952
|
declare function parseSFC(source: string, ctx: ICompilationContext, options?: ParserOptions): ParseResult;
|
|
1001
953
|
|
|
@@ -1166,66 +1118,8 @@ interface TransformerOptions {
|
|
|
1166
1118
|
* @param ast - Vue SFC 的解析结果,来自 {@link parse} 函数的返回值
|
|
1167
1119
|
* @param ctx - 编译上下文对象
|
|
1168
1120
|
* @param plugins - 可选的插件注册表,用于对转换结果进行自定义处理和增强
|
|
1169
|
-
* @returns React 中间表示描述符,包含模板、脚本和样式的转换结果
|
|
1170
|
-
*
|
|
1171
|
-
* @remarks
|
|
1172
|
-
* - 模板转换:将 Vue 模板 AST 转换为 React 可用的模板 IR
|
|
1173
|
-
* - 脚本转换:将 Vue 脚本 AST 转换为 React 可用的脚本 IR
|
|
1174
|
-
* - 样式处理:提取样式块内容,保留原始 CSS 字符串
|
|
1175
|
-
* - 插件支持:支持通过插件对转换结果进行自定义处理
|
|
1176
1121
|
*
|
|
1177
|
-
* @
|
|
1178
|
-
* ```typescript
|
|
1179
|
-
* // 转换示例
|
|
1180
|
-
*
|
|
1181
|
-
* const ctx: ICompilationContext = {
|
|
1182
|
-
* filename: 'MyComponent.vue',
|
|
1183
|
-
* // 其他上下文配置...
|
|
1184
|
-
* };
|
|
1185
|
-
*
|
|
1186
|
-
* // 1. 首先解析 Vue SFC
|
|
1187
|
-
* const parseResult = parse(vueSource, ctx);
|
|
1188
|
-
*
|
|
1189
|
-
* // 2. 将解析结果转换为 React IR
|
|
1190
|
-
* const reactIR = transform(parseResult, ctx);
|
|
1191
|
-
*
|
|
1192
|
-
* // 访问转换结果
|
|
1193
|
-
* console.log(reactIR.template); // 模板转换结果
|
|
1194
|
-
* console.log(reactIR.script); // 脚本转换结果
|
|
1195
|
-
* console.log(reactIR.style); // 样式内容字符串
|
|
1196
|
-
*
|
|
1197
|
-
* // 使用可选插件配置,进行自定义处理
|
|
1198
|
-
* const options: TransformerOptions = {
|
|
1199
|
-
* plugins: {
|
|
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
|
-
* };
|
|
1210
|
-
* },
|
|
1211
|
-
*
|
|
1212
|
-
* // 插2:样式预处理
|
|
1213
|
-
* preprocessStyles: (result, ctx) => {
|
|
1214
|
-
* if (result.style) {
|
|
1215
|
-
* // 对样式进行预处理,如添加前缀等
|
|
1216
|
-
* result.style = addVendorPrefixes(result.style);
|
|
1217
|
-
* result.style = minifyCSS(result.style);
|
|
1218
|
-
* }
|
|
1219
|
-
* },
|
|
1220
|
-
* }
|
|
1221
|
-
* }
|
|
1222
|
-
*
|
|
1223
|
-
* // 使用多个插件进行转换
|
|
1224
|
-
* const reactIRWithPlugins = transform(parseResult, ctx, plugins);
|
|
1225
|
-
*
|
|
1226
|
-
* // 插件处理后的结果包含自定义数据
|
|
1227
|
-
* console.log(reactIRWithPlugins.metadata);
|
|
1228
|
-
* ```
|
|
1122
|
+
* @returns React 中间表示描述符,包含模板、脚本和样式的转换结果
|
|
1229
1123
|
*/
|
|
1230
1124
|
declare function transform(ast: ParseResult, ctx: ICompilationContext, options?: TransformerOptions): ReactIRDescriptor;
|
|
1231
1125
|
|
|
@@ -1246,76 +1140,8 @@ interface GeneratorResult {
|
|
|
1246
1140
|
* @param ir - React 中间表示描述符,来自 {@link transform} 函数的返回值
|
|
1247
1141
|
* @param ctx - 编译上下文对象
|
|
1248
1142
|
* @param options - 可选的生成选项,包括 Babel 生成器选项和插件
|
|
1249
|
-
* @returns 生成结果对象,包含 AST、生成的代码和原始源码引用
|
|
1250
1143
|
*
|
|
1251
|
-
* @
|
|
1252
|
-
* - JSX 构建:将模板 IR 转换为 JSX AST 节点
|
|
1253
|
-
* - 脚本构建:将脚本 IR 与 JSX 结合,构建完整的程序 AST
|
|
1254
|
-
* - 代码生成:使用 Babel 生成器将 AST 转换为源代码字符串
|
|
1255
|
-
* - 插件支持:支持通过插件对生成结果进行自定义处理
|
|
1256
|
-
*
|
|
1257
|
-
* @example
|
|
1258
|
-
* ```typescript
|
|
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);
|
|
1269
|
-
*
|
|
1270
|
-
* // 2. 转换为 React IR
|
|
1271
|
-
* const reactIR = transform(parseResult, ctx);
|
|
1272
|
-
*
|
|
1273
|
-
* // 使用可选配置项进行自定义处理
|
|
1274
|
-
* const generatorOptions: GeneratorOptions = {
|
|
1275
|
-
* // 配置 jsesc 避免 Unicode 转义
|
|
1276
|
-
* jsescOption: {
|
|
1277
|
-
* minimal: true,
|
|
1278
|
-
* quotes: 'single'
|
|
1279
|
-
* },
|
|
1280
|
-
* minified: true,
|
|
1281
|
-
*
|
|
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
|
-
* },
|
|
1293
|
-
*
|
|
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
|
-
* });
|
|
1302
|
-
*
|
|
1303
|
-
* if (issues.length > 0) {
|
|
1304
|
-
* result.lintIssues = issues;
|
|
1305
|
-
* console.warn(`Found ${issues.length} lint issues in generated code`);
|
|
1306
|
-
* }
|
|
1307
|
-
* },
|
|
1308
|
-
* },
|
|
1309
|
-
* };
|
|
1310
|
-
*
|
|
1311
|
-
* // 3. 生成 React 组件
|
|
1312
|
-
* const generated = generateComponent(reactIR, ctx, generatorOptions);
|
|
1313
|
-
*
|
|
1314
|
-
* // 访问生成结果
|
|
1315
|
-
* console.log(generated.ast); // 完整的 Babel AST
|
|
1316
|
-
* console.log(generated.code); // 生成的 React 代码
|
|
1317
|
-
* console.log(generated.source); // 原始 Vue 源码
|
|
1318
|
-
* ```
|
|
1144
|
+
* @returns 生成结果对象,包含 AST、生成的代码和原始源码引用
|
|
1319
1145
|
*/
|
|
1320
1146
|
declare function generateComponent(ir: ReactIRDescriptor, ctx: ICompilationContext, options?: GeneratorOptions): GeneratorResult;
|
|
1321
1147
|
|
package/lib/compiler-core.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @vureact/compiler-core v1.
|
|
2
|
+
* @vureact/compiler-core v1.5.0
|
|
3
3
|
* (c) 2025-present Ruihong Zhong (Ryan John)
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
parseOnlyScript,
|
|
19
19
|
parseSFC,
|
|
20
20
|
transform
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-IGLKQRRZ.esm.js";
|
|
22
22
|
export {
|
|
23
23
|
BaseCompiler,
|
|
24
24
|
CacheKey,
|
package/lib/compiler-core.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});/**
|
|
2
|
-
* @vureact/compiler-core v1.
|
|
2
|
+
* @vureact/compiler-core v1.5.0
|
|
3
3
|
* (c) 2025-present Ruihong Zhong (Ryan John)
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var _chunkTSGO73AOjs = require('./chunk-TSGO73AO.js');
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
|
|
@@ -33,4 +33,4 @@ var _chunkIVRFEV6Hjs = require('./chunk-IVRFEV6H.js');
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
exports.BaseCompiler =
|
|
36
|
+
exports.BaseCompiler = _chunkTSGO73AOjs.BaseCompiler; exports.CacheKey = _chunkTSGO73AOjs.CacheKey; exports.FileCompiler = _chunkTSGO73AOjs.FileCompiler; exports.Helper = _chunkTSGO73AOjs.Helper; exports.VuReact = _chunkTSGO73AOjs.VuReact; exports.defineConfig = _chunkTSGO73AOjs.defineConfig; exports.generate = _chunkTSGO73AOjs.generate; exports.generateComponent = _chunkTSGO73AOjs.generateComponent; exports.generateOnlyScript = _chunkTSGO73AOjs.generateOnlyScript; exports.parse = _chunkTSGO73AOjs.parse; exports.parseOnlyScript = _chunkTSGO73AOjs.parseOnlyScript; exports.parseSFC = _chunkTSGO73AOjs.parseSFC; exports.transform = _chunkTSGO73AOjs.transform;
|