@nasti-toolchain/nasti 1.6.5 → 1.7.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.
package/dist/index.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import { InputOptions, OutputOptions } from 'rolldown';
2
+
1
3
  interface NastiConfig {
2
4
  /** 项目根目录 */
3
5
  root?: string;
@@ -87,10 +89,28 @@ interface BuildConfig {
87
89
  minify?: boolean | 'oxc';
88
90
  sourcemap?: boolean | 'inline' | 'hidden';
89
91
  target?: string | string[];
90
- rolldownOptions?: Record<string, unknown>;
92
+ /**
93
+ * 透传给 Rolldown 的底层选项,供生产应用手动控制代码拆分与 Tree-shaking。
94
+ *
95
+ * - input 侧(`treeshake`、`resolve`、`external`、`platform` 等)会合并进 `rolldown()`;
96
+ * - `output` 会合并进 `bundle.write()`,用于控制代码拆分
97
+ * (`output.advancedChunks` / `output.codeSplitting`)、chunk 命名等。
98
+ *
99
+ * 注:`input` 与 `plugins` 由 Nasti 管理,故不在此暴露;`output.dir` 始终由
100
+ * `build.outDir` 决定(HTML 改写依赖产物路径),传入会被忽略。
101
+ */
102
+ rolldownOptions?: NastiRolldownOptions;
91
103
  emptyOutDir?: boolean;
92
104
  css?: CssConfig;
93
105
  }
106
+ /**
107
+ * Nasti 暴露的 Rolldown 选项:在 Rolldown {@link InputOptions} 基础上去掉由 Nasti
108
+ * 接管的 `input` / `plugins`,并补充一个 `output` 出口用于 `bundle.write()`。
109
+ */
110
+ type NastiRolldownOptions = Omit<InputOptions, 'input' | 'plugins'> & {
111
+ /** 传给 `bundle.write()` 的输出选项:代码拆分(`advancedChunks` / `codeSplitting`)、chunk 命名等 */
112
+ output?: OutputOptions;
113
+ };
94
114
  interface CssConfig {
95
115
  /** CSP nonce to add to inline <style> tags */
96
116
  nonce?: string;
@@ -330,4 +350,4 @@ interface MonacoEditorPluginOptions {
330
350
  }
331
351
  declare function monacoEditorPlugin(options?: MonacoEditorPluginOptions): NastiPlugin;
332
352
 
333
- export { type DevServer, type ElectronConfig, type HmrPayload, type ModuleNode, type MonacoCustomWorker, type MonacoEditorLanguageWorker, type MonacoEditorPluginOptions, type NastiConfig, type NastiPlugin, type ResolvedConfig, type TransformResult, build, buildElectron, createServer, defineConfig, electronPlugin, monacoEditorPlugin, resolveConfig, startElectronDev };
353
+ export { type BuildConfig, type DevServer, type ElectronConfig, type HmrPayload, type ModuleNode, type MonacoCustomWorker, type MonacoEditorLanguageWorker, type MonacoEditorPluginOptions, type NastiConfig, type NastiPlugin, type NastiRolldownOptions, type ResolvedConfig, type TransformResult, build, buildElectron, createServer, defineConfig, electronPlugin, monacoEditorPlugin, resolveConfig, startElectronDev };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { InputOptions, OutputOptions } from 'rolldown';
2
+
1
3
  interface NastiConfig {
2
4
  /** 项目根目录 */
3
5
  root?: string;
@@ -87,10 +89,28 @@ interface BuildConfig {
87
89
  minify?: boolean | 'oxc';
88
90
  sourcemap?: boolean | 'inline' | 'hidden';
89
91
  target?: string | string[];
90
- rolldownOptions?: Record<string, unknown>;
92
+ /**
93
+ * 透传给 Rolldown 的底层选项,供生产应用手动控制代码拆分与 Tree-shaking。
94
+ *
95
+ * - input 侧(`treeshake`、`resolve`、`external`、`platform` 等)会合并进 `rolldown()`;
96
+ * - `output` 会合并进 `bundle.write()`,用于控制代码拆分
97
+ * (`output.advancedChunks` / `output.codeSplitting`)、chunk 命名等。
98
+ *
99
+ * 注:`input` 与 `plugins` 由 Nasti 管理,故不在此暴露;`output.dir` 始终由
100
+ * `build.outDir` 决定(HTML 改写依赖产物路径),传入会被忽略。
101
+ */
102
+ rolldownOptions?: NastiRolldownOptions;
91
103
  emptyOutDir?: boolean;
92
104
  css?: CssConfig;
93
105
  }
106
+ /**
107
+ * Nasti 暴露的 Rolldown 选项:在 Rolldown {@link InputOptions} 基础上去掉由 Nasti
108
+ * 接管的 `input` / `plugins`,并补充一个 `output` 出口用于 `bundle.write()`。
109
+ */
110
+ type NastiRolldownOptions = Omit<InputOptions, 'input' | 'plugins'> & {
111
+ /** 传给 `bundle.write()` 的输出选项:代码拆分(`advancedChunks` / `codeSplitting`)、chunk 命名等 */
112
+ output?: OutputOptions;
113
+ };
94
114
  interface CssConfig {
95
115
  /** CSP nonce to add to inline <style> tags */
96
116
  nonce?: string;
@@ -330,4 +350,4 @@ interface MonacoEditorPluginOptions {
330
350
  }
331
351
  declare function monacoEditorPlugin(options?: MonacoEditorPluginOptions): NastiPlugin;
332
352
 
333
- export { type DevServer, type ElectronConfig, type HmrPayload, type ModuleNode, type MonacoCustomWorker, type MonacoEditorLanguageWorker, type MonacoEditorPluginOptions, type NastiConfig, type NastiPlugin, type ResolvedConfig, type TransformResult, build, buildElectron, createServer, defineConfig, electronPlugin, monacoEditorPlugin, resolveConfig, startElectronDev };
353
+ export { type BuildConfig, type DevServer, type ElectronConfig, type HmrPayload, type ModuleNode, type MonacoCustomWorker, type MonacoEditorLanguageWorker, type MonacoEditorPluginOptions, type NastiConfig, type NastiPlugin, type NastiRolldownOptions, type ResolvedConfig, type TransformResult, build, buildElectron, createServer, defineConfig, electronPlugin, monacoEditorPlugin, resolveConfig, startElectronDev };
package/dist/index.js CHANGED
@@ -286,6 +286,17 @@ function resolvePlugin(config) {
286
286
  const aliasEntries = Object.entries(alias).sort(
287
287
  ([a], [b]) => b.length - a.length
288
288
  );
289
+ let vueRuntimeEntry = null;
290
+ if (config.framework === "vue") {
291
+ try {
292
+ const vuePkgJson = require2.resolve("vue/package.json", { paths: [config.root] });
293
+ const vueDir = path2.dirname(vuePkgJson);
294
+ const mod = JSON.parse(fs2.readFileSync(vuePkgJson, "utf-8")).module;
295
+ const entry = path2.join(vueDir, mod ?? "dist/vue.runtime.esm-bundler.js");
296
+ if (fs2.existsSync(entry)) vueRuntimeEntry = entry;
297
+ } catch {
298
+ }
299
+ }
289
300
  return {
290
301
  name: "nasti:resolve",
291
302
  enforce: "pre",
@@ -316,6 +327,7 @@ function resolvePlugin(config) {
316
327
  if (resolved) return resolved;
317
328
  }
318
329
  if (!source.startsWith("/") && !source.startsWith(".")) {
330
+ if (vueRuntimeEntry && source === "vue") return vueRuntimeEntry;
319
331
  try {
320
332
  const resolved = require2.resolve(source, {
321
333
  paths: [importer ? path2.dirname(importer) : config.root]
@@ -400,15 +412,15 @@ async function loadTailwind(projectRoot) {
400
412
  async function compileTailwind(css, fromFile, projectRoot) {
401
413
  const { node, oxide } = await loadTailwind(projectRoot);
402
414
  const dependencies = [];
403
- const compiler = await node.compile(css, {
415
+ const compiler2 = await node.compile(css, {
404
416
  base: path3.dirname(fromFile),
405
417
  from: fromFile,
406
418
  onDependency: (p) => dependencies.push(p)
407
419
  });
408
- const scanner = new oxide.Scanner({ sources: compiler.sources });
420
+ const scanner = new oxide.Scanner({ sources: compiler2.sources });
409
421
  const candidates = scanner.scan();
410
422
  return {
411
- css: compiler.build(candidates),
423
+ css: compiler2.build(candidates),
412
424
  dependencies: [...dependencies, ...scanner.files]
413
425
  };
414
426
  }
@@ -590,6 +602,215 @@ var init_assets = __esm({
590
602
  }
591
603
  });
592
604
 
605
+ // src/core/transformer.ts
606
+ import { transformSync } from "oxc-transform";
607
+ function shouldTransform(id) {
608
+ return TS_EXTENSIONS.test(id) || JSX_EXTENSIONS.test(id) || JS_EXTENSIONS.test(id) && false;
609
+ }
610
+ function transformCode(filename, code, options = {}) {
611
+ const isTS = TS_EXTENSIONS.test(filename) || /\.tsx$/.test(filename);
612
+ const isJSX = JSX_EXTENSIONS.test(filename);
613
+ const result = transformSync(filename, code, {
614
+ typescript: isTS ? {} : void 0,
615
+ jsx: isJSX || /\.tsx$/.test(filename) ? {
616
+ runtime: options.jsxRuntime ?? "automatic",
617
+ importSource: options.jsxImportSource ?? "react",
618
+ refresh: options.reactRefresh ?? false
619
+ } : void 0,
620
+ sourcemap: options.sourcemap ?? true
621
+ });
622
+ if (result.errors && result.errors.length > 0) {
623
+ const msg = result.errors.map((e) => e.message ?? String(e)).join("\n");
624
+ throw new Error(`OXC transform failed for ${filename}:
625
+ ${msg}`);
626
+ }
627
+ return {
628
+ code: result.code,
629
+ map: result.map ? JSON.stringify(result.map) : null
630
+ };
631
+ }
632
+ var JS_EXTENSIONS, TS_EXTENSIONS, JSX_EXTENSIONS;
633
+ var init_transformer = __esm({
634
+ "src/core/transformer.ts"() {
635
+ "use strict";
636
+ JS_EXTENSIONS = /\.(js|mjs|cjs)$/;
637
+ TS_EXTENSIONS = /\.(ts|mts|cts)$/;
638
+ JSX_EXTENSIONS = /\.(jsx|tsx)$/;
639
+ }
640
+ });
641
+
642
+ // src/plugins/vue.ts
643
+ import crypto2 from "crypto";
644
+ async function loadVueCompiler() {
645
+ if (compiler) return compiler;
646
+ try {
647
+ compiler = await import("@vue/compiler-sfc");
648
+ return compiler;
649
+ } catch {
650
+ return null;
651
+ }
652
+ }
653
+ function vuePlugin(config) {
654
+ const isDev = config.command === "serve";
655
+ const descriptorCache = /* @__PURE__ */ new Map();
656
+ return {
657
+ name: "nasti:vue",
658
+ enforce: "pre",
659
+ async resolveId(source) {
660
+ if (VUE_QUERY_RE.test(source)) {
661
+ return source;
662
+ }
663
+ return null;
664
+ },
665
+ async transform(code, id) {
666
+ if (!VUE_FILE_RE.test(id) && !VUE_QUERY_RE.test(id)) return null;
667
+ const sfc = await loadVueCompiler();
668
+ if (!sfc) {
669
+ console.warn("[nasti:vue] @vue/compiler-sfc not found. Install it: npm install @vue/compiler-sfc");
670
+ return null;
671
+ }
672
+ if (VUE_QUERY_RE.test(id)) {
673
+ return handleVueSubBlock(id, sfc, descriptorCache, config);
674
+ }
675
+ const { descriptor, errors } = sfc.parse(code, { filename: id });
676
+ if (errors.length) {
677
+ console.error(`[nasti:vue] Parse error in ${id}:`, errors[0].message);
678
+ return null;
679
+ }
680
+ descriptorCache.set(id, descriptor);
681
+ const scopeId = hashId(id);
682
+ let scriptCode = "";
683
+ if (descriptor.script || descriptor.scriptSetup) {
684
+ const compiled = sfc.compileScript(descriptor, {
685
+ id: scopeId,
686
+ isProd: !isDev,
687
+ inlineTemplate: true,
688
+ // 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。
689
+ // 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个
690
+ // 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。
691
+ genDefaultAs: "__sfc__"
692
+ });
693
+ scriptCode = compiled.content;
694
+ }
695
+ let templateCode = "";
696
+ if (descriptor.template && !descriptor.scriptSetup) {
697
+ const compiled = sfc.compileTemplate({
698
+ source: descriptor.template.content,
699
+ filename: id,
700
+ id: scopeId,
701
+ compilerOptions: { scopeId: `data-v-${scopeId}` }
702
+ });
703
+ templateCode = compiled.code;
704
+ }
705
+ let output = scriptCode || "const __sfc__ = {}";
706
+ if (templateCode) {
707
+ output += `
708
+ ${templateCode}
709
+ `;
710
+ output += `
711
+ __sfc__.render = render
712
+ `;
713
+ }
714
+ if (descriptor.styles.length > 0) {
715
+ for (let i = 0; i < descriptor.styles.length; i++) {
716
+ const style = descriptor.styles[i];
717
+ const lang2 = style.lang ?? "css";
718
+ output += `
719
+ import "${id}?vue&type=style&index=${i}&lang=${lang2}"
720
+ `;
721
+ }
722
+ }
723
+ output += `
724
+ __sfc__.__scopeId = "data-v-${scopeId}"
725
+ `;
726
+ if (isDev) {
727
+ output += `
728
+ __sfc__.__hmrId = ${JSON.stringify(scopeId)}
729
+ if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
730
+ __VUE_HMR_RUNTIME__.createRecord(__sfc__.__hmrId, __sfc__)
731
+ }
732
+ if (import.meta.hot) {
733
+ import.meta.hot.accept((mod) => {
734
+ if (!mod) return
735
+ const { default: updated } = mod
736
+ if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
737
+ __VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render)
738
+ }
739
+ })
740
+ }
741
+ `;
742
+ }
743
+ output += `
744
+ export default __sfc__
745
+ `;
746
+ const lang = descriptor.scriptSetup?.lang ?? descriptor.script?.lang;
747
+ if (lang === "ts") {
748
+ const transpiled = transformCode(`${id}.ts`, output, { sourcemap: false });
749
+ return { code: transpiled.code };
750
+ }
751
+ return { code: output };
752
+ },
753
+ handleHotUpdate(ctx) {
754
+ const { file, modules } = ctx;
755
+ if (VUE_FILE_RE.test(file)) {
756
+ for (const mod of modules) {
757
+ mod.isSelfAccepting = true;
758
+ }
759
+ descriptorCache.delete(file);
760
+ }
761
+ return modules;
762
+ }
763
+ };
764
+ }
765
+ async function handleVueSubBlock(id, sfc, cache, config) {
766
+ const match = id.match(/(.+\.vue)\?vue&type=(\w+)(?:&index=(\d+))?(?:&lang=(\w+))?/);
767
+ if (!match) return null;
768
+ const [, filePath, type, indexStr, lang] = match;
769
+ const descriptor = cache.get(filePath);
770
+ if (!descriptor) return null;
771
+ if (type === "style") {
772
+ const index = parseInt(indexStr ?? "0", 10);
773
+ const style = descriptor.styles[index];
774
+ if (!style) return null;
775
+ const scopeId = hashId(filePath);
776
+ const result = await sfc.compileStyleAsync({
777
+ source: style.content,
778
+ filename: filePath,
779
+ id: `data-v-${scopeId}`,
780
+ scoped: style.scoped ?? false
781
+ });
782
+ const cssCode = JSON.stringify(result.code);
783
+ return {
784
+ code: `
785
+ const css = ${cssCode};
786
+ const style = document.createElement('style');
787
+ style.setAttribute('data-v-${scopeId}', '');
788
+ style.textContent = css;
789
+ document.head.appendChild(style);
790
+
791
+ if (import.meta.hot) {
792
+ import.meta.hot.accept();
793
+ import.meta.hot.prune(() => style.remove());
794
+ }
795
+ `
796
+ };
797
+ }
798
+ return null;
799
+ }
800
+ function hashId(filename) {
801
+ return crypto2.createHash("sha256").update(filename).digest("hex").slice(0, 8);
802
+ }
803
+ var VUE_FILE_RE, VUE_QUERY_RE, compiler;
804
+ var init_vue = __esm({
805
+ "src/plugins/vue.ts"() {
806
+ "use strict";
807
+ init_transformer();
808
+ VUE_FILE_RE = /\.vue$/;
809
+ VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang=\w+)?/;
810
+ compiler = null;
811
+ }
812
+ });
813
+
593
814
  // src/plugins/html.ts
594
815
  import path6 from "path";
595
816
  import fs4 from "fs";
@@ -673,43 +894,6 @@ window.__vite_plugin_react_preamble_installed__ = true;
673
894
  }
674
895
  });
675
896
 
676
- // src/core/transformer.ts
677
- import { transformSync } from "oxc-transform";
678
- function shouldTransform(id) {
679
- return TS_EXTENSIONS.test(id) || JSX_EXTENSIONS.test(id) || JS_EXTENSIONS.test(id) && false;
680
- }
681
- function transformCode(filename, code, options = {}) {
682
- const isTS = TS_EXTENSIONS.test(filename) || /\.tsx$/.test(filename);
683
- const isJSX = JSX_EXTENSIONS.test(filename);
684
- const result = transformSync(filename, code, {
685
- typescript: isTS ? {} : void 0,
686
- jsx: isJSX || /\.tsx$/.test(filename) ? {
687
- runtime: options.jsxRuntime ?? "automatic",
688
- importSource: options.jsxImportSource ?? "react",
689
- refresh: options.reactRefresh ?? false
690
- } : void 0,
691
- sourcemap: options.sourcemap ?? true
692
- });
693
- if (result.errors && result.errors.length > 0) {
694
- const msg = result.errors.map((e) => e.message ?? String(e)).join("\n");
695
- throw new Error(`OXC transform failed for ${filename}:
696
- ${msg}`);
697
- }
698
- return {
699
- code: result.code,
700
- map: result.map ? JSON.stringify(result.map) : null
701
- };
702
- }
703
- var JS_EXTENSIONS, TS_EXTENSIONS, JSX_EXTENSIONS;
704
- var init_transformer = __esm({
705
- "src/core/transformer.ts"() {
706
- "use strict";
707
- JS_EXTENSIONS = /\.(js|mjs|cjs)$/;
708
- TS_EXTENSIONS = /\.(ts|mts|cts)$/;
709
- JSX_EXTENSIONS = /\.(jsx|tsx)$/;
710
- }
711
- });
712
-
713
897
  // src/core/env.ts
714
898
  import path7 from "path";
715
899
  import fs5 from "fs";
@@ -903,7 +1087,7 @@ import pc from "picocolors";
903
1087
  async function build(inlineConfig = {}) {
904
1088
  const config = await resolveConfig(inlineConfig, "build");
905
1089
  const startTime = performance.now();
906
- console.log(pc.cyan("\n\u{1F528} nasti build") + pc.dim(` v${"1.6.5"}`));
1090
+ console.log(pc.cyan("\n\u{1F528} nasti build") + pc.dim(` v${"1.7.1"}`));
907
1091
  console.log(pc.dim(` root: ${config.root}`));
908
1092
  console.log(pc.dim(` mode: ${config.mode}`));
909
1093
  const outDir = path8.resolve(config.root, config.build.outDir);
@@ -936,6 +1120,7 @@ async function build(inlineConfig = {}) {
936
1120
  throw new Error("No entry point found. Add a <script> tag to index.html or create src/main.ts");
937
1121
  }
938
1122
  const builtinPlugins = [
1123
+ ...config.framework === "vue" ? [vuePlugin(config)] : [],
939
1124
  resolvePlugin(config),
940
1125
  cssPlugin(config),
941
1126
  assetsPlugin(config)
@@ -957,11 +1142,17 @@ async function build(inlineConfig = {}) {
957
1142
  };
958
1143
  const env = loadEnv(config.mode, config.root, config.envPrefix);
959
1144
  const envDefine = buildEnvDefine(env, config.mode);
960
- const existingTransform = config.build.rolldownOptions?.transform;
961
- const mergedDefine = { ...existingTransform?.define ?? {}, ...envDefine };
1145
+ const { output: userOutput, transform: userTransform, ...restInputOptions } = config.build.rolldownOptions;
1146
+ const vueDefine = config.framework === "vue" ? {
1147
+ __VUE_OPTIONS_API__: "true",
1148
+ __VUE_PROD_DEVTOOLS__: "false",
1149
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false"
1150
+ } : {};
1151
+ const mergedDefine = { ...vueDefine, ...userTransform?.define ?? {}, ...envDefine };
962
1152
  const bundle = await rolldown({
1153
+ ...restInputOptions,
963
1154
  input: entryPoints,
964
- transform: { ...existingTransform, define: mergedDefine },
1155
+ transform: { ...userTransform, define: mergedDefine },
965
1156
  plugins: [
966
1157
  oxcTransformPlugin,
967
1158
  // 转换 Nasti 插件为 Rolldown 插件格式
@@ -977,17 +1168,19 @@ async function build(inlineConfig = {}) {
977
1168
  // manifest/SW writers) rely on for final-stage artifact emission.
978
1169
  closeBundle: p.closeBundle
979
1170
  }))
980
- ],
981
- ...config.build.rolldownOptions
1171
+ ]
982
1172
  });
983
1173
  const { output } = await bundle.write({
984
- dir: outDir,
985
1174
  format: "esm",
986
1175
  sourcemap: !!config.build.sourcemap,
987
1176
  minify: !!config.build.minify,
988
1177
  entryFileNames: "assets/[name].[hash].js",
989
1178
  chunkFileNames: "assets/[name].[hash].js",
990
- assetFileNames: "assets/[name].[hash][extname]"
1179
+ assetFileNames: "assets/[name].[hash][extname]",
1180
+ // 用户可覆盖默认输出:代码拆分(advancedChunks / codeSplitting)、chunk 命名等
1181
+ ...userOutput,
1182
+ // dir 始终由 Nasti 掌管 —— 下方 HTML 改写依赖固定的产物目录,故放在最后强制生效
1183
+ dir: outDir
991
1184
  });
992
1185
  await bundle.close();
993
1186
  await pluginContainer.buildEnd();
@@ -1047,6 +1240,7 @@ var init_build = __esm({
1047
1240
  init_resolve();
1048
1241
  init_css();
1049
1242
  init_assets();
1243
+ init_vue();
1050
1244
  init_html();
1051
1245
  init_transformer();
1052
1246
  init_env();
@@ -2052,6 +2246,7 @@ import pc3 from "picocolors";
2052
2246
  async function createServer(inlineConfig = {}) {
2053
2247
  const config = await resolveConfig(inlineConfig, "serve");
2054
2248
  const allPlugins = [
2249
+ ...config.framework === "vue" ? [vuePlugin(config)] : [],
2055
2250
  resolvePlugin(config),
2056
2251
  cssPlugin(config),
2057
2252
  assetsPlugin(config),
@@ -2112,7 +2307,7 @@ async function createServer(inlineConfig = {}) {
2112
2307
  const localUrl = `http://localhost:${actualPort}`;
2113
2308
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
2114
2309
  console.log();
2115
- console.log(pc3.cyan(" nasti dev server") + pc3.dim(` v${"1.6.5"}`));
2310
+ console.log(pc3.cyan(" nasti dev server") + pc3.dim(` v${"1.7.1"}`));
2116
2311
  console.log();
2117
2312
  console.log(` ${pc3.green(">")} Local: ${pc3.cyan(localUrl)}`);
2118
2313
  if (networkUrl) {
@@ -2180,6 +2375,7 @@ var init_server = __esm({
2180
2375
  init_resolve();
2181
2376
  init_css();
2182
2377
  init_assets();
2378
+ init_vue();
2183
2379
  init_html();
2184
2380
  }
2185
2381
  });
@@ -2236,7 +2432,7 @@ async function buildElectron(inlineConfig = {}) {
2236
2432
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
2237
2433
  const startTime = performance.now();
2238
2434
  assertElectronVersion(config);
2239
- console.log(pc2.cyan("\n\u26A1 nasti build (electron)") + pc2.dim(` v${"1.6.5"}`));
2435
+ console.log(pc2.cyan("\n\u26A1 nasti build (electron)") + pc2.dim(` v${"1.7.1"}`));
2240
2436
  console.log(pc2.dim(` root: ${config.root}`));
2241
2437
  console.log(pc2.dim(` mode: ${config.mode}`));
2242
2438
  console.log(pc2.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -2314,21 +2510,23 @@ async function bundleNode(config, entry, opts) {
2314
2510
  return { code: result.code, map: result.map ? JSON.parse(result.map) : void 0 };
2315
2511
  }
2316
2512
  };
2317
- const existingTransform = config.build.rolldownOptions?.transform;
2318
- const mergedDefine = { ...existingTransform?.define ?? {}, ...envDefine };
2513
+ const { output: userOutput, transform: userTransform, ...restInputOptions } = config.build.rolldownOptions;
2514
+ const mergedDefine = { ...userTransform?.define ?? {}, ...envDefine };
2319
2515
  const bundle = await rolldown2({
2516
+ ...restInputOptions,
2320
2517
  input: entry,
2321
- transform: { ...existingTransform, define: mergedDefine },
2322
2518
  platform: "node",
2323
- plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)],
2324
- ...config.build.rolldownOptions
2519
+ transform: { ...userTransform, define: mergedDefine },
2520
+ plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
2325
2521
  });
2326
2522
  fs7.mkdirSync(path9.dirname(opts.outFile), { recursive: true });
2327
2523
  await bundle.write({
2328
- file: opts.outFile,
2329
- format: opts.format === "cjs" ? "cjs" : "esm",
2330
2524
  sourcemap: !!config.build.sourcemap,
2331
2525
  minify: !!config.build.minify,
2526
+ // 允许用户微调 output;但主进程 / preload 的单文件约束由下方键强制保证
2527
+ ...userOutput,
2528
+ file: opts.outFile,
2529
+ format: opts.format === "cjs" ? "cjs" : "esm",
2332
2530
  codeSplitting: false
2333
2531
  });
2334
2532
  await bundle.close();
@@ -2385,7 +2583,7 @@ async function startElectronDev(inlineConfig = {}) {
2385
2583
  const { noSpawn, ...rest } = inlineConfig;
2386
2584
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
2387
2585
  warnElectronVersion(config);
2388
- console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.6.5"}`));
2586
+ console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.7.1"}`));
2389
2587
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
2390
2588
  const server = await createServer2({ ...rest, target: "electron" });
2391
2589
  await server.listen();
@@ -2571,7 +2769,7 @@ function warnElectronVersion(config) {
2571
2769
  // src/plugins/monaco-editor.ts
2572
2770
  import path14 from "path";
2573
2771
  import fs11 from "fs";
2574
- import crypto2 from "crypto";
2772
+ import crypto3 from "crypto";
2575
2773
  import { createRequire as createRequire5 } from "module";
2576
2774
  var DEFAULT_WORKERS = {
2577
2775
  editorWorkerService: "monaco-editor/esm/vs/editor/editor.worker",
@@ -2685,7 +2883,7 @@ function monacoEditorPlugin(options = {}) {
2685
2883
  configResolved(config) {
2686
2884
  resolvedConfig = config;
2687
2885
  const version = readMonacoVersion(config.root);
2688
- const key = crypto2.createHash("sha1").update(version + "|" + publicPath).digest("hex").slice(0, 8);
2886
+ const key = crypto3.createHash("sha1").update(version + "|" + publicPath).digest("hex").slice(0, 8);
2689
2887
  cacheDir = path14.resolve(config.root, "node_modules/.nasti/monaco", key);
2690
2888
  },
2691
2889
  async configureServer(server) {