@nasti-toolchain/nasti 2.4.2 → 2.4.3

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/dist/index.d.cts CHANGED
@@ -150,6 +150,17 @@ interface VueEnvironmentOptions {
150
150
  script?: Partial<SFCScriptCompileOptions>;
151
151
  template?: Partial<SFCTemplateCompileOptions>;
152
152
  style?: Partial<SFCAsyncStyleCompileOptions>;
153
+ /**
154
+ * Vue 编译特性开关。
155
+ *
156
+ * `vapor`:将可强制进入 Vapor Mode 的 SFC(`<script setup>` / 纯 template)
157
+ * 统一按 Vapor 编译。单文件仍可通过 `<script setup vapor>` / `<template vapor>`
158
+ * 按需 opt-in。需要 `@vue/compiler-sfc` ≥ 3.6。
159
+ * @experimental
160
+ */
161
+ features?: {
162
+ vapor?: boolean;
163
+ };
153
164
  transformSfc?: VueSfcSourceTransform;
154
165
  transformTemplate?: VueSfcSourceTransform;
155
166
  transformStyle?: VueSfcSourceTransform;
package/dist/index.d.ts CHANGED
@@ -150,6 +150,17 @@ interface VueEnvironmentOptions {
150
150
  script?: Partial<SFCScriptCompileOptions>;
151
151
  template?: Partial<SFCTemplateCompileOptions>;
152
152
  style?: Partial<SFCAsyncStyleCompileOptions>;
153
+ /**
154
+ * Vue 编译特性开关。
155
+ *
156
+ * `vapor`:将可强制进入 Vapor Mode 的 SFC(`<script setup>` / 纯 template)
157
+ * 统一按 Vapor 编译。单文件仍可通过 `<script setup vapor>` / `<template vapor>`
158
+ * 按需 opt-in。需要 `@vue/compiler-sfc` ≥ 3.6。
159
+ * @experimental
160
+ */
161
+ features?: {
162
+ vapor?: boolean;
163
+ };
153
164
  transformSfc?: VueSfcSourceTransform;
154
165
  transformTemplate?: VueSfcSourceTransform;
155
166
  transformStyle?: VueSfcSourceTransform;
package/dist/index.js CHANGED
@@ -2316,8 +2316,10 @@ function vuePlugin(config, environmentName = "client") {
2316
2316
  });
2317
2317
  const scopeId = hashId(id);
2318
2318
  const wantsSourceMap = !!config.build.sourcemap || transformedSfc.map != null;
2319
+ const vapor = resolveVaporMode(descriptor, vueOptions, sfc, config);
2319
2320
  let scriptCode = "";
2320
2321
  let scriptMap;
2322
+ let scriptBindings;
2321
2323
  if (descriptor.script || descriptor.scriptSetup) {
2322
2324
  const inlineTemplate = vueOptions.script?.inlineTemplate !== false;
2323
2325
  const compiled = sfc.compileScript(descriptor, {
@@ -2329,9 +2331,11 @@ function vuePlugin(config, environmentName = "client") {
2329
2331
  // 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。
2330
2332
  // 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个
2331
2333
  // 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。
2332
- genDefaultAs: "__sfc__"
2334
+ genDefaultAs: "__sfc__",
2335
+ vapor
2333
2336
  });
2334
2337
  scriptCode = compiled.content;
2338
+ scriptBindings = compiled.bindings;
2335
2339
  scriptMap = composeSourceMapChain(
2336
2340
  [compiled.map, transformedSfc.map],
2337
2341
  { filename: id, environmentName, type: "sfc" }
@@ -2345,7 +2349,9 @@ function vuePlugin(config, environmentName = "client") {
2345
2349
  }
2346
2350
  let templateCode = "";
2347
2351
  let templateMap;
2352
+ let templateMultiRoot;
2348
2353
  const scriptSetupIsInline = !!descriptor.scriptSetup && vueOptions.script?.inlineTemplate !== false;
2354
+ const isTemplateOnlyVapor = vapor && !descriptor.script && !descriptor.scriptSetup;
2349
2355
  if (descriptor.template && !scriptSetupIsInline) {
2350
2356
  const transformedTemplate = await applySourceTransform(
2351
2357
  vueOptions.transformTemplate,
@@ -2367,12 +2373,16 @@ function vuePlugin(config, environmentName = "client") {
2367
2373
  filename: id,
2368
2374
  id: scopeId,
2369
2375
  inMap: templateInputMap,
2376
+ vapor,
2370
2377
  compilerOptions: {
2371
2378
  ...customCompilerOptions,
2379
+ // Vapor 在 bindingMetadata 缺失时需要空对象(与 Vite / compiler-sfc 一致)
2380
+ bindingMetadata: customCompilerOptions.bindingMetadata ?? scriptBindings ?? (vapor ? {} : void 0),
2372
2381
  scopeId: `data-v-${scopeId}`
2373
2382
  }
2374
2383
  });
2375
2384
  templateCode = compiled.code;
2385
+ templateMultiRoot = compiled.multiRoot;
2376
2386
  if (wantsSourceMap || transformedTemplate.map != null) {
2377
2387
  templateMap = compiled.map;
2378
2388
  }
@@ -2410,12 +2420,20 @@ function vuePlugin(config, environmentName = "client") {
2410
2420
  outputNode.add(fragment);
2411
2421
  }
2412
2422
  };
2413
- append(scriptCode || "const __sfc__ = {}", scriptMap);
2423
+ append(
2424
+ scriptCode || (vapor ? "const __sfc__ = { __vapor: true }" : "const __sfc__ = {}"),
2425
+ scriptMap
2426
+ );
2414
2427
  if (templateCode) {
2415
2428
  append("\n");
2416
2429
  append(templateCode, templateMap);
2417
2430
  append("\n");
2418
2431
  append("\n__sfc__.render = render\n");
2432
+ if (isTemplateOnlyVapor && templateMultiRoot !== void 0) {
2433
+ append(`
2434
+ __sfc__.__multiRoot = ${JSON.stringify(templateMultiRoot)}
2435
+ `);
2436
+ }
2419
2437
  }
2420
2438
  if (descriptor.styles.length > 0) {
2421
2439
  for (let i = 0; i < descriptor.styles.length; i++) {
@@ -2424,6 +2442,16 @@ import "${id}?vue&type=style&index=${i}&lang.css"
2424
2442
  `);
2425
2443
  }
2426
2444
  }
2445
+ if (vapor) {
2446
+ append(
2447
+ `
2448
+ if (!globalThis.__NASTI_VAPOR_BETA_WARNED__) {
2449
+ globalThis.__NASTI_VAPOR_BETA_WARNED__ = true
2450
+ console.warn(${JSON.stringify(VAPOR_BETA_WARNING)})
2451
+ }
2452
+ `
2453
+ );
2454
+ }
2427
2455
  append(`
2428
2456
  __sfc__.__scopeId = "data-v-${scopeId}"
2429
2457
  `);
@@ -2483,6 +2511,32 @@ if (import.meta.hot) {
2483
2511
  }
2484
2512
  };
2485
2513
  }
2514
+ function resolveVaporMode(descriptor, vueOptions, sfc, config) {
2515
+ const requested = !!descriptor.vapor || !!vueOptions.features?.vapor && canForceVaporMode(descriptor);
2516
+ if (!requested) return false;
2517
+ if (!supportsVaporCompiler(sfc)) {
2518
+ config.logger.warnOnce(
2519
+ "[nasti:vue] Vapor Mode requires @vue/compiler-sfc >= 3.6. Install it: npm install @vue/compiler-sfc@^3.6.0-0"
2520
+ );
2521
+ return false;
2522
+ }
2523
+ config.logger.warnOnce(VAPOR_BETA_WARNING);
2524
+ return true;
2525
+ }
2526
+ function canForceVaporMode(descriptor) {
2527
+ if (typeof descriptor.filename === "string" && descriptor.filename.endsWith(".vue")) {
2528
+ if (descriptor.script && !descriptor.scriptSetup) return false;
2529
+ return !!(descriptor.scriptSetup || descriptor.template);
2530
+ }
2531
+ return true;
2532
+ }
2533
+ function supportsVaporCompiler(sfc) {
2534
+ const version = sfc.version;
2535
+ if (!version) return false;
2536
+ const [major, minor] = version.split(".").map((part) => Number.parseInt(part, 10));
2537
+ if (!Number.isFinite(major) || !Number.isFinite(minor)) return false;
2538
+ return major > 3 || major === 3 && minor >= 6;
2539
+ }
2486
2540
  async function applySourceTransform(transform2, source, context) {
2487
2541
  if (!transform2) return { code: source };
2488
2542
  const result = await transform2(source, context);
@@ -2543,7 +2597,7 @@ function warnUnchainableMap(context, reason) {
2543
2597
  function hashId(filename) {
2544
2598
  return crypto2.createHash("sha256").update(filename).digest("hex").slice(0, 8);
2545
2599
  }
2546
- var VUE_FILE_RE, VUE_QUERY_RE, debug2, compiler;
2600
+ var VUE_FILE_RE, VUE_QUERY_RE, debug2, VAPOR_BETA_WARNING, compiler;
2547
2601
  var init_vue = __esm({
2548
2602
  "src/plugins/vue.ts"() {
2549
2603
  "use strict";
@@ -2552,6 +2606,7 @@ var init_vue = __esm({
2552
2606
  VUE_FILE_RE = /\.vue$/;
2553
2607
  VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang[.=]\w+)?/;
2554
2608
  debug2 = createDebugger("nasti:vue");
2609
+ VAPOR_BETA_WARNING = "Vapor Mode is a beta feature; Zixiao Labs and the Vue team do not provide guarantees against crashes in production environments, and it is not suitable for server-side rendering environments.";
2555
2610
  compiler = null;
2556
2611
  }
2557
2612
  });
@@ -3811,7 +3866,7 @@ async function build(inlineConfig = {}) {
3811
3866
  const startTime = performance.now();
3812
3867
  logger.info(
3813
3868
  pc4.cyan(`
3814
- nasti v${"2.4.2"} `) + pc4.green(`building for ${config.mode}...`)
3869
+ nasti v${"2.4.3"} `) + pc4.green(`building for ${config.mode}...`)
3815
3870
  );
3816
3871
  debug5?.(`root: ${config.root}`);
3817
3872
  const buildableNames = Object.keys(config.environments).filter((name) => {
@@ -6414,7 +6469,7 @@ async function createServer(inlineConfig = {}) {
6414
6469
  const readyIn = Math.ceil(performance.now() - startTime);
6415
6470
  logger.info(
6416
6471
  `
6417
- ${pc9.cyan(pc9.bold("NASTI"))} ${pc9.cyan(`v${"2.4.2"}`)} ${pc9.dim("ready in")} ${pc9.bold(readyIn)} ${pc9.dim("ms")}
6472
+ ${pc9.cyan(pc9.bold("NASTI"))} ${pc9.cyan(`v${"2.4.3"}`)} ${pc9.dim("ready in")} ${pc9.bold(readyIn)} ${pc9.dim("ms")}
6418
6473
  `
6419
6474
  );
6420
6475
  printServerUrls(
@@ -6605,7 +6660,7 @@ async function buildElectron(inlineConfig = {}) {
6605
6660
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
6606
6661
  const startTime = performance.now();
6607
6662
  assertElectronVersion(config);
6608
- console.log(pc5.cyan("\n\u26A1 nasti build (electron)") + pc5.dim(` v${"2.4.2"}`));
6663
+ console.log(pc5.cyan("\n\u26A1 nasti build (electron)") + pc5.dim(` v${"2.4.3"}`));
6609
6664
  console.log(pc5.dim(` root: ${config.root}`));
6610
6665
  console.log(pc5.dim(` mode: ${config.mode}`));
6611
6666
  console.log(pc5.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -6778,7 +6833,7 @@ async function startElectronDev(inlineConfig = {}) {
6778
6833
  const { noSpawn, ...rest } = inlineConfig;
6779
6834
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
6780
6835
  warnElectronVersion(config);
6781
- console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.2"}`));
6836
+ console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.3"}`));
6782
6837
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
6783
6838
  const server = await createServer2({
6784
6839
  ...rest,