@nasti-toolchain/nasti 1.7.0 → 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.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.7.0"}`));
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)
@@ -958,7 +1143,12 @@ async function build(inlineConfig = {}) {
958
1143
  const env = loadEnv(config.mode, config.root, config.envPrefix);
959
1144
  const envDefine = buildEnvDefine(env, config.mode);
960
1145
  const { output: userOutput, transform: userTransform, ...restInputOptions } = config.build.rolldownOptions;
961
- const mergedDefine = { ...userTransform?.define ?? {}, ...envDefine };
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({
963
1153
  ...restInputOptions,
964
1154
  input: entryPoints,
@@ -1050,6 +1240,7 @@ var init_build = __esm({
1050
1240
  init_resolve();
1051
1241
  init_css();
1052
1242
  init_assets();
1243
+ init_vue();
1053
1244
  init_html();
1054
1245
  init_transformer();
1055
1246
  init_env();
@@ -2055,6 +2246,7 @@ import pc3 from "picocolors";
2055
2246
  async function createServer(inlineConfig = {}) {
2056
2247
  const config = await resolveConfig(inlineConfig, "serve");
2057
2248
  const allPlugins = [
2249
+ ...config.framework === "vue" ? [vuePlugin(config)] : [],
2058
2250
  resolvePlugin(config),
2059
2251
  cssPlugin(config),
2060
2252
  assetsPlugin(config),
@@ -2115,7 +2307,7 @@ async function createServer(inlineConfig = {}) {
2115
2307
  const localUrl = `http://localhost:${actualPort}`;
2116
2308
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
2117
2309
  console.log();
2118
- console.log(pc3.cyan(" nasti dev server") + pc3.dim(` v${"1.7.0"}`));
2310
+ console.log(pc3.cyan(" nasti dev server") + pc3.dim(` v${"1.7.1"}`));
2119
2311
  console.log();
2120
2312
  console.log(` ${pc3.green(">")} Local: ${pc3.cyan(localUrl)}`);
2121
2313
  if (networkUrl) {
@@ -2183,6 +2375,7 @@ var init_server = __esm({
2183
2375
  init_resolve();
2184
2376
  init_css();
2185
2377
  init_assets();
2378
+ init_vue();
2186
2379
  init_html();
2187
2380
  }
2188
2381
  });
@@ -2239,7 +2432,7 @@ async function buildElectron(inlineConfig = {}) {
2239
2432
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
2240
2433
  const startTime = performance.now();
2241
2434
  assertElectronVersion(config);
2242
- console.log(pc2.cyan("\n\u26A1 nasti build (electron)") + pc2.dim(` v${"1.7.0"}`));
2435
+ console.log(pc2.cyan("\n\u26A1 nasti build (electron)") + pc2.dim(` v${"1.7.1"}`));
2243
2436
  console.log(pc2.dim(` root: ${config.root}`));
2244
2437
  console.log(pc2.dim(` mode: ${config.mode}`));
2245
2438
  console.log(pc2.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -2390,7 +2583,7 @@ async function startElectronDev(inlineConfig = {}) {
2390
2583
  const { noSpawn, ...rest } = inlineConfig;
2391
2584
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
2392
2585
  warnElectronVersion(config);
2393
- console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.7.0"}`));
2586
+ console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.7.1"}`));
2394
2587
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
2395
2588
  const server = await createServer2({ ...rest, target: "electron" });
2396
2589
  await server.listen();
@@ -2576,7 +2769,7 @@ function warnElectronVersion(config) {
2576
2769
  // src/plugins/monaco-editor.ts
2577
2770
  import path14 from "path";
2578
2771
  import fs11 from "fs";
2579
- import crypto2 from "crypto";
2772
+ import crypto3 from "crypto";
2580
2773
  import { createRequire as createRequire5 } from "module";
2581
2774
  var DEFAULT_WORKERS = {
2582
2775
  editorWorkerService: "monaco-editor/esm/vs/editor/editor.worker",
@@ -2690,7 +2883,7 @@ function monacoEditorPlugin(options = {}) {
2690
2883
  configResolved(config) {
2691
2884
  resolvedConfig = config;
2692
2885
  const version = readMonacoVersion(config.root);
2693
- 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);
2694
2887
  cacheDir = path14.resolve(config.root, "node_modules/.nasti/monaco", key);
2695
2888
  },
2696
2889
  async configureServer(server) {