@nasti-toolchain/nasti 1.3.9 → 1.4.0

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/cli.cjs CHANGED
@@ -30,7 +30,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
 
32
32
  // src/config/defaults.ts
33
- var defaultResolve, defaultServer, defaultBuild, defaults;
33
+ var defaultResolve, defaultServer, defaultBuild, defaultElectron, defaults;
34
34
  var init_defaults = __esm({
35
35
  "src/config/defaults.ts"() {
36
36
  "use strict";
@@ -58,14 +58,29 @@ var init_defaults = __esm({
58
58
  rolldownOptions: {},
59
59
  emptyOutDir: true
60
60
  };
61
+ defaultElectron = {
62
+ main: "src/electron/main.ts",
63
+ preload: "src/electron/preload.ts",
64
+ renderer: "index.html",
65
+ nodeTarget: "node22",
66
+ mainFormat: "cjs",
67
+ preloadFormat: "cjs",
68
+ electronPath: "",
69
+ electronArgs: [],
70
+ autoRestart: true,
71
+ minVersion: 41,
72
+ external: ["electron"]
73
+ };
61
74
  defaults = {
62
75
  root: ".",
63
76
  base: "/",
64
77
  mode: "development",
78
+ target: "web",
65
79
  framework: "auto",
66
80
  resolve: defaultResolve,
67
81
  server: defaultServer,
68
82
  build: defaultBuild,
83
+ electron: defaultElectron,
69
84
  plugins: [],
70
85
  envPrefix: ["NASTI_", "VITE_"],
71
86
  logLevel: "info"
@@ -141,6 +156,7 @@ async function resolveConfig(inlineConfig = {}, command) {
141
156
  root,
142
157
  base: merged.base ?? defaults.base,
143
158
  mode: command === "build" ? "production" : "development",
159
+ target: merged.target ?? defaults.target,
144
160
  framework: merged.framework ?? defaults.framework,
145
161
  command,
146
162
  resolve: {
@@ -153,6 +169,7 @@ async function resolveConfig(inlineConfig = {}, command) {
153
169
  plugins: [],
154
170
  server: { ...defaults.server, ...merged.server },
155
171
  build: { ...defaults.build, ...merged.build },
172
+ electron: { ...defaults.electron, ...merged.electron },
156
173
  envPrefix: Array.isArray(merged.envPrefix) ? merged.envPrefix : merged.envPrefix ? [merged.envPrefix] : [...defaults.envPrefix],
157
174
  logLevel: merged.logLevel ?? defaults.logLevel
158
175
  };
@@ -771,8 +788,8 @@ async function bundlePackageAsEsm(entryFile) {
771
788
  return esmBundleCache.get(entryFile);
772
789
  }
773
790
  async function doBundlePackage(entryFile) {
774
- const { rolldown: rolldown2 } = await import("rolldown");
775
- const bundle = await rolldown2({
791
+ const { rolldown: rolldown4 } = await import("rolldown");
792
+ const bundle = await rolldown4({
776
793
  input: entryFile,
777
794
  // 仅将其他 npm 包外部化;相对路径(包内部文件)全部内联打包
778
795
  external: (id) => {
@@ -812,7 +829,8 @@ function rewriteExternalRequires(code) {
812
829
  const imports = [];
813
830
  for (const pkg of pkgs) {
814
831
  const safe = pkg.replace(/[^a-zA-Z0-9_$]/g, "_");
815
- imports.push(`import __req_${safe} from "/@modules/${pkg}";`);
832
+ imports.push(`import * as __ns_${safe} from "/@modules/${pkg}";`);
833
+ imports.push(`var __req_${safe} = "default" in __ns_${safe} ? __ns_${safe}["default"] : __ns_${safe};`);
816
834
  result = result.replaceAll(`__require("${pkg}")`, `__req_${safe}`);
817
835
  result = result.replaceAll(`__require('${pkg}')`, `__req_${safe}`);
818
836
  }
@@ -820,8 +838,8 @@ function rewriteExternalRequires(code) {
820
838
  }
821
839
  async function injectCjsNamedExports(code, entryFile) {
822
840
  try {
823
- const { createRequire: createRequire2 } = await import("module");
824
- const req = createRequire2(entryFile);
841
+ const { createRequire: createRequire3 } = await import("module");
842
+ const req = createRequire3(entryFile);
825
843
  const cjsExports = req(entryFile);
826
844
  if (!cjsExports || typeof cjsExports !== "object" && typeof cjsExports !== "function" || Array.isArray(cjsExports)) return code;
827
845
  const namedKeys = Object.keys(cjsExports).filter(
@@ -1442,10 +1460,11 @@ async function createServer(inlineConfig = {}) {
1442
1460
  let currentPort = finalPort;
1443
1461
  const onListening = () => {
1444
1462
  const actualPort = httpServer.address()?.port ?? currentPort;
1463
+ config.server.port = actualPort;
1445
1464
  const localUrl = `http://localhost:${actualPort}`;
1446
1465
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
1447
1466
  console.log();
1448
- console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.3.9"}`));
1467
+ console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.4.0"}`));
1449
1468
  console.log();
1450
1469
  console.log(` ${import_picocolors.default.green(">")} Local: ${import_picocolors.default.cyan(localUrl)}`);
1451
1470
  if (networkUrl) {
@@ -1515,6 +1534,45 @@ var init_server = __esm({
1515
1534
  }
1516
1535
  });
1517
1536
 
1537
+ // src/plugins/electron.ts
1538
+ function electronPlugin(config) {
1539
+ const external = /* @__PURE__ */ new Set([
1540
+ ...ELECTRON_MODULES,
1541
+ ...NODE_BUILTINS,
1542
+ ...config.electron.external ?? []
1543
+ ]);
1544
+ return {
1545
+ name: "nasti:electron",
1546
+ enforce: "pre",
1547
+ resolveId(source) {
1548
+ if (external.has(source)) {
1549
+ return { id: source, external: true };
1550
+ }
1551
+ if (source.startsWith("electron/")) {
1552
+ return { id: source, external: true };
1553
+ }
1554
+ return null;
1555
+ }
1556
+ };
1557
+ }
1558
+ var import_node_module2, NODE_BUILTINS, ELECTRON_MODULES;
1559
+ var init_electron = __esm({
1560
+ "src/plugins/electron.ts"() {
1561
+ "use strict";
1562
+ import_node_module2 = require("module");
1563
+ NODE_BUILTINS = /* @__PURE__ */ new Set([
1564
+ ...import_node_module2.builtinModules,
1565
+ ...import_node_module2.builtinModules.map((m) => `node:${m}`)
1566
+ ]);
1567
+ ELECTRON_MODULES = /* @__PURE__ */ new Set([
1568
+ "electron",
1569
+ "electron/main",
1570
+ "electron/common",
1571
+ "electron/renderer"
1572
+ ]);
1573
+ }
1574
+ });
1575
+
1518
1576
  // src/build/index.ts
1519
1577
  var build_exports = {};
1520
1578
  __export(build_exports, {
@@ -1523,7 +1581,7 @@ __export(build_exports, {
1523
1581
  async function build(inlineConfig = {}) {
1524
1582
  const config = await resolveConfig(inlineConfig, "build");
1525
1583
  const startTime = performance.now();
1526
- console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.3.9"}`));
1584
+ console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.4.0"}`));
1527
1585
  console.log(import_picocolors2.default.dim(` root: ${config.root}`));
1528
1586
  console.log(import_picocolors2.default.dim(` mode: ${config.mode}`));
1529
1587
  const outDir = import_node_path10.default.resolve(config.root, config.build.outDir);
@@ -1673,9 +1731,355 @@ var init_build = __esm({
1673
1731
  }
1674
1732
  });
1675
1733
 
1734
+ // src/build/electron.ts
1735
+ var electron_exports = {};
1736
+ __export(electron_exports, {
1737
+ buildElectron: () => buildElectron,
1738
+ detectInstalledElectron: () => detectInstalledElectron,
1739
+ normalizePreload: () => normalizePreload
1740
+ });
1741
+ async function buildElectron(inlineConfig = {}) {
1742
+ const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
1743
+ const startTime = performance.now();
1744
+ assertElectronVersion(config);
1745
+ console.log(import_picocolors3.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors3.default.dim(` v${"1.4.0"}`));
1746
+ console.log(import_picocolors3.default.dim(` root: ${config.root}`));
1747
+ console.log(import_picocolors3.default.dim(` mode: ${config.mode}`));
1748
+ console.log(import_picocolors3.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
1749
+ const outDir = import_node_path11.default.resolve(config.root, config.build.outDir);
1750
+ if (config.build.emptyOutDir && import_node_fs9.default.existsSync(outDir)) {
1751
+ import_node_fs9.default.rmSync(outDir, { recursive: true, force: true });
1752
+ }
1753
+ import_node_fs9.default.mkdirSync(outDir, { recursive: true });
1754
+ const rendererOutDir = import_node_path11.default.join(outDir, "renderer");
1755
+ const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
1756
+ await build2({
1757
+ ...inlineConfig,
1758
+ target: "web",
1759
+ build: {
1760
+ ...inlineConfig.build,
1761
+ outDir: rendererOutDir,
1762
+ emptyOutDir: false
1763
+ }
1764
+ });
1765
+ const mainEntry = import_node_path11.default.resolve(config.root, config.electron.main);
1766
+ if (!import_node_fs9.default.existsSync(mainEntry)) {
1767
+ throw new Error(
1768
+ `Electron main entry not found: ${config.electron.main}
1769
+ \u5728 nasti.config.ts \u7684 electron.main \u6307\u5B9A\u4E3B\u8FDB\u7A0B\u5165\u53E3\u6587\u4EF6\u3002`
1770
+ );
1771
+ }
1772
+ const mainFile = await bundleNode(config, mainEntry, {
1773
+ outFile: outFileName(outDir, "main", config.electron.mainFormat),
1774
+ format: config.electron.mainFormat,
1775
+ label: "main"
1776
+ });
1777
+ const preloadEntries = normalizePreload(config.electron.preload, config.root);
1778
+ const preloadFiles = [];
1779
+ for (const entry of preloadEntries) {
1780
+ if (!import_node_fs9.default.existsSync(entry)) {
1781
+ console.warn(import_picocolors3.default.yellow(` \u26A0 preload entry not found, skipped: ${entry}`));
1782
+ continue;
1783
+ }
1784
+ const base = import_node_path11.default.basename(entry).replace(/\.[^.]+$/, "");
1785
+ const out = outFileName(outDir, base, config.electron.preloadFormat);
1786
+ await bundleNode(config, entry, {
1787
+ outFile: out,
1788
+ format: config.electron.preloadFormat,
1789
+ label: `preload (${base})`
1790
+ });
1791
+ preloadFiles.push(out);
1792
+ }
1793
+ const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
1794
+ console.log(import_picocolors3.default.green(`
1795
+ \u2713 Electron build complete in ${elapsed}s`));
1796
+ console.log(import_picocolors3.default.dim(` renderer: ${import_node_path11.default.relative(config.root, rendererOutDir)}/`));
1797
+ console.log(import_picocolors3.default.dim(` main: ${import_node_path11.default.relative(config.root, mainFile)}`));
1798
+ for (const pf of preloadFiles) {
1799
+ console.log(import_picocolors3.default.dim(` preload: ${import_node_path11.default.relative(config.root, pf)}`));
1800
+ }
1801
+ console.log();
1802
+ return { rendererOutDir, mainFile, preloadFiles };
1803
+ }
1804
+ async function bundleNode(config, entry, opts) {
1805
+ const env = loadEnv(config.mode, config.root, config.envPrefix);
1806
+ const envDefine = {
1807
+ ...buildEnvDefine(env, config.mode),
1808
+ __ELECTRON__: "true",
1809
+ __NASTI_TARGET__: JSON.stringify("electron")
1810
+ };
1811
+ const oxcTransformPlugin = {
1812
+ name: "nasti:oxc-transform",
1813
+ transform(code, id) {
1814
+ if (!shouldTransform(id)) return null;
1815
+ const result = transformCode(id, code, {
1816
+ sourcemap: !!config.build.sourcemap,
1817
+ jsxRuntime: "automatic",
1818
+ jsxImportSource: config.framework === "vue" ? "vue" : "react"
1819
+ });
1820
+ return { code: result.code, map: result.map ? JSON.parse(result.map) : void 0 };
1821
+ }
1822
+ };
1823
+ const bundle = await (0, import_rolldown2.rolldown)({
1824
+ input: entry,
1825
+ define: envDefine,
1826
+ platform: "node",
1827
+ plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)],
1828
+ ...config.build.rolldownOptions
1829
+ });
1830
+ import_node_fs9.default.mkdirSync(import_node_path11.default.dirname(opts.outFile), { recursive: true });
1831
+ await bundle.write({
1832
+ file: opts.outFile,
1833
+ format: opts.format === "cjs" ? "cjs" : "esm",
1834
+ sourcemap: !!config.build.sourcemap,
1835
+ minify: !!config.build.minify,
1836
+ inlineDynamicImports: true
1837
+ });
1838
+ await bundle.close();
1839
+ console.log(import_picocolors3.default.dim(` \u2713 ${opts.label} \u2192 ${import_node_path11.default.relative(config.root, opts.outFile)}`));
1840
+ return opts.outFile;
1841
+ }
1842
+ function outFileName(outDir, base, format) {
1843
+ const ext = format === "cjs" ? ".cjs" : ".mjs";
1844
+ return import_node_path11.default.join(outDir, base + ext);
1845
+ }
1846
+ function normalizePreload(preload, root) {
1847
+ const list = Array.isArray(preload) ? preload : preload ? [preload] : [];
1848
+ return list.map((p) => import_node_path11.default.resolve(root, p));
1849
+ }
1850
+ function assertElectronVersion(config) {
1851
+ const min = config.electron.minVersion;
1852
+ const installed = detectInstalledElectron(config.root);
1853
+ if (installed && installed < min) {
1854
+ console.warn(
1855
+ import_picocolors3.default.yellow(
1856
+ ` \u26A0 \u68C0\u6D4B\u5230 Electron ${installed}\uFF0CNasti \u8981\u6C42 \u2265 ${min}\u3002\u65E7\u7248\u672C\u53EF\u80FD\u7F3A\u5C11 ESM \u4E3B\u8FDB\u7A0B\u652F\u6301\u3002`
1857
+ )
1858
+ );
1859
+ }
1860
+ }
1861
+ function detectInstalledElectron(root) {
1862
+ try {
1863
+ const pkgPath = import_node_path11.default.resolve(root, "node_modules/electron/package.json");
1864
+ if (!import_node_fs9.default.existsSync(pkgPath)) return null;
1865
+ const pkg = JSON.parse(import_node_fs9.default.readFileSync(pkgPath, "utf-8"));
1866
+ const major = parseInt(String(pkg.version).split(".")[0], 10);
1867
+ return Number.isFinite(major) ? major : null;
1868
+ } catch {
1869
+ return null;
1870
+ }
1871
+ }
1872
+ var import_node_path11, import_node_fs9, import_rolldown2, import_picocolors3;
1873
+ var init_electron2 = __esm({
1874
+ "src/build/electron.ts"() {
1875
+ "use strict";
1876
+ import_node_path11 = __toESM(require("path"), 1);
1877
+ import_node_fs9 = __toESM(require("fs"), 1);
1878
+ import_rolldown2 = require("rolldown");
1879
+ import_picocolors3 = __toESM(require("picocolors"), 1);
1880
+ init_config();
1881
+ init_resolve();
1882
+ init_electron();
1883
+ init_transformer();
1884
+ init_env();
1885
+ }
1886
+ });
1887
+
1888
+ // src/server/electron-dev.ts
1889
+ var electron_dev_exports = {};
1890
+ __export(electron_dev_exports, {
1891
+ startElectronDev: () => startElectronDev
1892
+ });
1893
+ async function startElectronDev(inlineConfig = {}) {
1894
+ const { noSpawn, ...rest } = inlineConfig;
1895
+ const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
1896
+ warnElectronVersion(config);
1897
+ console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.4.0"}`));
1898
+ const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
1899
+ const server = await createServer2({ ...rest, target: "electron" });
1900
+ await server.listen();
1901
+ const devUrl = `http://localhost:${server.config.server.port}/`;
1902
+ console.log(import_picocolors4.default.dim(` renderer: ${devUrl}`));
1903
+ const stageDir = import_node_path12.default.resolve(config.root, ".nasti");
1904
+ import_node_fs10.default.mkdirSync(stageDir, { recursive: true });
1905
+ const mainEntry = import_node_path12.default.resolve(config.root, config.electron.main);
1906
+ const preloadEntries = normalizePreload(config.electron.preload, config.root);
1907
+ const builtMainFile = import_node_path12.default.join(stageDir, "main" + extFor(config.electron.mainFormat));
1908
+ const builtPreloadFiles = [];
1909
+ const compileAll = async () => {
1910
+ await compileNode(config, mainEntry, {
1911
+ outFile: builtMainFile,
1912
+ format: config.electron.mainFormat,
1913
+ devUrl
1914
+ });
1915
+ builtPreloadFiles.length = 0;
1916
+ for (const entry of preloadEntries) {
1917
+ if (!import_node_fs10.default.existsSync(entry)) continue;
1918
+ const base = import_node_path12.default.basename(entry).replace(/\.[^.]+$/, "");
1919
+ const out = import_node_path12.default.join(stageDir, base + extFor(config.electron.preloadFormat));
1920
+ await compileNode(config, entry, {
1921
+ outFile: out,
1922
+ format: config.electron.preloadFormat,
1923
+ devUrl
1924
+ });
1925
+ builtPreloadFiles.push(out);
1926
+ }
1927
+ };
1928
+ await compileAll();
1929
+ if (noSpawn) {
1930
+ console.log(import_picocolors4.default.dim(" (noSpawn) \u5DF2\u7F16\u8BD1\u4E3B/preload\uFF0C\u8DF3\u8FC7\u542F\u52A8 Electron\u3002"));
1931
+ return;
1932
+ }
1933
+ const electronBin = resolveElectronBinary(config);
1934
+ if (!electronBin) {
1935
+ console.warn(
1936
+ import_picocolors4.default.yellow(
1937
+ " \u26A0 \u672A\u627E\u5230 Electron \u53EF\u6267\u884C\u6587\u4EF6\uFF0C\u8BF7\u5148\u5B89\u88C5\uFF1Anpm install -D electron\n \u5DF2\u7F16\u8BD1\u4E3B/preload \u81F3 .nasti/\uFF0C\u53EF\u624B\u52A8\u8FD0\u884C\u3002"
1938
+ )
1939
+ );
1940
+ return;
1941
+ }
1942
+ let child = null;
1943
+ const spawnElectron = () => {
1944
+ const args = [builtMainFile, ...config.electron.electronArgs];
1945
+ child = (0, import_node_child_process.spawn)(electronBin, args, {
1946
+ stdio: "inherit",
1947
+ env: { ...process.env, NASTI_DEV_SERVER_URL: devUrl, NASTI_TARGET: "electron" }
1948
+ });
1949
+ child.on("exit", (code) => {
1950
+ if (code !== null && child && child.__nastiKilled !== true) {
1951
+ console.log(import_picocolors4.default.dim(` Electron exited (${code}).`));
1952
+ process.exit(code ?? 0);
1953
+ }
1954
+ });
1955
+ };
1956
+ spawnElectron();
1957
+ if (config.electron.autoRestart) {
1958
+ const watchTargets = [mainEntry, ...preloadEntries].filter(import_node_fs10.default.existsSync);
1959
+ const watcher = import_chokidar2.default.watch(watchTargets, { ignoreInitial: true });
1960
+ let restarting = null;
1961
+ watcher.on("all", async () => {
1962
+ if (restarting) return;
1963
+ restarting = (async () => {
1964
+ console.log(import_picocolors4.default.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
1965
+ try {
1966
+ if (child && !child.killed) {
1967
+ ;
1968
+ child.__nastiKilled = true;
1969
+ const dying = child;
1970
+ await new Promise((resolve) => {
1971
+ const timer = setTimeout(() => resolve(), 3e3);
1972
+ dying.once("exit", () => {
1973
+ clearTimeout(timer);
1974
+ resolve();
1975
+ });
1976
+ dying.kill();
1977
+ });
1978
+ }
1979
+ await compileAll();
1980
+ spawnElectron();
1981
+ } finally {
1982
+ restarting = null;
1983
+ }
1984
+ })();
1985
+ });
1986
+ }
1987
+ }
1988
+ function extFor(format) {
1989
+ return format === "cjs" ? ".cjs" : ".mjs";
1990
+ }
1991
+ async function compileNode(config, entry, opts) {
1992
+ const env = loadEnv(config.mode, config.root, config.envPrefix);
1993
+ const envDefine = {
1994
+ ...buildEnvDefine(env, config.mode),
1995
+ __ELECTRON__: "true",
1996
+ __NASTI_TARGET__: JSON.stringify("electron"),
1997
+ __NASTI_DEV_SERVER_URL__: JSON.stringify(opts.devUrl)
1998
+ };
1999
+ const oxcTransformPlugin = {
2000
+ name: "nasti:oxc-transform",
2001
+ transform(code, id) {
2002
+ if (!shouldTransform(id)) return null;
2003
+ const result = transformCode(id, code, {
2004
+ sourcemap: !!config.build.sourcemap,
2005
+ jsxRuntime: "automatic",
2006
+ jsxImportSource: config.framework === "vue" ? "vue" : "react"
2007
+ });
2008
+ return { code: result.code, map: result.map ? JSON.parse(result.map) : void 0 };
2009
+ }
2010
+ };
2011
+ const bundle = await (0, import_rolldown3.rolldown)({
2012
+ input: entry,
2013
+ transform: { define: envDefine },
2014
+ platform: "node",
2015
+ plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
2016
+ });
2017
+ import_node_fs10.default.mkdirSync(import_node_path12.default.dirname(opts.outFile), { recursive: true });
2018
+ await bundle.write({
2019
+ file: opts.outFile,
2020
+ format: opts.format === "cjs" ? "cjs" : "esm",
2021
+ sourcemap: false,
2022
+ minify: false,
2023
+ inlineDynamicImports: true
2024
+ });
2025
+ await bundle.close();
2026
+ }
2027
+ function resolveElectronBinary(config) {
2028
+ if (config.electron.electronPath && import_node_fs10.default.existsSync(config.electron.electronPath)) {
2029
+ return config.electron.electronPath;
2030
+ }
2031
+ try {
2032
+ const require2 = (0, import_node_module3.createRequire)(import_node_path12.default.resolve(config.root, "package.json"));
2033
+ const pathFile = require2.resolve("electron");
2034
+ const electronModule = require2(pathFile);
2035
+ if (typeof electronModule === "string" && import_node_fs10.default.existsSync(electronModule)) {
2036
+ return electronModule;
2037
+ }
2038
+ } catch {
2039
+ }
2040
+ return null;
2041
+ }
2042
+ function warnElectronVersion(config) {
2043
+ const installed = detectInstalledElectron(config.root);
2044
+ if (installed === null) {
2045
+ console.warn(
2046
+ import_picocolors4.default.yellow(
2047
+ ` \u26A0 \u672A\u68C0\u6D4B\u5230 Electron\uFF0C\u8BF7\u5B89\u88C5\uFF1Anpm install -D electron@^${config.electron.minVersion}`
2048
+ )
2049
+ );
2050
+ return;
2051
+ }
2052
+ if (installed < config.electron.minVersion) {
2053
+ console.warn(
2054
+ import_picocolors4.default.yellow(
2055
+ ` \u26A0 Electron ${installed} \u4F4E\u4E8E Nasti \u8981\u6C42\u7684 ${config.electron.minVersion}\uFF0C\u67D0\u4E9B\u7279\u6027\uFF08\u5982 ESM \u4E3B\u8FDB\u7A0B\uFF09\u4E0D\u53EF\u7528\u3002`
2056
+ )
2057
+ );
2058
+ }
2059
+ }
2060
+ var import_node_path12, import_node_fs10, import_node_module3, import_node_child_process, import_chokidar2, import_picocolors4, import_rolldown3;
2061
+ var init_electron_dev = __esm({
2062
+ "src/server/electron-dev.ts"() {
2063
+ "use strict";
2064
+ import_node_path12 = __toESM(require("path"), 1);
2065
+ import_node_fs10 = __toESM(require("fs"), 1);
2066
+ import_node_module3 = require("module");
2067
+ import_node_child_process = require("child_process");
2068
+ import_chokidar2 = __toESM(require("chokidar"), 1);
2069
+ import_picocolors4 = __toESM(require("picocolors"), 1);
2070
+ init_config();
2071
+ import_rolldown3 = require("rolldown");
2072
+ init_electron();
2073
+ init_resolve();
2074
+ init_transformer();
2075
+ init_env();
2076
+ init_electron2();
2077
+ }
2078
+ });
2079
+
1676
2080
  // src/cli.ts
1677
2081
  var import_cac = require("cac");
1678
- var import_picocolors3 = __toESM(require("picocolors"), 1);
2082
+ var import_picocolors5 = __toESM(require("picocolors"), 1);
1679
2083
  var cli = (0, import_cac.cac)("nasti");
1680
2084
  cli.command("[root]", "Start dev server").alias("dev").option("--port <port>", "Port number", { default: 3e3 }).option("--host [host]", "Hostname").option("--open [path]", "Open browser on startup").option("--mode <mode>", "Set env mode").action(async (root, options) => {
1681
2085
  try {
@@ -1691,56 +2095,114 @@ cli.command("[root]", "Start dev server").alias("dev").option("--port <port>", "
1691
2095
  });
1692
2096
  await server.listen();
1693
2097
  } catch (err) {
1694
- console.error(import_picocolors3.default.red(`
2098
+ console.error(import_picocolors5.default.red(`
1695
2099
  Error starting dev server:
1696
2100
  ${err.message}
1697
2101
  `));
1698
- if (err.stack) console.error(import_picocolors3.default.dim(err.stack));
2102
+ if (err.stack) console.error(import_picocolors5.default.dim(err.stack));
1699
2103
  process.exit(1);
1700
2104
  }
1701
2105
  });
1702
- cli.command("build [root]", "Build for production").option("--outDir <dir>", "Output directory", { default: "dist" }).option("--sourcemap", "Generate source map").option("--minify", "Minify output", { default: true }).option("--mode <mode>", "Set env mode").action(async (root, options) => {
2106
+ cli.command("build [root]", "Build for production").option("--outDir <dir>", "Output directory", { default: "dist" }).option("--sourcemap", "Generate source map").option("--minify", "Minify output", { default: true }).option("--mode <mode>", "Set env mode").option("--target <target>", "Build target: web | electron", { default: "web" }).action(async (root, options) => {
1703
2107
  try {
1704
- const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
1705
- await build2({
2108
+ const target = options.target;
2109
+ if (target !== "web" && target !== "electron") {
2110
+ throw new Error(`Invalid --target "${target}". Expected "web" or "electron".`);
2111
+ }
2112
+ const inline = {
1706
2113
  root: root ?? ".",
1707
2114
  mode: options.mode ?? "production",
2115
+ target,
1708
2116
  build: {
1709
2117
  outDir: options.outDir,
1710
2118
  sourcemap: options.sourcemap,
1711
2119
  minify: options.minify
1712
2120
  }
1713
- });
2121
+ };
2122
+ if (target === "electron") {
2123
+ const { buildElectron: buildElectron2 } = await Promise.resolve().then(() => (init_electron2(), electron_exports));
2124
+ await buildElectron2(inline);
2125
+ } else {
2126
+ const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
2127
+ await build2(inline);
2128
+ }
1714
2129
  } catch (err) {
1715
- console.error(import_picocolors3.default.red(`
2130
+ console.error(import_picocolors5.default.red(`
1716
2131
  Build failed:
1717
2132
  ${err.message}
1718
2133
  `));
1719
- if (err.stack) console.error(import_picocolors3.default.dim(err.stack));
2134
+ if (err.stack) console.error(import_picocolors5.default.dim(err.stack));
2135
+ process.exit(1);
2136
+ }
2137
+ });
2138
+ cli.command("electron [root]", "Start Electron dev mode (requires electron ^41)").alias("electron-dev").option("--port <port>", "Renderer dev server port", { default: 3e3 }).option("--host [host]", "Hostname").option("--mode <mode>", "Set env mode").option("--no-spawn", "Compile main/preload but do not spawn Electron").option("--no-restart", "Disable auto-restart on main/preload changes").action(async (root, options) => {
2139
+ try {
2140
+ const { startElectronDev: startElectronDev2 } = await Promise.resolve().then(() => (init_electron_dev(), electron_dev_exports));
2141
+ await startElectronDev2({
2142
+ root: root ?? ".",
2143
+ mode: options.mode ?? "development",
2144
+ target: "electron",
2145
+ server: {
2146
+ port: options.port,
2147
+ host: options.host
2148
+ },
2149
+ electron: {
2150
+ autoRestart: options.restart !== false
2151
+ },
2152
+ noSpawn: options.spawn === false
2153
+ });
2154
+ } catch (err) {
2155
+ console.error(import_picocolors5.default.red(`
2156
+ Electron dev failed:
2157
+ ${err.message}
2158
+ `));
2159
+ if (err.stack) console.error(import_picocolors5.default.dim(err.stack));
2160
+ process.exit(1);
2161
+ }
2162
+ });
2163
+ cli.command("electron-build [root]", "Build Electron app for production").option("--outDir <dir>", "Output directory", { default: "dist" }).option("--sourcemap", "Generate source map").option("--minify", "Minify output", { default: true }).option("--mode <mode>", "Set env mode").action(async (root, options) => {
2164
+ try {
2165
+ const { buildElectron: buildElectron2 } = await Promise.resolve().then(() => (init_electron2(), electron_exports));
2166
+ await buildElectron2({
2167
+ root: root ?? ".",
2168
+ mode: options.mode ?? "production",
2169
+ target: "electron",
2170
+ build: {
2171
+ outDir: options.outDir,
2172
+ sourcemap: options.sourcemap,
2173
+ minify: options.minify
2174
+ }
2175
+ });
2176
+ } catch (err) {
2177
+ console.error(import_picocolors5.default.red(`
2178
+ Electron build failed:
2179
+ ${err.message}
2180
+ `));
2181
+ if (err.stack) console.error(import_picocolors5.default.dim(err.stack));
1720
2182
  process.exit(1);
1721
2183
  }
1722
2184
  });
1723
2185
  cli.command("preview [root]", "Preview production build").option("--port <port>", "Port number", { default: 4173 }).option("--host [host]", "Hostname").option("--outDir <dir>", "Output directory to serve", { default: "dist" }).action(async (root, options) => {
1724
2186
  try {
1725
2187
  const http2 = await import("http");
1726
- const path11 = await import("path");
2188
+ const path13 = await import("path");
1727
2189
  const sirv2 = (await import("sirv")).default;
1728
2190
  const connect2 = (await import("connect")).default;
1729
- const resolvedRoot = path11.resolve(root ?? ".");
1730
- const outDir = path11.resolve(resolvedRoot, options.outDir);
2191
+ const resolvedRoot = path13.resolve(root ?? ".");
2192
+ const outDir = path13.resolve(resolvedRoot, options.outDir);
1731
2193
  const app = connect2();
1732
2194
  app.use(sirv2(outDir, { single: true, etag: true, gzip: true, brotli: true }));
1733
2195
  const port = options.port;
1734
2196
  const host = options.host === true ? "0.0.0.0" : options.host ?? "localhost";
1735
2197
  http2.createServer(app).listen(port, host, () => {
1736
2198
  console.log();
1737
- console.log(import_picocolors3.default.cyan(" \u{1F50D} nasti preview"));
2199
+ console.log(import_picocolors5.default.cyan(" \u{1F50D} nasti preview"));
1738
2200
  console.log();
1739
- console.log(` ${import_picocolors3.default.green("\u279C")} Local: ${import_picocolors3.default.cyan(`http://localhost:${port}`)}`);
2201
+ console.log(` ${import_picocolors5.default.green("\u279C")} Local: ${import_picocolors5.default.cyan(`http://localhost:${port}`)}`);
1740
2202
  console.log();
1741
2203
  });
1742
2204
  } catch (err) {
1743
- console.error(import_picocolors3.default.red(`
2205
+ console.error(import_picocolors5.default.red(`
1744
2206
  Preview failed:
1745
2207
  ${err.message}
1746
2208
  `));
@@ -1748,6 +2210,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
1748
2210
  }
1749
2211
  });
1750
2212
  cli.help();
1751
- cli.version("1.3.9");
2213
+ cli.version("1.4.0");
1752
2214
  cli.parse();
1753
2215
  //# sourceMappingURL=cli.cjs.map