@vureact/compiler-core 1.2.0 → 1.2.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.1.1
2
+ * @vureact/compiler-core v1.2.1
3
3
  * (c) 2025-present Ruihong Zhong (Ryan John)
4
4
  * @license MIT
5
5
  */
@@ -312,11 +312,27 @@ var ADAPTER_RULES = {
312
312
  package: PACKAGE_NAME.router,
313
313
  type: "rename"
314
314
  },
315
+ // =============== Methods ===============
315
316
  createRouter: {
316
317
  target: "createRouter",
317
318
  package: PACKAGE_NAME.router,
318
319
  type: "rename"
319
320
  },
321
+ createWebHistory: {
322
+ target: "createWebHistory",
323
+ package: PACKAGE_NAME.router,
324
+ type: "rename"
325
+ },
326
+ createWebHashHistory: {
327
+ target: "createWebHashHistory",
328
+ package: PACKAGE_NAME.router,
329
+ type: "rename"
330
+ },
331
+ createMemoryHistory: {
332
+ target: "createMemoryHistory",
333
+ package: PACKAGE_NAME.router,
334
+ type: "rename"
335
+ },
320
336
  // =============== Hooks ===============
321
337
  useRoute: {
322
338
  target: "useRoute",
@@ -369,6 +385,56 @@ var VUE_API_MAP = {
369
385
  RouterLink: "RouterLink"
370
386
  };
371
387
 
388
+ // src/shared/babel-utils.ts
389
+ import { parseExpression } from "@babel/parser";
390
+ function getBabelParseOptions(lang = "js", context = "script", filename) {
391
+ const baseOptions = {
392
+ sourceType: "module",
393
+ sourceFilename: filename ?? "anonymous",
394
+ errorRecovery: true
395
+ // 容错模式
396
+ };
397
+ const plugins = [];
398
+ if (lang.includes("ts")) {
399
+ plugins.push("typescript");
400
+ }
401
+ if (lang.endsWith("sx")) {
402
+ if (lang.startsWith("t")) plugins.push("typescript");
403
+ plugins.push("jsx");
404
+ }
405
+ if (context === "vueTemplate") {
406
+ plugins.push("decorators-legacy");
407
+ } else if (context === "expression") {
408
+ baseOptions.sourceType = "script";
409
+ baseOptions.allowReturnOutsideFunction = true;
410
+ baseOptions.allowSuperOutsideMethod = true;
411
+ }
412
+ plugins.push("classProperties", "objectRestSpread", "asyncGenerators");
413
+ return {
414
+ ...baseOptions,
415
+ plugins: [...new Set(plugins)]
416
+ };
417
+ }
418
+ function stringToExpr(input, lang, filename = "") {
419
+ return parseExpression(input, getBabelParseOptions(lang, "expression", filename));
420
+ }
421
+ function atComponentOrHookRoot(path7, rootScope, inScriptFile = false) {
422
+ const { parentPath, scope } = path7;
423
+ const parentBlock = scope.block;
424
+ if (!parentPath) return !inScriptFile;
425
+ if (parentBlock === rootScope) {
426
+ if (inScriptFile) return false;
427
+ if (parentPath.isBlockStatement() && parentPath.node !== rootScope) {
428
+ return false;
429
+ }
430
+ if (parentPath.isCallExpression() || parentPath.isNewExpression()) {
431
+ return false;
432
+ }
433
+ return true;
434
+ }
435
+ return false;
436
+ }
437
+
372
438
  // src/core/codegen/component/jsx/utils/jsx-element-utils.ts
373
439
  import * as t from "@babel/types";
374
440
  function createJsxElement(tag, props, children, selfClosing) {
@@ -548,7 +614,7 @@ function buildMemoNode(nodeIR, ctx) {
548
614
  import * as t8 from "@babel/types";
549
615
 
550
616
  // src/core/codegen/component/jsx/syntax-processor/process/build-slot-prop.ts
551
- import { parseExpression } from "@babel/parser";
617
+ import { parseExpression as parseExpression2 } from "@babel/parser";
552
618
  import * as t7 from "@babel/types";
553
619
 
554
620
  // src/shared/logger.ts
@@ -815,7 +881,7 @@ function buildSlotProp(nodeIR, ctx) {
815
881
  return slotValue;
816
882
  }
817
883
  if (!nodeIR.isStatic) {
818
- const dynamicSlotKey = parseExpression(nodeIR.name);
884
+ const dynamicSlotKey = parseExpression2(nodeIR.name);
819
885
  const spreadObject = t7.objectExpression([
820
886
  t7.objectProperty(dynamicSlotKey, convertSlotValueToExpression(slotValue), true)
821
887
  ]);
@@ -836,7 +902,7 @@ function buildSlotCallbackParams(nodeIR, ctx) {
836
902
  }
837
903
  const source = rawArg.startsWith("(") ? `${rawArg} => null` : `(${rawArg}) => null`;
838
904
  try {
839
- const expression = parseExpression(source);
905
+ const expression = parseExpression2(source);
840
906
  if (!t7.isArrowFunctionExpression(expression)) {
841
907
  return [];
842
908
  }
@@ -952,17 +1018,25 @@ function buildCtxProviderNode(nodeIR, ctx, children) {
952
1018
  if (nextProvide?.isOccupied) {
953
1019
  childNodes = [buildCtxProviderNode(nextProvide, ctx, children)];
954
1020
  }
955
- const keyProp = t10.jsxAttribute(
956
- t10.jsxIdentifier("key"),
957
- buildJsxExpressionNode(t10.identifier(name))
1021
+ const parseProviderExpr = (raw) => {
1022
+ if (!raw) return t10.stringLiteral("");
1023
+ try {
1024
+ return stringToExpr(raw, ctx.scriptData.lang, ctx.filename);
1025
+ } catch {
1026
+ return t10.stringLiteral(raw);
1027
+ }
1028
+ };
1029
+ const nameProp = t10.jsxAttribute(
1030
+ t10.jsxIdentifier("name"),
1031
+ buildJsxExpressionNode(parseProviderExpr(name))
958
1032
  );
959
1033
  const valueProp = t10.jsxAttribute(
960
1034
  t10.jsxIdentifier("value"),
961
- buildJsxExpressionNode(t10.identifier(value))
1035
+ buildJsxExpressionNode(parseProviderExpr(value))
962
1036
  );
963
1037
  void ctx;
964
1038
  const adpater = ADAPTER_RULES.runtime[VUE_API_MAP.provide];
965
- return createJsxElement(adpater.target, [keyProp, valueProp], childNodes);
1039
+ return createJsxElement(adpater.target, [nameProp, valueProp], childNodes);
966
1040
  }
967
1041
 
968
1042
  // src/core/codegen/component/jsx/syntax-processor/postprocess/build-root-jsx.ts
@@ -1270,58 +1344,6 @@ function generate(ir, ctx, options) {
1270
1344
 
1271
1345
  // src/core/parse/script-only.ts
1272
1346
  import { parse as babelParse } from "@babel/parser";
1273
-
1274
- // src/shared/babel-utils.ts
1275
- import { parseExpression as parseExpression2 } from "@babel/parser";
1276
- function getBabelParseOptions(lang = "js", context = "script", filename) {
1277
- const baseOptions = {
1278
- sourceType: "module",
1279
- sourceFilename: filename ?? "anonymous",
1280
- errorRecovery: true
1281
- // 容错模式
1282
- };
1283
- const plugins = [];
1284
- if (lang.includes("ts")) {
1285
- plugins.push("typescript");
1286
- }
1287
- if (lang.endsWith("sx")) {
1288
- if (lang.startsWith("t")) plugins.push("typescript");
1289
- plugins.push("jsx");
1290
- }
1291
- if (context === "vueTemplate") {
1292
- plugins.push("decorators-legacy");
1293
- } else if (context === "expression") {
1294
- baseOptions.sourceType = "script";
1295
- baseOptions.allowReturnOutsideFunction = true;
1296
- baseOptions.allowSuperOutsideMethod = true;
1297
- }
1298
- plugins.push("classProperties", "objectRestSpread", "asyncGenerators");
1299
- return {
1300
- ...baseOptions,
1301
- plugins: [...new Set(plugins)]
1302
- };
1303
- }
1304
- function stringToExpr(input, lang, filename = "") {
1305
- return parseExpression2(input, getBabelParseOptions(lang, "expression", filename));
1306
- }
1307
- function atComponentOrHookRoot(path7, rootScope, inScriptFile = false) {
1308
- const { parentPath, scope } = path7;
1309
- const parentBlock = scope.block;
1310
- if (!parentPath) return !inScriptFile;
1311
- if (parentBlock === rootScope) {
1312
- if (inScriptFile) return false;
1313
- if (parentPath.isBlockStatement() && parentPath.node !== rootScope) {
1314
- return false;
1315
- }
1316
- if (parentPath.isCallExpression() || parentPath.isNewExpression()) {
1317
- return false;
1318
- }
1319
- return true;
1320
- }
1321
- return false;
1322
- }
1323
-
1324
- // src/core/parse/script-only.ts
1325
1347
  function parseOnlyScript(source, ctx, options) {
1326
1348
  const lang = ctx.inputType.split("-")[1];
1327
1349
  const ast = babelParse(source, getBabelParseOptions(lang, "script", ctx.filename));
@@ -1868,6 +1890,9 @@ import * as t17 from "@babel/types";
1868
1890
  // src/core/transform/shared.ts
1869
1891
  function recordImport(ctx, pkg, name, onDemand = true) {
1870
1892
  const { imports } = ctx;
1893
+ if (isTypeOnlyImport(name)) {
1894
+ name = `type ${name}`;
1895
+ }
1871
1896
  if (imports.has(pkg)) {
1872
1897
  const list = imports.get(pkg);
1873
1898
  const foundItem = list.find((item) => item.name === name);
@@ -1878,6 +1903,10 @@ function recordImport(ctx, pkg, name, onDemand = true) {
1878
1903
  }
1879
1904
  imports.set(pkg, [{ name, onDemand }]);
1880
1905
  }
1906
+ function isTypeOnlyImport(name) {
1907
+ const arr = [REACT_API_MAP.ReactNode];
1908
+ return arr.includes(name);
1909
+ }
1881
1910
 
1882
1911
  // src/core/transform/sfc/script/shared/replace-vue-suffix.ts
1883
1912
  function replaceVueSuffix(ctx, node) {
@@ -2462,6 +2491,14 @@ function extractName(prop, ctx) {
2462
2491
  // src/core/transform/sfc/script/syntax-processor/preprocess/resolve-emit-calls.ts
2463
2492
  import * as t24 from "@babel/types";
2464
2493
  function resolveEmitCalls(ctx) {
2494
+ const formatEmitEventName = (raw) => {
2495
+ if (raw.startsWith("update:")) {
2496
+ const modelKey = raw.slice("update:".length);
2497
+ return `onUpdate${capitalize(camelCase(modelKey))}`;
2498
+ }
2499
+ const normalized = raw.includes(":") ? raw.replace(/:/g, "-") : raw;
2500
+ return `on${capitalize(camelCase(normalized))}`;
2501
+ };
2465
2502
  return {
2466
2503
  CallExpression(path7) {
2467
2504
  const { node } = path7;
@@ -2487,7 +2524,7 @@ function resolveEmitCalls(ctx) {
2487
2524
  };
2488
2525
  if (!checkIfFromDefineEmits()) return;
2489
2526
  const [callee, ...args] = node.arguments;
2490
- const eventName = t24.isStringLiteral(callee) ? `on${capitalize(camelCase(callee.value))}` : void 0;
2527
+ const eventName = t24.isStringLiteral(callee) ? formatEmitEventName(callee.value) : void 0;
2491
2528
  if (!eventName) {
2492
2529
  logger.warn(`Expected String type but got ${callee?.type}, expression will be removed`, {
2493
2530
  file: filename,
@@ -3257,7 +3294,8 @@ function createSlotScopeParam(props, ctx) {
3257
3294
  const foundBindingValue = reactiveBindings[prop]?.value;
3258
3295
  const foundBindingTypes = foundBindingValue ? expressionToTSType(foundBindingValue) : null;
3259
3296
  const typeAnnotation = foundBindingTypes ? t28.tsTypeAnnotation(foundBindingTypes) : tsType;
3260
- const propSign = t28.tsPropertySignature(t28.identifier(prop), typeAnnotation);
3297
+ const key = t28.isValidIdentifier(prop) ? t28.identifier(prop) : t28.stringLiteral(prop);
3298
+ const propSign = t28.tsPropertySignature(key, typeAnnotation);
3261
3299
  propsSigns.push(propSign);
3262
3300
  });
3263
3301
  paramId.typeAnnotation = t28.tsTypeAnnotation(t28.tsTypeLiteral(propsSigns));
@@ -3850,11 +3888,13 @@ function resolveLintRules(ctx, ast) {
3850
3888
  import { generate as generate3 } from "@babel/generator";
3851
3889
  import * as t35 from "@babel/types";
3852
3890
  function resolveProvide(ctx) {
3853
- if (ctx.inputType !== "sfc") return {};
3891
+ if (ctx.inputType === "style") return {};
3854
3892
  return {
3855
3893
  CallExpression(path7) {
3856
3894
  const { node } = path7;
3857
- if (!isCalleeNamed(node, VUE_API_MAP.provide)) return;
3895
+ const providerTarget = ADAPTER_RULES.runtime[VUE_API_MAP.provide]?.target;
3896
+ const isProvideCall = isCalleeNamed(node, VUE_API_MAP.provide) || providerTarget && isCalleeNamed(node, providerTarget);
3897
+ if (!isProvideCall) return;
3858
3898
  const { provide } = ctx.scriptData;
3859
3899
  const [key, value] = node.arguments;
3860
3900
  const target = findOrCreateCtxProvider(provide);
@@ -3879,7 +3919,7 @@ function assignProviderValue(target, key, value) {
3879
3919
  const getRawExp = (exp) => {
3880
3920
  if (!exp) return "''";
3881
3921
  if (t35.isStringLiteral(exp)) {
3882
- return `'${exp.value}'`;
3922
+ return JSON.stringify(exp.value);
3883
3923
  }
3884
3924
  if (t35.isNumericLiteral(exp)) {
3885
3925
  return exp.value.toString();
@@ -3956,11 +3996,12 @@ function processVueSyntax2(ast, ctx) {
3956
3996
  process: {
3957
3997
  applyBabel: [
3958
3998
  resolveElementRef,
3999
+ // provide 需要在 rename 之前收集并移除原始调用,避免被重命名后失配
4000
+ resolveProvide,
3959
4001
  resolveRenameAdapter,
3960
4002
  resolveArrowFnDeps,
3961
4003
  resolveUnanalyzedArrow,
3962
4004
  resolveAnalysisOnlyAdapter,
3963
- resolveProvide,
3964
4005
  resolveExprMemo,
3965
4006
  resolveLintRules
3966
4007
  ],
@@ -4128,7 +4169,7 @@ function resolveEmitsCalls(input, ctx) {
4128
4169
  if (!result) return input;
4129
4170
  const [, , eventName, args] = result;
4130
4171
  const callee = eventName.split(/[:\-]/).map((part) => capitalize(camelCase(part))).join("");
4131
- const event = args ? `on${callee}(${args})` : `on${callee}()`;
4172
+ const event = args ? `on${callee}?.(${args})` : `on${callee}?.()`;
4132
4173
  return `${ctx.propField}?.${event}`;
4133
4174
  }
4134
4175
  function matchEmitCalls(input, ctx) {
@@ -4449,6 +4490,8 @@ function resolveDefaultStyleModuleName(node) {
4449
4490
  // src/core/transform/sfc/template/syntax-processor/preprocess/resolve-style-scope-attribute.ts
4450
4491
  import {
4451
4492
  ElementTypes,
4493
+ isSlotOutlet,
4494
+ isTemplateNode,
4452
4495
  NodeTypes as NodeTypes3
4453
4496
  } from "@vue/compiler-core";
4454
4497
  function resolveStyleScopeAttribute(node, _ir, ctx) {
@@ -4470,7 +4513,7 @@ function walkElementNodes2(node, onElement) {
4470
4513
  }
4471
4514
  function injectStyleScopeAttribute(node, ctx) {
4472
4515
  const { scopeId } = ctx.styleData;
4473
- if (!scopeId || isComponentElement(node)) {
4516
+ if (!scopeId || isComponentElement(node) || isSlotOutlet(node) || isTemplateNode(node)) {
4474
4517
  return;
4475
4518
  }
4476
4519
  const hasDynamicIs = node.props.some((prop) => {
@@ -4853,9 +4896,8 @@ function resolveVModel(node, _ir, ctx, elementNode, nodeIR) {
4853
4896
  let eventPropIR;
4854
4897
  if (isComponent) {
4855
4898
  valuePropIR = createPropsIR("v-model", propName, getterName);
4856
- const getterNamespace = getRootIdName(getterName);
4857
- const eventReactName = `onUpdate${capitalize(getterNamespace)}`;
4858
- const eventVueName = `update:${getterNamespace}`;
4899
+ const eventReactName = `onUpdate${capitalize(camelCase(propName))}`;
4900
+ const eventVueName = `update:${propName}`;
4859
4901
  const isTS = ctx.scriptData?.lang?.startsWith("ts");
4860
4902
  const valueArg = isTS ? "value: any" : "value";
4861
4903
  const processedValue = applyValueModifiers("value", modifiers);
@@ -4916,12 +4958,6 @@ function applyValueModifiers(valueExp, modifiers) {
4916
4958
  }
4917
4959
  return result;
4918
4960
  }
4919
- function getRootIdName(expr) {
4920
- if (typeof expr !== "string") return;
4921
- const pattern = /^([a-zA-Z_$][a-zA-Z0-9_$]*)(?:[\.\?\.\[\(].*)?$/;
4922
- const match = pattern.exec(expr.trim());
4923
- return match?.[1];
4924
- }
4925
4961
 
4926
4962
  // src/core/transform/sfc/template/syntax-processor/process/props/resolve-v-on.ts
4927
4963
  import * as t40 from "@babel/types";
@@ -5187,7 +5223,7 @@ import { NodeTypes as NodeTypes9 } from "@vue/compiler-core";
5187
5223
 
5188
5224
  // src/core/transform/sfc/template/syntax-processor/process/resolve-template-children.ts
5189
5225
  import {
5190
- isSlotOutlet,
5226
+ isSlotOutlet as isSlotOutlet2,
5191
5227
  NodeTypes as VueNodeTypes
5192
5228
  } from "@vue/compiler-core";
5193
5229
 
@@ -5223,7 +5259,7 @@ function resolveTemplateChildren(node, nodeIR, ctx) {
5223
5259
  function resolveChildNodes(node, nodeIR, ctx, parentIR, childrenIR) {
5224
5260
  for (const child of node.children) {
5225
5261
  if (child.type === VueNodeTypes.ELEMENT) {
5226
- if (isSlotOutlet(child)) {
5262
+ if (isSlotOutlet2(child)) {
5227
5263
  resolveSlotOutletNode(child, nodeIR, ctx, parentIR, childrenIR);
5228
5264
  continue;
5229
5265
  }
@@ -5389,7 +5425,7 @@ function transform(ast, ctx, options) {
5389
5425
  }
5390
5426
 
5391
5427
  // package.json
5392
- var version = "1.1.1";
5428
+ var version = "1.2.1";
5393
5429
  var bin = {
5394
5430
  vureact: "./bin/vureact.js"
5395
5431
  };