@vureact/compiler-core 1.4.0 → 1.5.1

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @vureact/compiler-core v1.4.0
2
+ * @vureact/compiler-core v1.5.1
3
3
  * (c) 2025-present Ruihong Zhong (Ryan John)
4
4
  * @license MIT
5
5
  */
@@ -35,11 +35,11 @@ var PACKAGE_NAME = {
35
35
  var RUNTIME_PACKAGES = {
36
36
  router: {
37
37
  name: PACKAGE_NAME.router,
38
- version: "^1.0.0"
38
+ version: "^2.0.1"
39
39
  },
40
40
  runtime: {
41
41
  name: PACKAGE_NAME.runtime,
42
- version: "^1.0.0"
42
+ version: "^1.0.1"
43
43
  }
44
44
  };
45
45
  var STYLE_MODULE_NAME = "$style";
@@ -1385,7 +1385,12 @@ function generateComponent(ir, ctx, options) {
1385
1385
  quotes: "single"
1386
1386
  // 使用单引号
1387
1387
  },
1388
- minified: true,
1388
+ minified: false,
1389
+ // 不压缩输出内容
1390
+ retainLines: false,
1391
+ // 不保留行号
1392
+ retainFunctionParens: true,
1393
+ // 保留函数括号
1389
1394
  ...options
1390
1395
  });
1391
1396
  const result = {
@@ -1461,6 +1466,7 @@ function resolveScript(descriptor, ctx, pResult) {
1461
1466
  source: scriptBlock
1462
1467
  };
1463
1468
  const options = getBabelParseOptions(scriptBlock.lang, "script", ctx.filename);
1469
+ resolveCtxData(scriptBlock, ctx);
1464
1470
  if (descriptor.script) {
1465
1471
  const { code, ast, name } = extractSetupBodyToTopLevel(scriptBlock.content, options);
1466
1472
  if (ast) {
@@ -1480,12 +1486,21 @@ function resolveScript(descriptor, ctx, pResult) {
1480
1486
  logger.warn(msg, { file: ctx.filename });
1481
1487
  });
1482
1488
  }
1483
- const source = scriptBlock.content;
1484
- ctx.scriptData.source = source;
1485
- ctx.compName = extractCompName(source);
1486
- ctx.scriptData.lang = scriptBlock.lang || "js";
1487
1489
  pResult.script = result;
1488
1490
  }
1491
+ function resolveCtxData(scriptBlock, ctx) {
1492
+ let { content, lang } = scriptBlock;
1493
+ const resolveVRComment = (source) => {
1494
+ const regx = /\/\/\s*@vr-name:\s*(\w+)/;
1495
+ const nameMatch = source.match(regx);
1496
+ content = content.replace(regx, "");
1497
+ return nameMatch?.[1]?.trim() || "";
1498
+ };
1499
+ ctx.compName = resolveVRComment(content);
1500
+ ctx.scriptData.source = content;
1501
+ ctx.scriptData.lang = lang || "js";
1502
+ scriptBlock.content = content;
1503
+ }
1489
1504
  function extractSetupBodyToTopLevel(content, options) {
1490
1505
  let name = "";
1491
1506
  try {
@@ -1549,10 +1564,6 @@ function extractSetupBodyToTopLevel(content, options) {
1549
1564
  return { name, code: content };
1550
1565
  }
1551
1566
  }
1552
- function extractCompName(source) {
1553
- const nameMatch = source.match(/@vr-name:\s*(\w+)/);
1554
- return nameMatch?.[1]?.trim() || "";
1555
- }
1556
1567
 
1557
1568
  // src/core/parse/sfc/process/resolve-script-meta.ts
1558
1569
  import { traverse } from "@babel/core";
@@ -1827,12 +1838,6 @@ function resolveStyles(descriptor, ctx, result) {
1827
1838
  { file: filename }
1828
1839
  );
1829
1840
  }
1830
- if (content.includes("@import")) {
1831
- logger.warn(
1832
- "Detected @import in scoped style. Imported styles remain global. Consider inlining them to preserve scoping.",
1833
- { file: filename }
1834
- );
1835
- }
1836
1841
  const { code, fileExt } = resolveLessSass(content, {
1837
1842
  lang,
1838
1843
  filename,
@@ -1942,181 +1947,8 @@ import { parse as babelParse3 } from "@babel/parser";
1942
1947
  // src/core/transform/sfc/script/syntax-processor/index.ts
1943
1948
  import { traverse as traverse3 } from "@babel/core";
1944
1949
 
1945
- // src/core/transform/sfc/script/syntax-processor/postprocess/insert-css-import.ts
1946
- import * as t17 from "@babel/types";
1947
- function insertCSSImport(ctx) {
1948
- const { inputType } = ctx;
1949
- if (inputType !== "sfc") return;
1950
- const { filePath, moduleName } = ctx.styleData;
1951
- if (!filePath) return;
1952
- const scriptIR = getScriptIR(ctx);
1953
- const filename = normalizePath(filePath).split("/").pop();
1954
- const importPath = `./${filename}`;
1955
- const importDecl = t17.importDeclaration(
1956
- !moduleName ? [] : [t17.importDefaultSpecifier(t17.identifier(moduleName))],
1957
- t17.stringLiteral(importPath)
1958
- );
1959
- scriptIR.imports.push(importDecl);
1960
- }
1961
-
1962
- // src/core/transform/sfc/script/syntax-processor/postprocess/insert-required-imports.ts
1963
- import * as t18 from "@babel/types";
1964
-
1965
- // src/core/transform/shared.ts
1966
- function recordImport(ctx, pkg, name, onDemand = true) {
1967
- const { imports } = ctx;
1968
- if (isTypeOnlyImport(name)) {
1969
- name = `type ${name}`;
1970
- }
1971
- if (imports.has(pkg)) {
1972
- const list = imports.get(pkg);
1973
- const foundItem = list.find((item) => item.name === name);
1974
- if (!foundItem) {
1975
- list.push({ name, onDemand });
1976
- }
1977
- return;
1978
- }
1979
- imports.set(pkg, [{ name, onDemand }]);
1980
- }
1981
- function isTypeOnlyImport(name) {
1982
- const arr = [REACT_API_MAP.ReactNode];
1983
- return arr.includes(name);
1984
- }
1985
-
1986
- // src/core/transform/sfc/script/shared/replace-vue-suffix.ts
1987
- function replaceVueSuffix(ctx, node) {
1988
- if (!node.value.endsWith(".vue")) return;
1989
- const jsxFile = node.value.replace(/.vue$/, "");
1990
- node.value = jsxFile;
1991
- node.extra = { rawValue: jsxFile, raw: jsxFile };
1992
- }
1993
-
1994
- // src/core/transform/sfc/script/syntax-processor/postprocess/insert-required-imports.ts
1995
- function insertRequiredImports(ctx) {
1996
- const processedModules = /* @__PURE__ */ new Set();
1997
- let hasProcessedImports = false;
1998
- recordImport(ctx, PACKAGE_NAME.react, REACT_API_MAP.memo);
1999
- function resolveRequiredImport(path9) {
2000
- const { node } = path9;
2001
- const moduleName = node.source.value.toLowerCase();
2002
- const isVueLike = isVueEcosystemPackage(moduleName);
2003
- mergeImports(node, ctx);
2004
- if (processedModules.has(moduleName) && !path9.removed) {
2005
- path9.remove();
2006
- return;
2007
- }
2008
- processedModules.add(moduleName);
2009
- if (!hasProcessedImports) {
2010
- const required = createRequiredImports(ctx);
2011
- if (isVueLike) {
2012
- path9.replaceWithMultiple(required);
2013
- } else if (moduleName === PACKAGE_NAME.react) {
2014
- path9.insertAfter(required);
2015
- } else {
2016
- path9.insertBefore(required);
2017
- }
2018
- hasProcessedImports = true;
2019
- }
2020
- if (isVueLike && !path9.removed) {
2021
- path9.remove();
2022
- return;
2023
- }
2024
- replaceVueSuffix(ctx, node.source);
2025
- }
2026
- function resolveStyleFileExt(path9) {
2027
- if (!ctx.preprocessStyles) return;
2028
- const { node } = path9;
2029
- if (!node || !node.source || !node.source.value) return;
2030
- const importSource = node.source.value;
2031
- if (typeof importSource !== "string") return;
2032
- const styleExtRegex = /\.(less|sass|scss)$/i;
2033
- if (!styleExtRegex.test(importSource)) return;
2034
- const newSource = importSource.replace(styleExtRegex, ".css");
2035
- node.source.value = newSource;
2036
- }
2037
- return {
2038
- // 增加 Program.exit 兜底注入 required imports(处理无 ImportDeclaration 的 SFC)
2039
- Program: {
2040
- exit(path9) {
2041
- if (hasProcessedImports) return;
2042
- const required = createRequiredImports(ctx);
2043
- path9.unshiftContainer("body", required);
2044
- hasProcessedImports = true;
2045
- }
2046
- },
2047
- ImportDeclaration(path9) {
2048
- resolveRequiredImport(path9);
2049
- resolveStyleFileExt(path9);
2050
- }
2051
- };
2052
- }
2053
- function isVueEcosystemPackage(moduleName) {
2054
- if (moduleName.startsWith(".") || moduleName.startsWith("/") || moduleName.startsWith("file:")) {
2055
- return false;
2056
- }
2057
- if (moduleName.startsWith("@vue/")) {
2058
- return true;
2059
- }
2060
- if (moduleName === "vue-router" || moduleName.startsWith("vue-router/")) {
2061
- return true;
2062
- }
2063
- return VUE_PACKAGES.some((name) => moduleName === name || moduleName.startsWith(`${name}/`));
2064
- }
2065
- function mergeImports(currentNode, ctx) {
2066
- const moduleName = currentNode.source.value.toLowerCase();
2067
- const ctxImportItems = ctx.imports.get(moduleName);
2068
- if (!ctxImportItems?.length) {
2069
- return;
2070
- }
2071
- const currentImports = /* @__PURE__ */ new Set();
2072
- for (const spec of currentNode.specifiers) {
2073
- if (t18.isImportSpecifier(spec) && t18.isIdentifier(spec.imported)) {
2074
- currentImports.add(spec.imported.name);
2075
- }
2076
- if (t18.isImportDefaultSpecifier(spec) && t18.isIdentifier(spec.local)) {
2077
- currentImports.add(spec.local.name);
2078
- }
2079
- }
2080
- for (const item of ctxImportItems) {
2081
- if (currentImports.has(item.name)) return;
2082
- const local = t18.identifier(item.name);
2083
- const newNode = !item.onDemand ? t18.importDefaultSpecifier(local) : t18.importSpecifier(local, local);
2084
- currentNode.specifiers.push(newNode);
2085
- }
2086
- ctx.imports.delete(moduleName);
2087
- }
2088
- function createRequiredImports(ctx) {
2089
- const result = [];
2090
- const importMap = {};
2091
- ctx.imports.forEach((items, moduleName) => {
2092
- const specifier = [];
2093
- for (const item of items) {
2094
- const local = t18.identifier(item.name);
2095
- if (!item.onDemand) {
2096
- specifier.push(t18.importDefaultSpecifier(local));
2097
- } else {
2098
- specifier.push(t18.importSpecifier(local, local));
2099
- }
2100
- }
2101
- importMap[moduleName] = specifier;
2102
- });
2103
- for (const name in importMap) {
2104
- const specifiers = importMap[name];
2105
- const importDecl = t18.importDeclaration(specifiers, t18.stringLiteral(name));
2106
- if (name === PACKAGE_NAME.react) {
2107
- result.unshift(importDecl);
2108
- } else {
2109
- result.push(importDecl);
2110
- }
2111
- }
2112
- return result;
2113
- }
2114
-
2115
- // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-static-hoisting.ts
2116
- import * as t20 from "@babel/types";
2117
-
2118
1950
  // src/core/transform/sfc/script/shared/babel-utils.ts
2119
- import * as t19 from "@babel/types";
1951
+ import * as t17 from "@babel/types";
2120
1952
  function findRootVariablePath(path9) {
2121
1953
  const rootId = findRootIdentifier(path9.node);
2122
1954
  if (!rootId?.name) return null;
@@ -2127,10 +1959,10 @@ function findRootVariablePath(path9) {
2127
1959
  }
2128
1960
  function findRootIdentifier(node) {
2129
1961
  let current = node.object;
2130
- while (t19.isMemberExpression(current) || t19.isOptionalMemberExpression(current)) {
1962
+ while (t17.isMemberExpression(current) || t17.isOptionalMemberExpression(current)) {
2131
1963
  current = current.object;
2132
1964
  }
2133
- return t19.isIdentifier(current) ? current : null;
1965
+ return t17.isIdentifier(current) ? current : null;
2134
1966
  }
2135
1967
  function getVariableDeclaratorPath(path9) {
2136
1968
  if (path9.isVariableDeclarator()) {
@@ -2214,14 +2046,14 @@ function isPropertyName(path9) {
2214
2046
  }
2215
2047
  function replaceCallName(callExp, identifierName) {
2216
2048
  const { callee } = callExp;
2217
- if (!t19.isIdentifier(callee)) return;
2049
+ if (!t17.isIdentifier(callee)) return;
2218
2050
  callee.name = identifierName;
2219
2051
  if (callee.loc) {
2220
2052
  callee.loc.identifierName = identifierName;
2221
2053
  }
2222
2054
  }
2223
2055
  function replaceIdName(id, newName) {
2224
- if (!t19.isIdentifier(id)) return;
2056
+ if (!t17.isIdentifier(id)) return;
2225
2057
  id.name = newName;
2226
2058
  if (id.loc) {
2227
2059
  id.loc.identifierName = newName;
@@ -2231,69 +2063,110 @@ function stringValueToTSType(ctx, input, tsTypeAnnotation7) {
2231
2063
  const { filename, scriptData } = ctx;
2232
2064
  const exp = stringToExpr(input, scriptData.lang, filename);
2233
2065
  const ts = expressionToTSType(exp);
2234
- return tsTypeAnnotation7 ? t19.tsTypeAnnotation(ts) : ts;
2066
+ return tsTypeAnnotation7 ? t17.tsTypeAnnotation(ts) : ts;
2235
2067
  }
2236
2068
  function expressionToTSType(exp) {
2237
- if (t19.isStringLiteral(exp)) return t19.tsStringKeyword();
2238
- if (t19.isNumericLiteral(exp)) return t19.tsNumberKeyword();
2239
- if (t19.isBooleanLiteral(exp)) return t19.tsBooleanKeyword();
2240
- if (t19.isArrayExpression(exp)) return t19.tsArrayType(t19.tsAnyKeyword());
2241
- if (t19.isObjectExpression(exp)) {
2069
+ if (t17.isStringLiteral(exp)) return t17.tsStringKeyword();
2070
+ if (t17.isNumericLiteral(exp)) return t17.tsNumberKeyword();
2071
+ if (t17.isBooleanLiteral(exp)) return t17.tsBooleanKeyword();
2072
+ if (t17.isArrayExpression(exp)) return t17.tsArrayType(t17.tsAnyKeyword());
2073
+ if (t17.isObjectExpression(exp)) {
2242
2074
  const members = [];
2243
2075
  for (const p of exp.properties) {
2244
- if (!t19.isObjectProperty(p)) continue;
2076
+ if (!t17.isObjectProperty(p)) continue;
2245
2077
  let key;
2246
- if (t19.isIdentifier(p.key)) key = p.key.name;
2247
- else if (t19.isStringLiteral(p.key)) key = p.key.value;
2078
+ if (t17.isIdentifier(p.key)) key = p.key.name;
2079
+ else if (t17.isStringLiteral(p.key)) key = p.key.value;
2248
2080
  if (!key) continue;
2249
- if (t19.isExpression(p.value)) {
2081
+ if (t17.isExpression(p.value)) {
2250
2082
  members.push(
2251
- t19.tsPropertySignature(t19.identifier(key), t19.tsTypeAnnotation(expressionToTSType(p.value)))
2083
+ t17.tsPropertySignature(t17.identifier(key), t17.tsTypeAnnotation(expressionToTSType(p.value)))
2252
2084
  );
2253
2085
  } else {
2254
2086
  members.push(
2255
- t19.tsPropertySignature(t19.identifier(key), t19.tsTypeAnnotation(t19.tsAnyKeyword()))
2087
+ t17.tsPropertySignature(t17.identifier(key), t17.tsTypeAnnotation(t17.tsAnyKeyword()))
2256
2088
  );
2257
2089
  }
2258
2090
  }
2259
- return t19.tsTypeLiteral(members);
2091
+ return t17.tsTypeLiteral(members);
2260
2092
  }
2261
- if (t19.isArrowFunctionExpression(exp) || t19.isFunctionExpression(exp)) {
2093
+ if (t17.isArrowFunctionExpression(exp) || t17.isFunctionExpression(exp)) {
2262
2094
  const params = exp.params.map((p, i) => {
2263
- const id = t19.isIdentifier(p) ? t19.identifier(p.name) : t19.identifier(`arg${i}`);
2264
- id.typeAnnotation = t19.tsTypeAnnotation(t19.tsAnyKeyword());
2095
+ const id = t17.isIdentifier(p) ? t17.identifier(p.name) : t17.identifier(`arg${i}`);
2096
+ id.typeAnnotation = t17.tsTypeAnnotation(t17.tsAnyKeyword());
2265
2097
  return id;
2266
2098
  });
2267
- let returnType = t19.tsAnyKeyword();
2268
- if (t19.isBlockStatement(exp.body)) {
2099
+ let returnType = t17.tsAnyKeyword();
2100
+ if (t17.isBlockStatement(exp.body)) {
2269
2101
  for (const stmt of exp.body.body) {
2270
- if (t19.isReturnStatement(stmt) && stmt.argument) {
2271
- if (t19.isExpression(stmt.argument)) {
2102
+ if (t17.isReturnStatement(stmt) && stmt.argument) {
2103
+ if (t17.isExpression(stmt.argument)) {
2272
2104
  returnType = expressionToTSType(stmt.argument);
2273
2105
  break;
2274
2106
  }
2275
2107
  }
2276
2108
  }
2277
- } else if (t19.isExpression(exp.body)) {
2109
+ } else if (t17.isExpression(exp.body)) {
2278
2110
  returnType = expressionToTSType(exp.body);
2279
2111
  }
2280
- return t19.tsFunctionType(null, params, t19.tsTypeAnnotation(returnType));
2112
+ return t17.tsFunctionType(null, params, t17.tsTypeAnnotation(returnType));
2281
2113
  }
2282
- return t19.tsAnyKeyword();
2114
+ return t17.tsAnyKeyword();
2283
2115
  }
2284
2116
  function isCalleeNamed(node, name) {
2285
- if (!t19.isIdentifier(node.callee)) {
2117
+ if (!t17.isIdentifier(node.callee)) {
2286
2118
  return false;
2287
2119
  }
2288
2120
  return node.callee.name === name;
2289
2121
  }
2290
2122
  function isSimpleLiteral(node) {
2291
2123
  if (!node) return false;
2292
- if (t19.isStringLiteral(node) || t19.isNumericLiteral(node) || t19.isBooleanLiteral(node) || t19.isNullLiteral(node) || t19.isRegExpLiteral(node) || t19.isBigIntLiteral(node) || t19.isDecimalLiteral(node)) {
2124
+ if (t17.isStringLiteral(node) || t17.isNumericLiteral(node) || t17.isBooleanLiteral(node) || t17.isNullLiteral(node) || t17.isRegExpLiteral(node) || t17.isBigIntLiteral(node) || t17.isDecimalLiteral(node)) {
2293
2125
  return true;
2294
2126
  }
2295
2127
  return false;
2296
2128
  }
2129
+ function forkNode(node, deep = true) {
2130
+ const newNode = t17.cloneNode(node, deep);
2131
+ newNode.leadingComments = node.leadingComments;
2132
+ newNode.innerComments = node.innerComments;
2133
+ newNode.trailingComments = null;
2134
+ cleanNodeLoc(node);
2135
+ cleanNodeComments(node);
2136
+ return newNode;
2137
+ }
2138
+ function cleanNodeLoc(node) {
2139
+ node.start = null;
2140
+ node.end = null;
2141
+ node.loc = null;
2142
+ }
2143
+ function cleanNodeComments(node) {
2144
+ node.leadingComments = null;
2145
+ node.innerComments = null;
2146
+ node.trailingComments = null;
2147
+ }
2148
+
2149
+ // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-ast-chunks/resolve-global-type-chunk.ts
2150
+ function resolveGlobalTypeChunks(path9, ir) {
2151
+ if (!path9.parentPath?.isProgram()) {
2152
+ return;
2153
+ }
2154
+ const forked = forkNode(path9.node);
2155
+ ir.tsTypes.push(forked);
2156
+ path9.remove();
2157
+ }
2158
+
2159
+ // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-ast-chunks/resolve-module-chunk.ts
2160
+ import * as t18 from "@babel/types";
2161
+ function resolveModuleChunks(path9, ir) {
2162
+ const forked = forkNode(path9.node);
2163
+ if (t18.isImportDeclaration(forked)) {
2164
+ ir.imports.push(forked);
2165
+ } else if (t18.isExportDeclaration(forked)) {
2166
+ ir.exports.push(forked);
2167
+ }
2168
+ path9.remove();
2169
+ }
2297
2170
 
2298
2171
  // src/core/transform/sfc/script/shared/metadata-utils.ts
2299
2172
  var META_KEY = "__vureact_metadata";
@@ -2311,43 +2184,289 @@ function setScriptNodeMeta(node, opts) {
2311
2184
  node[META_KEY] = opts;
2312
2185
  }
2313
2186
 
2314
- // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-static-hoisting.ts
2315
- function resolveStaticHoisting(ctx) {
2187
+ // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-ast-chunks/resolve-static-const-chunk.ts
2188
+ function resolveStaticConstChunks(path9, ir) {
2189
+ const { node, parentPath } = path9;
2190
+ const parent = parentPath.node;
2191
+ if (!isVariableDeclTopLevel(path9) || !parentPath.isVariableDeclaration() || parent.kind !== "const" || !isSimpleLiteral(node.init) || getScriptNodeMeta(node)) {
2192
+ return;
2193
+ }
2194
+ const forked = forkNode(parent);
2195
+ ir.statement.global.push(forked);
2196
+ parentPath.remove();
2197
+ }
2198
+
2199
+ // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-ast-chunks/index.ts
2200
+ function resolveASTChunks(ctx, ast) {
2316
2201
  const scriptIR = getScriptIR(ctx);
2317
2202
  if (ctx.inputType !== "sfc") {
2318
2203
  return {};
2319
2204
  }
2205
+ scriptIR.statement.local = ast;
2320
2206
  return {
2207
+ // 提取 import/export
2321
2208
  "ImportDeclaration|ExportDeclaration"(path9) {
2322
- if (t20.isImportDeclaration(path9.node)) {
2323
- scriptIR.imports.push(path9.node);
2324
- } else if (t20.isExportDeclaration(path9.node)) {
2325
- scriptIR.exports.push(path9.node);
2326
- }
2327
- path9.remove();
2209
+ resolveModuleChunks(path9, scriptIR);
2328
2210
  },
2211
+ // 提取全局类型声明
2329
2212
  "TSInterfaceDeclaration|TSTypeAliasDeclaration|TSEnumDeclaration|TSModuleDeclaration|TSModuleDeclaration"(path9) {
2330
- if (t20.isProgram(path9.parent)) {
2331
- scriptIR.tsTypes.push(path9.node);
2332
- path9.remove();
2333
- }
2213
+ resolveGlobalTypeChunks(path9, scriptIR);
2334
2214
  },
2215
+ // 提升顶层常量声明
2335
2216
  VariableDeclarator(path9) {
2217
+ resolveStaticConstChunks(path9, scriptIR);
2218
+ }
2219
+ };
2220
+ }
2221
+
2222
+ // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-runtime-imports/index.ts
2223
+ import * as t19 from "@babel/types";
2224
+
2225
+ // src/core/transform/shared.ts
2226
+ function recordImport(ctx, pkg, name, onDemand = true) {
2227
+ const { imports } = ctx;
2228
+ if (isTypeOnlyImport(name)) {
2229
+ name = `type ${name}`;
2230
+ }
2231
+ if (imports.has(pkg)) {
2232
+ const list = imports.get(pkg);
2233
+ const foundItem = list.find((item) => item.name === name);
2234
+ if (!foundItem) {
2235
+ list.push({ name, onDemand });
2236
+ }
2237
+ return;
2238
+ }
2239
+ imports.set(pkg, [{ name, onDemand }]);
2240
+ }
2241
+ function isTypeOnlyImport(name) {
2242
+ const arr = [REACT_API_MAP.ReactNode];
2243
+ return arr.includes(name);
2244
+ }
2245
+
2246
+ // src/core/transform/sfc/script/shared/replace-vue-suffix.ts
2247
+ function replaceVueSuffix(node) {
2248
+ if (!node.value.endsWith(".vue")) return;
2249
+ const replaced = node.value.replace(/.vue$/, "");
2250
+ node.value = replaced;
2251
+ node.extra = {
2252
+ rawValue: replaced,
2253
+ // fix: 当 minified: true 的情况下,输出内容丢失引号
2254
+ raw: `'${replaced}'`
2255
+ };
2256
+ }
2257
+
2258
+ // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-runtime-imports/import-strategies.ts
2259
+ var VueRouterStrategy = class {
2260
+ matches(moduleName) {
2261
+ return moduleName === "vue-router" || moduleName.startsWith("vue-router/");
2262
+ }
2263
+ process() {
2264
+ return {
2265
+ shouldReplaceSource: true,
2266
+ newSource: PACKAGE_NAME.router,
2267
+ shouldRemove: false,
2268
+ shouldInjectRuntimeImports: false
2269
+ };
2270
+ }
2271
+ };
2272
+ var VueEcosystemStrategy = class {
2273
+ matches(moduleName) {
2274
+ if (moduleName.startsWith(".") || moduleName.startsWith("/") || moduleName.startsWith("file:")) {
2275
+ return false;
2276
+ }
2277
+ if (moduleName === "vue-router" || moduleName.startsWith("vue-router/")) {
2278
+ return false;
2279
+ }
2280
+ if (moduleName.startsWith("@vue/")) {
2281
+ return true;
2282
+ }
2283
+ for (const pkg of VUE_PACKAGES) {
2284
+ if (moduleName === pkg || moduleName.startsWith(`${pkg}/`)) {
2285
+ return true;
2286
+ }
2287
+ }
2288
+ return false;
2289
+ }
2290
+ process() {
2291
+ return {
2292
+ shouldReplaceSource: false,
2293
+ shouldRemove: true,
2294
+ shouldInjectRuntimeImports: true
2295
+ };
2296
+ }
2297
+ };
2298
+ var StyleFileStrategy = class {
2299
+ regExp = /\.(less|sass|scss)$/i;
2300
+ matches(moduleName) {
2301
+ return this.regExp.test(moduleName);
2302
+ }
2303
+ process(path9, ctx) {
2304
+ if (!ctx.preprocessStyles) {
2305
+ return {};
2306
+ }
2307
+ const importSource = path9.node.source.value;
2308
+ if (typeof importSource !== "string") {
2309
+ return {};
2310
+ }
2311
+ return {
2312
+ shouldReplaceSource: true,
2313
+ newSource: importSource.replace(this.regExp, ".css"),
2314
+ shouldRemove: false,
2315
+ shouldInjectRuntimeImports: false
2316
+ };
2317
+ }
2318
+ };
2319
+
2320
+ // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-runtime-imports/import-strategy-manager.ts
2321
+ var ImportStrategyManager = class {
2322
+ strategies = [];
2323
+ constructor() {
2324
+ this.strategies.push(new VueRouterStrategy());
2325
+ this.strategies.push(new VueEcosystemStrategy());
2326
+ this.strategies.push(new StyleFileStrategy());
2327
+ }
2328
+ /** 添加自定义策略 */
2329
+ addStrategy(strategy) {
2330
+ this.strategies.push(strategy);
2331
+ }
2332
+ /** 查找匹配的策略 */
2333
+ findStrategy(moduleName) {
2334
+ for (const strategy of this.strategies) {
2335
+ if (strategy.matches(moduleName)) {
2336
+ return strategy;
2337
+ }
2338
+ }
2339
+ return null;
2340
+ }
2341
+ };
2342
+
2343
+ // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-runtime-imports/index.ts
2344
+ function resolveRuntimeImports(ctx) {
2345
+ if (ctx.inputType === "sfc") {
2346
+ recordImport(ctx, PACKAGE_NAME.react, REACT_API_MAP.memo);
2347
+ }
2348
+ const strategyManager = new ImportStrategyManager();
2349
+ const processedModules = /* @__PURE__ */ new Set();
2350
+ let hasImports = false;
2351
+ return {
2352
+ ImportDeclaration(path9) {
2336
2353
  const { node } = path9;
2337
- if (!isVariableDeclTopLevel(path9) || !isSimpleLiteral(node.init) || getScriptNodeMeta(node)) {
2354
+ const originalModuleName = node.source.value.toLowerCase();
2355
+ const strategy = strategyManager.findStrategy(originalModuleName);
2356
+ let strategyResult = null;
2357
+ if (strategy) {
2358
+ strategyResult = strategy.process(path9, ctx, originalModuleName);
2359
+ if (strategyResult.shouldReplaceSource && strategyResult.newSource) {
2360
+ node.source.value = strategyResult.newSource;
2361
+ }
2362
+ if (strategyResult.shouldRemove && !path9.removed) {
2363
+ path9.remove();
2364
+ return;
2365
+ }
2366
+ }
2367
+ replaceVueSuffix(node.source);
2368
+ const finalModuleName = node.source.value.toLowerCase();
2369
+ if (processedModules.has(finalModuleName) && !path9.removed) {
2370
+ path9.remove();
2338
2371
  return;
2339
2372
  }
2340
- const declarationPath = path9.findParent((p) => p.isVariableDeclaration());
2341
- if (!declarationPath) return;
2342
- scriptIR.statement.global.push(declarationPath.node);
2343
- declarationPath.remove();
2373
+ processedModules.add(finalModuleName);
2374
+ mergeImports(node, ctx, finalModuleName);
2375
+ if (!hasImports) {
2376
+ const importNodes = createImportNodes(ctx);
2377
+ if (importNodes.length) {
2378
+ if (strategyResult?.shouldInjectRuntimeImports) {
2379
+ path9.insertAfter(importNodes);
2380
+ } else if (finalModuleName === PACKAGE_NAME.react) {
2381
+ path9.insertAfter(importNodes);
2382
+ } else {
2383
+ forkLeadingComments(importNodes[0], node);
2384
+ path9.insertBefore(importNodes);
2385
+ }
2386
+ }
2387
+ hasImports = true;
2388
+ }
2389
+ },
2390
+ // 兜底:无 ImportDeclaration 的文件也要能注入必需依赖。
2391
+ Program: {
2392
+ exit(path9) {
2393
+ if (hasImports) return;
2394
+ hasImports = true;
2395
+ const { node } = path9;
2396
+ const importNodes = createImportNodes(ctx);
2397
+ if (!importNodes.length) return;
2398
+ forkLeadingComments(importNodes[0], node);
2399
+ path9.unshiftContainer("body", importNodes);
2400
+ }
2344
2401
  }
2345
2402
  };
2346
2403
  }
2347
- function collectLocalStatements(ctx, ast) {
2404
+ function mergeImports(currentNode, ctx, moduleName) {
2405
+ const ctxImportItems = ctx.imports.get(moduleName);
2406
+ if (!ctxImportItems?.length) {
2407
+ return;
2408
+ }
2409
+ const currentImports = /* @__PURE__ */ new Set();
2410
+ for (const spec of currentNode.specifiers) {
2411
+ if (t19.isImportSpecifier(spec) && t19.isIdentifier(spec.imported)) {
2412
+ currentImports.add(spec.imported.name);
2413
+ }
2414
+ if (t19.isImportDefaultSpecifier(spec) && t19.isIdentifier(spec.local)) {
2415
+ currentImports.add(spec.local.name);
2416
+ }
2417
+ }
2418
+ for (const item of ctxImportItems) {
2419
+ if (currentImports.has(item.name)) {
2420
+ continue;
2421
+ }
2422
+ const local = t19.identifier(item.name);
2423
+ const newNode = !item.onDemand ? t19.importDefaultSpecifier(local) : t19.importSpecifier(local, local);
2424
+ currentNode.specifiers.push(newNode);
2425
+ }
2426
+ ctx.imports.delete(moduleName);
2427
+ }
2428
+ function createImportNodes(ctx) {
2429
+ const result = [];
2430
+ const importDeclarations = Array.from(ctx.imports).map(([moduleName, items]) => {
2431
+ const specifiers = items.map((item) => {
2432
+ const local = t19.identifier(item.name);
2433
+ return item.onDemand ? t19.importSpecifier(local, local) : t19.importDefaultSpecifier(local);
2434
+ });
2435
+ return t19.importDeclaration(specifiers, t19.stringLiteral(moduleName));
2436
+ });
2437
+ for (const decl of importDeclarations) {
2438
+ const name = decl.source.value;
2439
+ if (name === PACKAGE_NAME.react) {
2440
+ result.unshift(decl);
2441
+ } else {
2442
+ result.push(decl);
2443
+ }
2444
+ }
2445
+ return result;
2446
+ }
2447
+ function forkLeadingComments(target, source) {
2448
+ const { leadingComments } = source;
2449
+ if (!leadingComments?.length) {
2450
+ return;
2451
+ }
2452
+ const newComments = [...leadingComments];
2453
+ source.leadingComments = null;
2454
+ target.leadingComments = newComments;
2455
+ }
2456
+
2457
+ // src/core/transform/sfc/script/syntax-processor/postprocess/resolve-sfc-css-import.ts
2458
+ import * as t20 from "@babel/types";
2459
+ function resolveSfcCssImport(ctx) {
2348
2460
  if (ctx.inputType !== "sfc") return;
2349
2461
  const scriptIR = getScriptIR(ctx);
2350
- scriptIR.statement.local = ast;
2462
+ const { filePath, moduleName } = ctx.styleData;
2463
+ if (!filePath) return;
2464
+ const styleFilename = normalizePath(filePath).split("/").pop();
2465
+ const importDecl = t20.importDeclaration(
2466
+ !moduleName ? [] : [t20.importDefaultSpecifier(t20.identifier(moduleName))],
2467
+ t20.stringLiteral(`./${styleFilename}`)
2468
+ );
2469
+ scriptIR.imports.push(importDecl);
2351
2470
  }
2352
2471
 
2353
2472
  // src/core/transform/sfc/script/syntax-processor/preprocess/resolve-define-async-component.ts
@@ -2407,7 +2526,7 @@ function checkIsDynamicImport(ctx, node) {
2407
2526
  if (t21.isCallExpression(node)) {
2408
2527
  warnIsNotImport(node.callee);
2409
2528
  if (t21.isStringLiteral(node.arguments[0])) {
2410
- replaceVueSuffix(ctx, node.arguments[0]);
2529
+ replaceVueSuffix(node.arguments[0]);
2411
2530
  }
2412
2531
  return;
2413
2532
  }
@@ -3171,6 +3290,9 @@ var SLOT_DEFAULT_NAME = "default";
3171
3290
  var SLOT_CHILDREN_NAME = "children";
3172
3291
  var SLOT_FN_PARAM_NAME = "props";
3173
3292
  function resolveSlotsTopLevelTypes(ctx) {
3293
+ if (ctx.inputType !== "sfc") {
3294
+ return {};
3295
+ }
3174
3296
  return {
3175
3297
  "TSInterfaceDeclaration|TSTypeAliasDeclaration"(path9) {
3176
3298
  if (!t29.isProgram(path9.parent)) return;
@@ -3736,6 +3858,9 @@ function resolveAnalysisOnlyAdapter(ctx) {
3736
3858
  if (!adapter || adapter.type !== "analyzed-deps") {
3737
3859
  return;
3738
3860
  }
3861
+ if (!isVueApiReference(path9, apiName)) {
3862
+ return;
3863
+ }
3739
3864
  if (t32.isCallExpression(node)) {
3740
3865
  resolveCallNode(path9, adapter, ctx);
3741
3866
  } else {
@@ -3769,6 +3894,41 @@ function resolveCallNode(path9, adapter, ctx) {
3769
3894
  replaceCallName(node, adapter.target);
3770
3895
  recordImport(ctx, adapter.package, adapter.target);
3771
3896
  }
3897
+ function isVueApiReference(path9, apiName) {
3898
+ if (path9.isIdentifier()) {
3899
+ if (path9.parentPath.isCallExpression() && path9.parentPath.node.callee === path9.node) {
3900
+ return false;
3901
+ }
3902
+ if (!path9.isReferencedIdentifier()) {
3903
+ return false;
3904
+ }
3905
+ }
3906
+ if (path9.isCallExpression()) {
3907
+ const callee = path9.get("callee");
3908
+ if (!callee.isIdentifier()) return false;
3909
+ return isVueImportBinding(callee.scope.getBinding(apiName));
3910
+ }
3911
+ return isVueImportBinding(path9.scope.getBinding(apiName));
3912
+ }
3913
+ function isVueImportBinding(binding) {
3914
+ if (!binding) return false;
3915
+ const bindingPath = binding.path;
3916
+ if (!bindingPath.isImportSpecifier() && !bindingPath.isImportDefaultSpecifier() && !bindingPath.isImportNamespaceSpecifier()) {
3917
+ return false;
3918
+ }
3919
+ const parent = bindingPath.parentPath?.node;
3920
+ if (!parent || !t32.isImportDeclaration(parent)) {
3921
+ return false;
3922
+ }
3923
+ const source = parent.source.value.toLowerCase();
3924
+ if (source.startsWith("@vue/")) {
3925
+ return true;
3926
+ }
3927
+ if (source === "vue-router" || source.startsWith("vue-router/")) {
3928
+ return true;
3929
+ }
3930
+ return VUE_PACKAGES.some((name) => source === name || source.startsWith(`${name}/`));
3931
+ }
3772
3932
 
3773
3933
  // src/core/transform/sfc/script/syntax-processor/process/resolve-arrow-deps.ts
3774
3934
  function resolveArrowFnDeps(ctx, ast) {
@@ -4049,12 +4209,18 @@ function resolveRenameAdapter(ctx) {
4049
4209
  } else if (isCallNode && t37.isIdentifier(node.callee)) {
4050
4210
  apiName = node.callee.name;
4051
4211
  }
4212
+ if (!apiName) {
4213
+ return;
4214
+ }
4052
4215
  const runtimeAdapter = ADAPTER_RULES.runtime[apiName];
4053
4216
  const routerAdapter = ADAPTER_RULES.router[apiName];
4054
4217
  const adapter = runtimeAdapter || routerAdapter;
4055
4218
  if (!adapter || adapter.type !== "rename") {
4056
4219
  return;
4057
4220
  }
4221
+ if (!isVueApiReference2(path9, apiName)) {
4222
+ return;
4223
+ }
4058
4224
  if (adapter.isTrackable) {
4059
4225
  const reactiveType = getReactiveType(apiName);
4060
4226
  const declaratorPath = getVariableDeclaratorPath(path9);
@@ -4075,6 +4241,41 @@ function resolveRenameAdapter(ctx) {
4075
4241
  }
4076
4242
  };
4077
4243
  }
4244
+ function isVueApiReference2(path9, apiName) {
4245
+ if (path9.isIdentifier()) {
4246
+ if (path9.parentPath.isCallExpression() && path9.parentPath.node.callee === path9.node) {
4247
+ return false;
4248
+ }
4249
+ if (!path9.isReferencedIdentifier()) {
4250
+ return false;
4251
+ }
4252
+ }
4253
+ if (path9.isCallExpression()) {
4254
+ const callee = path9.get("callee");
4255
+ if (!callee.isIdentifier()) return false;
4256
+ return isVueImportBinding2(callee.scope.getBinding(apiName));
4257
+ }
4258
+ return isVueImportBinding2(path9.scope.getBinding(apiName));
4259
+ }
4260
+ function isVueImportBinding2(binding) {
4261
+ if (!binding) return false;
4262
+ const bindingPath = binding.path;
4263
+ if (!bindingPath.isImportSpecifier() && !bindingPath.isImportDefaultSpecifier() && !bindingPath.isImportNamespaceSpecifier()) {
4264
+ return false;
4265
+ }
4266
+ const parent = bindingPath.parentPath?.node;
4267
+ if (!parent || !t37.isImportDeclaration(parent)) {
4268
+ return false;
4269
+ }
4270
+ const source = parent.source.value.toLowerCase();
4271
+ if (source.startsWith("@vue/")) {
4272
+ return true;
4273
+ }
4274
+ if (source === "vue-router" || source.startsWith("vue-router/")) {
4275
+ return true;
4276
+ }
4277
+ return VUE_PACKAGES.some((name) => source === name || source.startsWith(`${name}/`));
4278
+ }
4078
4279
 
4079
4280
  // src/core/transform/sfc/script/syntax-processor/index.ts
4080
4281
  function processVueSyntax2(ast, ctx) {
@@ -4106,8 +4307,8 @@ function processVueSyntax2(ast, ctx) {
4106
4307
  excludeBabel: [resolveTemplateSlotIface, resolveCompIProps]
4107
4308
  },
4108
4309
  postprocess: {
4109
- applyBabel: [insertRequiredImports, resolveStaticHoisting],
4110
- excludeBabel: [insertCSSImport, collectLocalStatements]
4310
+ applyBabel: [resolveRuntimeImports, resolveASTChunks],
4311
+ excludeBabel: [resolveSfcCssImport]
4111
4312
  }
4112
4313
  });
4113
4314
  }
@@ -4247,7 +4448,7 @@ function isIdentifier20(code) {
4247
4448
  function isStringLiteral12(code) {
4248
4449
  try {
4249
4450
  const node = parseExpression3(code);
4250
- return t38.isStringLiteral(node) || t38.isTemplateLiteral(node);
4451
+ return t38.isStringLiteral(node);
4251
4452
  } catch {
4252
4453
  return false;
4253
4454
  }
@@ -4320,7 +4521,10 @@ function normalizePropName(rawName, name) {
4320
4521
  case "for":
4321
4522
  return "htmlFor";
4322
4523
  default:
4323
- return whitelist.test(name) ? name : camelCase(name);
4524
+ if (!isVBind(rawName) && whitelist.test(name)) {
4525
+ return name;
4526
+ }
4527
+ return camelCase(name);
4324
4528
  }
4325
4529
  }
4326
4530
  function isVOn(name) {
@@ -4336,7 +4540,7 @@ function isVModel(name) {
4336
4540
  return /^v-model/.test(name ?? "");
4337
4541
  }
4338
4542
  function isClassAttr(name) {
4339
- return /^(class|:class|v-bind:class|className)$/.test(name ?? "");
4543
+ return /^(class|:class|v-bind:class|className|class-name)$/.test(name ?? "");
4340
4544
  }
4341
4545
  function isStyleAttr(name) {
4342
4546
  return /^(style|:style|v-bind:style)$/.test(name ?? "");
@@ -4530,7 +4734,6 @@ function resolveDefaultStyleModuleName(node) {
4530
4734
 
4531
4735
  // src/core/transform/sfc/template/syntax-processor/preprocess/resolve-style-scope-attribute.ts
4532
4736
  import {
4533
- ElementTypes,
4534
4737
  isSlotOutlet,
4535
4738
  isTemplateNode,
4536
4739
  NodeTypes as NodeTypes3
@@ -4554,21 +4757,30 @@ function walkElementNodes2(node, onElement) {
4554
4757
  }
4555
4758
  function injectStyleScopeAttribute(node, ctx) {
4556
4759
  const { scopeId } = ctx.styleData;
4557
- if (!scopeId || isComponentElement(node) || isSlotOutlet(node) || isTemplateNode(node)) {
4760
+ if (!scopeId || isSlotOutlet(node) || isTemplateNode(node)) {
4558
4761
  return;
4559
4762
  }
4560
- const hasDynamicIs = node.props.some((prop) => {
4561
- if (prop.type !== NodeTypes3.DIRECTIVE || prop.arg?.type !== NodeTypes3.SIMPLE_EXPRESSION) {
4562
- return false;
4763
+ let hasScopeId = false;
4764
+ let hasClassOrId = false;
4765
+ for (const prop of node.props) {
4766
+ if (prop.type === NodeTypes3.ATTRIBUTE) {
4767
+ if (prop.name === scopeId) {
4768
+ hasScopeId = true;
4769
+ break;
4770
+ }
4771
+ if (getHasClassOrId(prop.name)) {
4772
+ hasClassOrId = true;
4773
+ break;
4774
+ }
4775
+ }
4776
+ if (prop.type === NodeTypes3.DIRECTIVE && prop.arg?.type === NodeTypes3.SIMPLE_EXPRESSION) {
4777
+ if (getHasClassOrId(prop.arg.content)) {
4778
+ hasClassOrId = true;
4779
+ break;
4780
+ }
4563
4781
  }
4564
- return prop.arg.content === "is";
4565
- });
4566
- const hasScopeId = node.props.some(
4567
- (prop) => prop.type === NodeTypes3.ATTRIBUTE && prop.name === scopeId
4568
- );
4569
- if (hasDynamicIs || hasScopeId) {
4570
- return;
4571
4782
  }
4783
+ if (hasScopeId || !hasClassOrId) return;
4572
4784
  const attr = {
4573
4785
  type: NodeTypes3.ATTRIBUTE,
4574
4786
  name: scopeId,
@@ -4578,11 +4790,8 @@ function injectStyleScopeAttribute(node, ctx) {
4578
4790
  };
4579
4791
  node.props.push(attr);
4580
4792
  }
4581
- function isComponentElement(node) {
4582
- if (node.tagType !== ElementTypes.COMPONENT) {
4583
- return camelCase(node.tag) !== node.tag;
4584
- }
4585
- return node.tagType === ElementTypes.COMPONENT;
4793
+ function getHasClassOrId(ns) {
4794
+ return isClassAttr(ns) || ns === "id";
4586
4795
  }
4587
4796
 
4588
4797
  // src/core/transform/sfc/template/shared/prop-merge-utils.ts
@@ -4773,7 +4982,12 @@ function resolvePropertyIR(node, ir, ctx, nodeIR, isDynamic = false) {
4773
4982
  content = node.value.content = parseStyleString(content);
4774
4983
  }
4775
4984
  if (isDynamic) {
4776
- node.value.isStringLiteral = strCodeTypes.isStringLiteral(content);
4985
+ const isStringLiteral13 = strCodeTypes.isStringLiteral(content);
4986
+ if (isStringLiteral13) {
4987
+ content = normalizeString(content);
4988
+ node.value.content = content;
4989
+ }
4990
+ node.value.isStringLiteral = isStringLiteral13;
4777
4991
  }
4778
4992
  const existing = findSameProp(nodeIR.props, node);
4779
4993
  if (existing) {
@@ -4783,6 +4997,12 @@ function resolvePropertyIR(node, ir, ctx, nodeIR, isDynamic = false) {
4783
4997
  }
4784
4998
  resolvePropAsBabelExp(existing ?? node, ctx);
4785
4999
  }
5000
+ function normalizeString(s) {
5001
+ if (s.startsWith("'") && s.endsWith("'")) {
5002
+ return s.slice(1, -1);
5003
+ }
5004
+ return s;
5005
+ }
4786
5006
 
4787
5007
  // src/core/transform/sfc/template/syntax-processor/process/props/resolve-attribute-prop.ts
4788
5008
  function resolveAttributeProp(node, ir, ctx, nodeIR) {
@@ -4922,7 +5142,7 @@ function resolveVMemo(node, _ir, ctx, nodeIR) {
4922
5142
 
4923
5143
  // src/core/transform/sfc/template/syntax-processor/process/props/resolve-v-model.ts
4924
5144
  import {
4925
- ElementTypes as ElementTypes2,
5145
+ ElementTypes,
4926
5146
  NodeTypes as NodeTypes6
4927
5147
  } from "@vue/compiler-core";
4928
5148
  function resolveVModel(node, _ir, ctx, elementNode, nodeIR) {
@@ -4930,7 +5150,7 @@ function resolveVModel(node, _ir, ctx, elementNode, nodeIR) {
4930
5150
  const exp = node.exp;
4931
5151
  const modifiers = node.modifiers.map((item) => item.content);
4932
5152
  const getterName = exp.content;
4933
- const isComponent = elementNode.tagType === ElementTypes2.COMPONENT;
5153
+ const isComponent = elementNode.tagType === ElementTypes.COMPONENT;
4934
5154
  const inputType = resolveHtmlInput(elementNode, isComponent);
4935
5155
  const propName = arg?.content ?? resolveModelPropName(inputType, isComponent);
4936
5156
  let valuePropIR;
@@ -5007,7 +5227,7 @@ function resolveVOn(node, _ir, ctx, nodeIR) {
5007
5227
  const exp = node.exp;
5008
5228
  const modifiers = node.modifiers.map((item) => item.content);
5009
5229
  const captureIndex = modifiers.findIndex((modifier) => modifier === "capture");
5010
- let eventName = `on${camelCase(capitalize(arg.content))}`;
5230
+ let eventName = normalizeVOnEventName(arg.content);
5011
5231
  let handler = resolveSpecialExpressions(exp.content.trim(), ctx);
5012
5232
  if (captureIndex > -1) {
5013
5233
  eventName = modifiers[captureIndex] ? `${eventName}Capture` : eventName;
@@ -5018,7 +5238,7 @@ function resolveVOn(node, _ir, ctx, nodeIR) {
5018
5238
  originalVueEventName = `${arg.content}.${modifiers.join(".")}`;
5019
5239
  } else {
5020
5240
  const expr = stringToExpr(handler);
5021
- if (!t40.isFunctionExpression(expr) && !t40.isIdentifier(expr)) {
5241
+ if (!t40.isFunctionExpression(expr) && !t40.isArrowFunctionExpression(expr) && !t40.isIdentifier(expr)) {
5022
5242
  handler = `() => {${handler}}`;
5023
5243
  }
5024
5244
  }
@@ -5036,6 +5256,11 @@ function resolveVOn(node, _ir, ctx, nodeIR) {
5036
5256
  }
5037
5257
  nodeIR.props.push(eventIR);
5038
5258
  }
5259
+ function normalizeVOnEventName(rawEventName) {
5260
+ const segments = rawEventName.split(/[:-]/g).map((segment) => segment.trim()).filter(Boolean);
5261
+ const normalized = segments.map((segment) => capitalize(camelCase(segment))).join("");
5262
+ return `on${normalized}`;
5263
+ }
5039
5264
 
5040
5265
  // src/core/transform/sfc/template/syntax-processor/process/props/resolve-v-show.ts
5041
5266
  function resolveVShow(node, _ir, ctx, nodeIR) {
@@ -5209,7 +5434,7 @@ function resolveCommentNode(node, _ir, ctx, childrenIR) {
5209
5434
  }
5210
5435
 
5211
5436
  // src/core/transform/sfc/template/syntax-processor/process/resolve-element-node.ts
5212
- import { ElementTypes as ElementTypes3 } from "@vue/compiler-core";
5437
+ import { ElementTypes as ElementTypes2 } from "@vue/compiler-core";
5213
5438
  function resolveElementNode(node, ir, ctx, siblingNodesIR) {
5214
5439
  const isComponent = getIsComponent(node);
5215
5440
  const tag = isComponent ? capitalize(camelCase(node.tag)) : node.tag;
@@ -5244,10 +5469,10 @@ function createElementNodeIR(options) {
5244
5469
  };
5245
5470
  }
5246
5471
  function getIsComponent(node) {
5247
- if (node.tagType !== ElementTypes3.COMPONENT) {
5472
+ if (node.tagType !== ElementTypes2.COMPONENT) {
5248
5473
  return camelCase(node.tag) !== node.tag;
5249
5474
  }
5250
- return node.tagType === ElementTypes3.COMPONENT;
5475
+ return node.tagType === ElementTypes2.COMPONENT;
5251
5476
  }
5252
5477
 
5253
5478
  // src/core/transform/sfc/template/syntax-processor/process/resolve-interpolation-node.ts
@@ -5466,7 +5691,7 @@ function transform(ast, ctx, options) {
5466
5691
  }
5467
5692
 
5468
5693
  // package.json
5469
- var version = "1.4.0";
5694
+ var version = "1.5.1";
5470
5695
  var bin = {
5471
5696
  vureact: "./bin/vureact.js"
5472
5697
  };
@@ -6214,18 +6439,10 @@ var BaseCompiler = class extends Helper {
6214
6439
  }
6215
6440
  prepareGenerateOptions(filename) {
6216
6441
  const userOptions = this.options.generate || {};
6217
- const mergedOptions = {
6218
- jsescOption: {
6219
- minimal: true,
6220
- quotes: "single"
6221
- },
6222
- minified: true,
6223
- ...userOptions
6224
- };
6225
- if (mergedOptions.sourceMaps && filename) {
6226
- mergedOptions.sourceFileName = mergedOptions.sourceFileName || filename;
6442
+ if (userOptions.sourceMaps && filename) {
6443
+ userOptions.sourceFileName = userOptions.sourceFileName || filename;
6227
6444
  }
6228
- return mergedOptions;
6445
+ return userOptions;
6229
6446
  }
6230
6447
  resolveMainResult(ir, gen, ctxData) {
6231
6448
  const { fileId, filename, scriptData, styleData, inputType } = ctxData;
@@ -6874,31 +7091,31 @@ var ViteBootstrapper = class {
6874
7091
  * 利用 Vite 官方脚手架创建标准 React 环境
6875
7092
  */
6876
7093
  async bootstrapIfNeeded() {
6877
- const { bootstrapVite } = this.options.output || {};
7094
+ const { output } = this.options;
6878
7095
  const workspaceDir = this.fileCompiler.getWorkspaceDir();
6879
7096
  await fs5.promises.mkdir(workspaceDir, { recursive: true });
6880
- if (bootstrapVite === false) {
7097
+ if (output?.bootstrapVite === false) {
6881
7098
  return false;
6882
7099
  }
6883
7100
  if (this.isSingleFile()) {
6884
7101
  console.info("Skipping Vite initialization for single file compilation");
6885
- return false;
7102
+ return;
6886
7103
  }
6887
7104
  const outputPkgPath = this.fileCompiler.getOutputPkgPath();
6888
7105
  if (fs5.existsSync(outputPkgPath)) {
6889
- return false;
7106
+ return;
6890
7107
  }
6891
- this.spinner.start("Bootstrapping Vite React environment...");
6892
7108
  try {
7109
+ this.spinner.start("Bootstrapping Vite React environment...");
6893
7110
  await this.resolveViteCreateApp();
6894
7111
  } catch (err) {
6895
- this.spinner.stop();
6896
7112
  console.error(
6897
7113
  kleur7.red("\u2716"),
6898
- "Failed to bootstrap Vite environment. Please check npm/network.",
7114
+ "Failed to bootstrap Vite environment. Please check npm/network.\n",
6899
7115
  err
6900
7116
  );
6901
- return false;
7117
+ this.spinner.stop();
7118
+ return;
6902
7119
  }
6903
7120
  const removeVuePackages = (deps) => {
6904
7121
  for (const name in deps) {
@@ -6920,15 +7137,15 @@ var ViteBootstrapper = class {
6920
7137
  }
6921
7138
  return deps;
6922
7139
  };
6923
- const rootPkgPath = this.fileCompiler.getRootPkgPath();
6924
- const rootPkg = await this.fileCompiler.resolvePackageFile(rootPkgPath);
6925
- const vitePkg = await this.fileCompiler.resolvePackageFile(outputPkgPath);
6926
- const newDeps = resolveDeps(rootPkg.dependencies, vitePkg.dependencies);
6927
- const newDevDeps = resolveDeps(rootPkg.devDependencies, vitePkg.devDependencies, true);
6928
- vitePkg.dependencies = newDeps;
6929
- vitePkg.devDependencies = newDevDeps;
6930
- const newVitePkg = JSON.stringify(vitePkg, null, 2);
6931
- await this.fileCompiler.writeFileWithDir(outputPkgPath, newVitePkg);
7140
+ const sourcePkgPath = this.fileCompiler.getRootPkgPath();
7141
+ const sourcePkg = await this.fileCompiler.resolvePackageFile(sourcePkgPath);
7142
+ let newPkg = await this.fileCompiler.resolvePackageFile(outputPkgPath);
7143
+ const newDeps = resolveDeps(sourcePkg.dependencies, newPkg.dependencies);
7144
+ const newDevDeps = resolveDeps(sourcePkg.devDependencies, newPkg.devDependencies, true);
7145
+ newPkg.dependencies = newDeps;
7146
+ newPkg.devDependencies = newDevDeps;
7147
+ newPkg = output?.packageJson?.(newPkg) || newPkg;
7148
+ await this.fileCompiler.writeFileWithDir(outputPkgPath, JSON.stringify(newPkg, null, 2));
6932
7149
  this.spinner.succeed("Standard Vite React environment initialized");
6933
7150
  return true;
6934
7151
  }
@@ -6960,15 +7177,15 @@ var ViteBootstrapper = class {
6960
7177
  */
6961
7178
  async resolveReactVersion(ver) {
6962
7179
  const outputPkgPath = this.fileCompiler.getOutputPkgPath();
6963
- const vitePkg = await this.fileCompiler.resolvePackageFile(outputPkgPath);
6964
- const typesVer = `^${ver.split(".")[0].replace(/@|\^/, "")}.0.0`;
6965
- vitePkg.dependencies.react = ver;
6966
- vitePkg.dependencies["react-dom"] = ver;
6967
- vitePkg.devDependencies["@types/react"] = typesVer;
6968
- vitePkg.devDependencies["@types/react-dom"] = typesVer;
6969
- await this.fileCompiler.writeFileWithDir(outputPkgPath, JSON.stringify(vitePkg, null, 2), {
6970
- lock: true
6971
- });
7180
+ const curPkg = await this.fileCompiler.resolvePackageFile(outputPkgPath);
7181
+ const mainVer = Number(ver.split(".")[0]);
7182
+ const typeVer = !isNaN(mainVer) ? `^${mainVer.toString().replace(/@|\^|~|>=|>|/, "")}.0.0` : "^19.0.0";
7183
+ curPkg.dependencies.react = ver;
7184
+ curPkg.dependencies["react-dom"] = ver;
7185
+ curPkg.devDependencies["@types/react"] = typeVer;
7186
+ curPkg.devDependencies["@types/react-dom"] = typeVer;
7187
+ await this.fileCompiler.writeFileWithDir(outputPkgPath, JSON.stringify(curPkg, null, 2));
7188
+ return curPkg;
6972
7189
  }
6973
7190
  };
6974
7191
 
@@ -7056,7 +7273,9 @@ var FileCompiler = class extends BaseCompiler {
7056
7273
  await rmWorkspace();
7057
7274
  console.error(kleur8.red("\u2716"), `Build failed in ${endTime}`);
7058
7275
  console.error(error);
7276
+ process.exit(-1);
7059
7277
  } finally {
7278
+ this.spinner.stop();
7060
7279
  this.resetSkippedCount();
7061
7280
  }
7062
7281
  }