@holix/cli 1.0.4 → 1.0.5

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.cjs CHANGED
@@ -328,49 +328,31 @@ const runDev = (0, citty.defineCommand)({
328
328
  });
329
329
  logger.success("Electron started");
330
330
  viteServer.printUrls();
331
- let isRestarting = false;
331
+ const onExit = (0, perfect_debounce.debounce)((code) => {
332
+ logger.info("Electron process exited with code", code);
333
+ watcher.close();
334
+ node_process.default.exit(code ?? 0);
335
+ }, 100);
332
336
  const cleanup = async () => {
333
337
  logger.info("正在关闭服务...");
334
- try {
335
- await electronProcess.close();
336
- logger.info("✓ Electron process closed");
337
- } catch (error) {
338
- logger.error("Failed to close Electron process:", error);
339
- }
340
- try {
341
- await viteServer.close();
342
- logger.info(" Vite server closed");
343
- } catch (error) {
344
- logger.error("Failed to close Vite server:", error);
345
- }
346
- try {
347
- await watcher.close();
348
- logger.info("✓ Watcher closed");
349
- } catch (error) {
350
- logger.error("Failed to close watcher:", error);
351
- }
338
+ node_process.default.off("SIGINT", cleanup);
339
+ node_process.default.off("SIGTERM", cleanup);
340
+ const forceExitTimeout = setTimeout(() => {
341
+ logger.warn("清理超时,强制退出进程...");
342
+ node_process.default.exit(0);
343
+ }, 3e3);
344
+ const cleanupPromises = [
345
+ electronProcess.stop().catch((error) => logger.error("Failed to close Electron:", error)),
346
+ viteServer.close().catch((error) => logger.error("Failed to close Vite:", error)),
347
+ watcher.close().catch((error) => logger.error("Failed to close Watcher:", error))
348
+ ];
349
+ await Promise.allSettled(cleanupPromises);
350
+ logger.info("✓ 所有服务已关闭");
351
+ clearTimeout(forceExitTimeout);
352
352
  node_process.default.exit(0);
353
353
  };
354
354
  node_process.default.on("SIGINT", cleanup);
355
355
  node_process.default.on("SIGTERM", cleanup);
356
- const onExit = (0, perfect_debounce.debounce)((code) => {
357
- logger.info("Electron process exited with code", code);
358
- watcher.close();
359
- node_process.default.exit(code ?? 0);
360
- }, 100);
361
- electronProcess.handleIpc("process:restart", async () => {
362
- logger.info("Electron process requested restart...");
363
- if (isRestarting) return {
364
- success: false,
365
- reason: "already restarting"
366
- };
367
- isRestarting = true;
368
- electronProcess.off("exit", onExit);
369
- await electronProcess.restart();
370
- electronProcess.on("exit", onExit);
371
- isRestarting = false;
372
- return { success: true };
373
- });
374
356
  const notifyFileChange = (0, perfect_debounce.debounce)(async (event, change) => {
375
357
  logger.info(`File ${change.event} detected: ${event}`);
376
358
  electronProcess.sendIpc("file:changed", {
package/dist/index.mjs CHANGED
@@ -327,49 +327,31 @@ const runDev = defineCommand({
327
327
  });
328
328
  logger.success("Electron started");
329
329
  viteServer.printUrls();
330
- let isRestarting = false;
330
+ const onExit = debounce((code) => {
331
+ logger.info("Electron process exited with code", code);
332
+ watcher.close();
333
+ process.exit(code ?? 0);
334
+ }, 100);
331
335
  const cleanup = async () => {
332
336
  logger.info("正在关闭服务...");
333
- try {
334
- await electronProcess.close();
335
- logger.info("✓ Electron process closed");
336
- } catch (error) {
337
- logger.error("Failed to close Electron process:", error);
338
- }
339
- try {
340
- await viteServer.close();
341
- logger.info(" Vite server closed");
342
- } catch (error) {
343
- logger.error("Failed to close Vite server:", error);
344
- }
345
- try {
346
- await watcher.close();
347
- logger.info("✓ Watcher closed");
348
- } catch (error) {
349
- logger.error("Failed to close watcher:", error);
350
- }
337
+ process.off("SIGINT", cleanup);
338
+ process.off("SIGTERM", cleanup);
339
+ const forceExitTimeout = setTimeout(() => {
340
+ logger.warn("清理超时,强制退出进程...");
341
+ process.exit(0);
342
+ }, 3e3);
343
+ const cleanupPromises = [
344
+ electronProcess.stop().catch((error) => logger.error("Failed to close Electron:", error)),
345
+ viteServer.close().catch((error) => logger.error("Failed to close Vite:", error)),
346
+ watcher.close().catch((error) => logger.error("Failed to close Watcher:", error))
347
+ ];
348
+ await Promise.allSettled(cleanupPromises);
349
+ logger.info("✓ 所有服务已关闭");
350
+ clearTimeout(forceExitTimeout);
351
351
  process.exit(0);
352
352
  };
353
353
  process.on("SIGINT", cleanup);
354
354
  process.on("SIGTERM", cleanup);
355
- const onExit = debounce((code) => {
356
- logger.info("Electron process exited with code", code);
357
- watcher.close();
358
- process.exit(code ?? 0);
359
- }, 100);
360
- electronProcess.handleIpc("process:restart", async () => {
361
- logger.info("Electron process requested restart...");
362
- if (isRestarting) return {
363
- success: false,
364
- reason: "already restarting"
365
- };
366
- isRestarting = true;
367
- electronProcess.off("exit", onExit);
368
- await electronProcess.restart();
369
- electronProcess.on("exit", onExit);
370
- isRestarting = false;
371
- return { success: true };
372
- });
373
355
  const notifyFileChange = debounce(async (event, change) => {
374
356
  logger.info(`File ${change.event} detected: ${event}`);
375
357
  electronProcess.sendIpc("file:changed", {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["viteEntry: string","err: any","electronBuild"],"sources":["../src/utils/electron-builder-config.ts","../src/utils/logger.ts","../src/vite/resolve.ts","../src/vite/build.ts","../src/commands/build.ts","../src/vite/server.ts","../src/commands/dev.ts","../src/index.ts"],"sourcesContent":["import type { HolixConfig } from '@holix/config'\r\nimport type { Configuration as ElectronBuilderConfig } from 'electron-builder'\r\nimport type { PackageJson } from 'pkg-types'\r\nimport { existsSync } from 'node:fs'\r\nimport { resolve } from 'node:path'\r\nimport { normalize } from 'pathe'\r\n/**\r\n * 根据 Holix 配置生成 electron-builder 配置\r\n */\r\nexport function generateElectronBuilderConfig(\r\n rootDir: string,\r\n config: HolixConfig,\r\n packageJson: PackageJson,\r\n): ElectronBuilderConfig {\r\n const builderConfig = config.electronBuilder || {}\r\n const appName = packageJson.name || 'holix-app'\r\n const outDir = config.outDir || '.holix'\r\n const appId = config.app?.id || `com.${appName.replace(/[^a-z0-9]/gi, '')}`\r\n\r\n // 清理 productName,移除不安全字符,但保留空格和连字符\r\n let cleanProductName = builderConfig.productName || appName\r\n\r\n // 如果没有空格和连字符,尝试将驼峰或其他格式转换为可读格式\r\n if (!/[\\s-]/.test(cleanProductName)) {\r\n // 处理驼峰命名: holixPlayground -> Holix Playground\r\n cleanProductName = cleanProductName\r\n .replace(/([a-z])([A-Z])/g, '$1 $2') // 小写后跟大写,添加空格\r\n .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2') // 连续大写后跟小写,添加空格\r\n .split(/[-_@/]/) // 按分隔符拆分\r\n .map((word: string) => word.charAt(0).toUpperCase() + word.slice(1)) // 首字母大写\r\n .join(' ')\r\n .trim()\r\n }\r\n\r\n // 移除文件系统不安全字符,但保留空格和连字符\r\n cleanProductName = cleanProductName\r\n .replace(/[@/\\\\:*?\"<>|]/g, '') // 移除不安全字符\r\n .replace(/\\s+/g, ' ') // 多个空格替换为单个空格\r\n .replace(/^[\\s-]+|[\\s-]+$/g, '') // 移除首尾空格和连字符\r\n .trim()\r\n\r\n // 如果清理后为空,使用默认值\r\n if (!cleanProductName) {\r\n cleanProductName = 'Holix App'\r\n }\r\n\r\n const relativeOutDir = normalize(outDir).replace(normalize(rootDir), '')\r\n const relativePublicDir = config.publicDir\r\n ? normalize(config.publicDir).replace(normalize(rootDir), '')\r\n : null\r\n\r\n // 检查 icon 文件是否存在\r\n const macIconPath = builderConfig.mac?.icon\r\n ? resolve(rootDir, builderConfig.mac.icon)\r\n : resolve(rootDir, 'public/icon.icns')\r\n const winIconPath = builderConfig.win?.icon\r\n ? resolve(rootDir, builderConfig.win.icon)\r\n : resolve(rootDir, 'public/icon.ico')\r\n const linuxIconPath = builderConfig.linux?.icon\r\n ? resolve(rootDir, builderConfig.linux.icon)\r\n : resolve(rootDir, 'public/icon.png')\r\n\r\n const hasMacIcon = existsSync(macIconPath)\r\n const hasWinIcon = existsSync(winIconPath)\r\n const hasLinuxIcon = existsSync(linuxIconPath)\r\n\r\n const devDependencies = Object.keys(packageJson.devDependencies || {}).map((dep) => {\r\n return `!node_modules/${dep}/**`\r\n })\r\n\r\n const files = Array.from(new Set([\r\n `${relativeOutDir.substring(1)}/**/*`,\r\n `!${relativeOutDir.substring(1)}/**/*.{ts,jsx,tsx,map,vue}`, // 排除源代码和映射文件\r\n `${relativePublicDir ? `./${relativePublicDir}/**` : ''}`,\r\n './package.json',\r\n '!tsconfig*.json',\r\n '!vite.config.*',\r\n '!holix.config.*',\r\n ...devDependencies,\r\n ...((builderConfig?.extraConfig?.files as string[]) || []),\r\n ]))\r\n\r\n return {\r\n appId,\r\n productName: cleanProductName,\r\n directories: {\r\n output: builderConfig.outputDir || 'app-dist',\r\n app: rootDir,\r\n },\r\n npmRebuild: false,\r\n nodeGypRebuild: false,\r\n buildDependenciesFromSource: false,\r\n includeSubNodeModules: false,\r\n mac: {\r\n target: (builderConfig.mac?.target || ['dmg', 'zip']) as any,\r\n category: builderConfig.mac?.category || 'public.app-category.utilities',\r\n ...(hasMacIcon ? { icon: macIconPath } : {}),\r\n },\r\n win: {\r\n target: (builderConfig.win?.target || ['nsis', 'zip']) as any,\r\n ...(hasWinIcon ? { icon: winIconPath } : {}),\r\n },\r\n linux: {\r\n target: (builderConfig.linux?.target || ['AppImage', 'deb']) as any,\r\n category: builderConfig.linux?.category || 'Utility',\r\n ...(hasLinuxIcon ? { icon: linuxIconPath } : {}),\r\n },\r\n nsis: {\r\n oneClick: builderConfig.nsis?.oneClick ?? false,\r\n allowToChangeInstallationDirectory: builderConfig.nsis?.allowToChangeInstallationDirectory ?? true,\r\n },\r\n // 允许用户通过 extraConfig 覆盖配置\r\n ...(builderConfig.extraConfig || {}),\r\n files,\r\n }\r\n}\r\n","import { consola } from 'consola'\r\n\r\nexport const logger = consola.withTag('holix')\r\n\r\nexport function banner(msg: string) {\r\n logger.box(msg)\r\n}\r\n","import type { HolixConfig } from '@holix/config'\r\nimport type { UserConfig as ViteConfig } from 'vite'\r\nimport { createRequire } from 'node:module'\r\nimport { join } from 'node:path'\r\nimport { pathToFileURL } from 'node:url'\r\n\r\nexport { mergeConfig } from 'vite'\r\n\r\nexport async function resolveViteFromCwd(\r\n cwd: string,\r\n): Promise<typeof import('vite')> {\r\n const _require = createRequire(import.meta.url)\r\n let viteEntry: string\r\n\r\n try {\r\n viteEntry = _require.resolve('vite', {\r\n paths: [cwd],\r\n })\r\n }\r\n catch {\r\n throw new Error(\r\n `[holix] Cannot find \"vite\" in project: ${cwd}\\n`\r\n + `Please install it first: pnpm add -D vite`,\r\n )\r\n }\r\n\r\n try {\r\n // 优先走 ESM\r\n return await import(pathToFileURL(viteEntry).href)\r\n }\r\n catch (err: any) {\r\n // 仅在明确是 CJS 不兼容时 fallback\r\n if (\r\n err?.code === 'ERR_REQUIRE_ESM'\r\n || err?.message?.includes('Cannot use import statement')\r\n ) {\r\n return _require(viteEntry)\r\n }\r\n\r\n throw err\r\n }\r\n}\r\n\r\nexport async function resolveViteConfigFromHolixConfig(cwd: string, holixConfig: HolixConfig): Promise<ViteConfig> {\r\n const outdir = join(holixConfig.outDir || '.holix', 'client')\r\n\r\n const viteConfig: ViteConfig = {\r\n root: cwd,\r\n base: '/',\r\n plugins: [\r\n ...(holixConfig.vitePlugins || []),\r\n ],\r\n resolve: {\r\n alias: holixConfig.alias || {},\r\n },\r\n build: {\r\n outDir: outdir,\r\n rollupOptions: {\r\n external: ['electron'],\r\n output: {\r\n // 可选:控制输出文件名\r\n entryFileNames: '[name].js',\r\n chunkFileNames: 'chunks/[name]-[hash].js',\r\n assetFileNames: 'assets/[name]-[hash][extname]',\r\n },\r\n },\r\n },\r\n }\r\n return viteConfig\r\n}\r\n","import type { HolixConfig } from '@holix/config'\r\nimport { resolveViteConfigFromHolixConfig, resolveViteFromCwd } from './resolve'\r\n\r\nexport async function buildVite(cwd: string, holixConfig: HolixConfig) {\r\n // 从用户项目的 node_modules 中解析 Vite\r\n const vite = await resolveViteFromCwd(cwd)\r\n\r\n // 创建 Vite 服务器配置\r\n const serverConfig = await resolveViteConfigFromHolixConfig(cwd, holixConfig)\r\n\r\n return vite.build(serverConfig)\r\n}\r\n","import { existsSync } from 'node:fs'\r\nimport { rm } from 'node:fs/promises'\r\nimport { platform } from 'node:os'\r\nimport { resolve } from 'node:path'\r\nimport process from 'node:process'\r\nimport { build } from '@holix/builder'\r\nimport { defineCommand } from 'citty'\r\nimport { build as electronBuild, Platform } from 'electron-builder'\r\nimport { loadHolixConfig } from '../config'\r\nimport { generateElectronBuilderConfig } from '../utils/electron-builder-config'\r\nimport { banner, logger } from '../utils/logger'\r\nimport { buildVite } from '../vite/build'\r\n\r\n/**\r\n * 获取当前平台对应的 electron-builder target\r\n */\r\nfunction getPlatformTarget(): 'mac' | 'win' | 'linux' {\r\n const currentPlatform = platform()\r\n switch (currentPlatform) {\r\n case 'darwin':\r\n return 'mac'\r\n case 'win32':\r\n return 'win'\r\n default:\r\n return 'linux'\r\n }\r\n}\r\n\r\nexport const runBuild = defineCommand({\r\n meta: {\r\n name: 'build',\r\n description: 'Build Holix application for production',\r\n },\r\n args: {\r\n clear: {\r\n type: 'boolean',\r\n description: 'clear output directory before build',\r\n default: true,\r\n },\r\n package: {\r\n type: 'boolean',\r\n description: 'package application with electron-builder after build',\r\n default: false,\r\n },\r\n target: {\r\n type: 'string',\r\n description: 'build target platform for packaging: mac, win, linux (default: current platform)',\r\n },\r\n publish: {\r\n type: 'string',\r\n description: 'publish options: never, onTag, onTagOrDraft, always',\r\n default: 'never',\r\n },\r\n },\r\n async run({ args }) {\r\n const rootDir = process.cwd()\r\n banner('🏗️ 构建 Holix 应用程序')\r\n\r\n logger.info('Root directory:', rootDir)\r\n if (args.clear) {\r\n logger.info('Clear output:', 'enabled')\r\n }\r\n\r\n try {\r\n const { config, packageJson } = await loadHolixConfig({\r\n cwd: rootDir,\r\n })\r\n\r\n logger.info('Building client and main processes...')\r\n\r\n await buildVite(rootDir, config)\r\n\r\n await build(config, packageJson, { clean: args.clear })\r\n\r\n logger.success('All builds completed successfully')\r\n\r\n // 如果启用了打包,使用 electron-builder 打包\r\n if (args.package) {\r\n logger.info('\\n📦 Packaging application with electron-builder...')\r\n\r\n const builderConfig = generateElectronBuilderConfig(rootDir, config, packageJson)\r\n const outputDir = resolve(rootDir, builderConfig.directories?.output || 'app-dist')\r\n\r\n // 清理之前的打包输出目录,避免文件占用问题\r\n if (existsSync(outputDir)) {\r\n logger.info('Cleaning previous build output...')\r\n try {\r\n await rm(outputDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 1000 })\r\n logger.success('Previous build output cleaned')\r\n }\r\n catch (cleanError) {\r\n logger.warn('Failed to clean previous build output:', cleanError)\r\n logger.warn('Continuing with build...')\r\n }\r\n }\r\n\r\n // logger.info('Electron builder config:', JSON.stringify(builderConfig, null, 2))\r\n\r\n // 确定打包目标\r\n const targetPlatform = args.target || getPlatformTarget()\r\n\r\n let targets\r\n switch (targetPlatform) {\r\n case 'mac':\r\n targets = Platform.MAC.createTarget()\r\n break\r\n case 'win':\r\n targets = Platform.WINDOWS.createTarget()\r\n break\r\n case 'linux':\r\n targets = Platform.LINUX.createTarget()\r\n break\r\n default:\r\n {\r\n logger.warn(`Unknown platform: ${targetPlatform}, using current platform`)\r\n const currentPlatform = getPlatformTarget()\r\n targets = currentPlatform === 'mac'\r\n ? Platform.MAC.createTarget()\r\n : currentPlatform === 'win'\r\n ? Platform.WINDOWS.createTarget()\r\n : Platform.LINUX.createTarget()\r\n }\r\n }\r\n\r\n // 执行打包\r\n const result = await electronBuild({\r\n targets,\r\n config: builderConfig,\r\n publish: args.publish as any,\r\n })\r\n\r\n logger.success('✅ Packaging completed successfully!')\r\n logger.info('Output directory:', outputDir)\r\n\r\n if (result && result.length > 0) {\r\n logger.success('\\nGenerated files:')\r\n result.forEach((file) => {\r\n logger.info(` - ${file}`)\r\n })\r\n }\r\n }\r\n }\r\n catch (error) {\r\n logger.error('Build failed:', error)\r\n throw error\r\n }\r\n },\r\n})\r\n","import type { HolixConfig } from '@holix/config/dist/index.mjs'\r\nimport { resolveViteConfigFromHolixConfig, resolveViteFromCwd } from './resolve'\r\n\r\n/**\r\n * 创建 Vite 开发服务器(不立即启动)\r\n *\r\n * @param options - Vite 开发服务器选项\r\n * @returns ViteDevServer 实例\r\n *\r\n * @example\r\n * ```ts\r\n * const server = await createViteDevServer({\r\n * cwd: '/path/to/project',\r\n * config: { root: './src' }\r\n * })\r\n *\r\n * // 手动启动\r\n * await server.listen()\r\n * server.printUrls()\r\n * ```\r\n */\r\nexport async function createViteDevServer(cwd: string, holixConfig: HolixConfig) {\r\n // 从用户项目的 node_modules 中解析 Vite\r\n const vite = await resolveViteFromCwd(cwd)\r\n\r\n // 创建 Vite 服务器配置\r\n const serverConfig = await resolveViteConfigFromHolixConfig(cwd, holixConfig)\r\n\r\n // 创建开发服务器(不启动)\r\n return vite.createServer(serverConfig)\r\n}\r\n","import { resolve } from 'node:path'\r\nimport process from 'node:process'\r\nimport { dev } from '@holix/builder'\r\nimport { startElectron } from '@holix/electron'\r\nimport { AsyncBatcher } from '@tanstack/pacer'\r\nimport { defineCommand } from 'citty'\r\nimport { debounce } from 'perfect-debounce'\r\nimport { loadHolixConfig } from '../config'\r\nimport { banner, logger } from '../utils/logger'\r\nimport { createViteDevServer } from '../vite/server'\r\n\r\nexport const runDev = defineCommand({\r\n meta: {\r\n name: 'dev',\r\n description: 'Start Holix development mode (with SSR + Electron hot reload)',\r\n },\r\n args: {\r\n open: {\r\n type: 'boolean',\r\n description: 'auto open Electron window',\r\n default: true,\r\n },\r\n clear: {\r\n type: 'boolean',\r\n description: 'clear output directory before build',\r\n default: true,\r\n },\r\n autoRestart: {\r\n type: 'boolean',\r\n description: 'automatically restart Electron on main process code changes',\r\n default: false,\r\n },\r\n // rebuild: {\r\n // type: 'boolean',\r\n // description: 'rebuild native modules for Electron',\r\n // default: true,\r\n // },\r\n },\r\n async run({ args }) {\r\n const rootDir = process.cwd()\r\n banner('🚀 启动 Holix 开发模式')\r\n\r\n logger.info('Root directory:', rootDir)\r\n logger.info('Auto open:', args.open)\r\n\r\n if (args.clear) {\r\n logger.info('Clear output:', 'enabled')\r\n }\r\n\r\n try {\r\n const { config, packageJson } = await loadHolixConfig({\r\n cwd: rootDir,\r\n })\r\n\r\n const viteServer = await createViteDevServer(rootDir, config)\r\n\r\n const port = config.port ?? 5183\r\n\r\n await viteServer.listen(port)\r\n\r\n logger.info('Building client and main processes...')\r\n\r\n // TODO: 重建 native 模块\r\n // if (args.rebuild) {\r\n // await import('../utils/rebuild').then(({ rebuildNativeModules }) =>\r\n // rebuildNativeModules(rootDir, packageJson),\r\n // )\r\n // logger.success('Native modules rebuilt successfully')\r\n // }\r\n // else {\r\n // logger.warn('Electron version not found in package.json, skipping native module rebuild.')\r\n // }\r\n\r\n const watcher = await dev(config, packageJson, { clean: args.clear })\r\n\r\n logger.success('✓ Client built')\r\n\r\n logger.success('All builds completed successfully')\r\n\r\n if (!packageJson.main) {\r\n logger.warn('No main entry found in package.json, skipping Electron start.')\r\n viteServer.printUrls()\r\n return\r\n }\r\n\r\n // 如果启用 open,启动 Electron 进程\r\n if (args.open && packageJson.main) {\r\n const mainEntry = resolve(rootDir, packageJson.main!)\r\n logger.info('Starting Electron...')\r\n\r\n const electronProcess = await startElectron({\r\n entry: mainEntry,\r\n cwd: rootDir,\r\n env: {\r\n NODE_ENV: 'development',\r\n },\r\n enableIpc: true, // 启用 IPC 通信\r\n })\r\n\r\n logger.success('Electron started')\r\n\r\n viteServer.printUrls()\r\n\r\n let isRestarting = false\r\n\r\n // 进程退出时的清理函数\r\n const cleanup = async () => {\r\n logger.info('正在关闭服务...')\r\n try {\r\n await electronProcess.close()\r\n logger.info('✓ Electron process closed')\r\n }\r\n catch (error) {\r\n logger.error('Failed to close Electron process:', error)\r\n }\r\n try {\r\n await viteServer.close()\r\n logger.info('✓ Vite server closed')\r\n }\r\n catch (error) {\r\n logger.error('Failed to close Vite server:', error)\r\n }\r\n try {\r\n await watcher.close()\r\n logger.info('✓ Watcher closed')\r\n }\r\n catch (error) {\r\n logger.error('Failed to close watcher:', error)\r\n }\r\n process.exit(0)\r\n }\r\n\r\n // 监听进程退出信号\r\n process.on('SIGINT', cleanup)\r\n process.on('SIGTERM', cleanup)\r\n\r\n const onExit = debounce((code: number | null) => {\r\n logger.info('Electron process exited with code', code)\r\n watcher.close()\r\n process.exit(code ?? 0)\r\n }, 100)\r\n\r\n // 注册 IPC 处理器:子进程请求重启\r\n electronProcess.handleIpc('process:restart', async () => {\r\n logger.info('Electron process requested restart...')\r\n if (isRestarting) {\r\n return { success: false, reason: 'already restarting' }\r\n }\r\n isRestarting = true\r\n electronProcess.off('exit', onExit)\r\n await electronProcess.restart()\r\n electronProcess.on('exit', onExit)\r\n isRestarting = false\r\n return { success: true }\r\n })\r\n\r\n const notifyFileChange = debounce(async (event: string[], change: any) => {\r\n logger.info(`File ${change.event} detected: ${event}`)\r\n // 发送文件变更通知到子进程,而不是重启\r\n electronProcess.sendIpc('file:changed', {\r\n path: event,\r\n event: change.event,\r\n timestamp: Date.now(),\r\n })\r\n }, 100)\r\n\r\n const batcher = new AsyncBatcher<string>(\r\n async (items) => {\r\n notifyFileChange(items, { event: 'change' })\r\n },\r\n {\r\n maxSize: 100,\r\n wait: 100,\r\n onError: (error, batch) => {\r\n logger.error('Failed to send update batch:', error, batch)\r\n },\r\n asyncRetryerOptions: {\r\n maxAttempts: 3,\r\n backoff: 'exponential',\r\n baseWait: 1000,\r\n jitter: 0.3,\r\n },\r\n },\r\n )\r\n\r\n if (args.autoRestart) {\r\n watcher.on('change', async (event, _) => {\r\n batcher.addItem(event)\r\n })\r\n }\r\n else {\r\n watcher.close()\r\n }\r\n\r\n electronProcess.on('exit', onExit)\r\n }\r\n else {\r\n watcher.close()\r\n }\r\n }\r\n catch (error) {\r\n logger.error('Build failed:', error)\r\n throw error\r\n }\r\n },\r\n})\r\n","#!/usr/bin/env node\r\nimport { defineCommand, runMain } from 'citty'\r\nimport { runBuild } from './commands/build'\r\nimport { runDev } from './commands/dev'\r\n\r\nconst main = defineCommand({\r\n meta: {\r\n name: 'holix',\r\n version: '0.1.0',\r\n description: 'Holix Application Framework CLI - Build desktop apps with Vue SSR + Electron',\r\n },\r\n args: {\r\n clear: {\r\n type: 'boolean',\r\n description: 'clear output directory before build',\r\n default: true,\r\n },\r\n },\r\n subCommands: {\r\n dev: runDev,\r\n build: runBuild,\r\n },\r\n})\r\n\r\nrunMain(main)\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["viteEntry: string","err: any","electronBuild"],"sources":["../src/utils/electron-builder-config.ts","../src/utils/logger.ts","../src/vite/resolve.ts","../src/vite/build.ts","../src/commands/build.ts","../src/vite/server.ts","../src/commands/dev.ts","../src/index.ts"],"sourcesContent":["import type { HolixConfig } from '@holix/config'\r\nimport type { Configuration as ElectronBuilderConfig } from 'electron-builder'\r\nimport type { PackageJson } from 'pkg-types'\r\nimport { existsSync } from 'node:fs'\r\nimport { resolve } from 'node:path'\r\nimport { normalize } from 'pathe'\r\n/**\r\n * 根据 Holix 配置生成 electron-builder 配置\r\n */\r\nexport function generateElectronBuilderConfig(\r\n rootDir: string,\r\n config: HolixConfig,\r\n packageJson: PackageJson,\r\n): ElectronBuilderConfig {\r\n const builderConfig = config.electronBuilder || {}\r\n const appName = packageJson.name || 'holix-app'\r\n const outDir = config.outDir || '.holix'\r\n const appId = config.app?.id || `com.${appName.replace(/[^a-z0-9]/gi, '')}`\r\n\r\n // 清理 productName,移除不安全字符,但保留空格和连字符\r\n let cleanProductName = builderConfig.productName || appName\r\n\r\n // 如果没有空格和连字符,尝试将驼峰或其他格式转换为可读格式\r\n if (!/[\\s-]/.test(cleanProductName)) {\r\n // 处理驼峰命名: holixPlayground -> Holix Playground\r\n cleanProductName = cleanProductName\r\n .replace(/([a-z])([A-Z])/g, '$1 $2') // 小写后跟大写,添加空格\r\n .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2') // 连续大写后跟小写,添加空格\r\n .split(/[-_@/]/) // 按分隔符拆分\r\n .map((word: string) => word.charAt(0).toUpperCase() + word.slice(1)) // 首字母大写\r\n .join(' ')\r\n .trim()\r\n }\r\n\r\n // 移除文件系统不安全字符,但保留空格和连字符\r\n cleanProductName = cleanProductName\r\n .replace(/[@/\\\\:*?\"<>|]/g, '') // 移除不安全字符\r\n .replace(/\\s+/g, ' ') // 多个空格替换为单个空格\r\n .replace(/^[\\s-]+|[\\s-]+$/g, '') // 移除首尾空格和连字符\r\n .trim()\r\n\r\n // 如果清理后为空,使用默认值\r\n if (!cleanProductName) {\r\n cleanProductName = 'Holix App'\r\n }\r\n\r\n const relativeOutDir = normalize(outDir).replace(normalize(rootDir), '')\r\n const relativePublicDir = config.publicDir\r\n ? normalize(config.publicDir).replace(normalize(rootDir), '')\r\n : null\r\n\r\n // 检查 icon 文件是否存在\r\n const macIconPath = builderConfig.mac?.icon\r\n ? resolve(rootDir, builderConfig.mac.icon)\r\n : resolve(rootDir, 'public/icon.icns')\r\n const winIconPath = builderConfig.win?.icon\r\n ? resolve(rootDir, builderConfig.win.icon)\r\n : resolve(rootDir, 'public/icon.ico')\r\n const linuxIconPath = builderConfig.linux?.icon\r\n ? resolve(rootDir, builderConfig.linux.icon)\r\n : resolve(rootDir, 'public/icon.png')\r\n\r\n const hasMacIcon = existsSync(macIconPath)\r\n const hasWinIcon = existsSync(winIconPath)\r\n const hasLinuxIcon = existsSync(linuxIconPath)\r\n\r\n const devDependencies = Object.keys(packageJson.devDependencies || {}).map((dep) => {\r\n return `!node_modules/${dep}/**`\r\n })\r\n\r\n const files = Array.from(new Set([\r\n `${relativeOutDir.substring(1)}/**/*`,\r\n `!${relativeOutDir.substring(1)}/**/*.{ts,jsx,tsx,map,vue}`, // 排除源代码和映射文件\r\n `${relativePublicDir ? `./${relativePublicDir}/**` : ''}`,\r\n './package.json',\r\n '!tsconfig*.json',\r\n '!vite.config.*',\r\n '!holix.config.*',\r\n ...devDependencies,\r\n ...((builderConfig?.extraConfig?.files as string[]) || []),\r\n ]))\r\n\r\n return {\r\n appId,\r\n productName: cleanProductName,\r\n directories: {\r\n output: builderConfig.outputDir || 'app-dist',\r\n app: rootDir,\r\n },\r\n npmRebuild: false,\r\n nodeGypRebuild: false,\r\n buildDependenciesFromSource: false,\r\n includeSubNodeModules: false,\r\n mac: {\r\n target: (builderConfig.mac?.target || ['dmg', 'zip']) as any,\r\n category: builderConfig.mac?.category || 'public.app-category.utilities',\r\n ...(hasMacIcon ? { icon: macIconPath } : {}),\r\n },\r\n win: {\r\n target: (builderConfig.win?.target || ['nsis', 'zip']) as any,\r\n ...(hasWinIcon ? { icon: winIconPath } : {}),\r\n },\r\n linux: {\r\n target: (builderConfig.linux?.target || ['AppImage', 'deb']) as any,\r\n category: builderConfig.linux?.category || 'Utility',\r\n ...(hasLinuxIcon ? { icon: linuxIconPath } : {}),\r\n },\r\n nsis: {\r\n oneClick: builderConfig.nsis?.oneClick ?? false,\r\n allowToChangeInstallationDirectory: builderConfig.nsis?.allowToChangeInstallationDirectory ?? true,\r\n },\r\n // 允许用户通过 extraConfig 覆盖配置\r\n ...(builderConfig.extraConfig || {}),\r\n files,\r\n }\r\n}\r\n","import { consola } from 'consola'\r\n\r\nexport const logger = consola.withTag('holix')\r\n\r\nexport function banner(msg: string) {\r\n logger.box(msg)\r\n}\r\n","import type { HolixConfig } from '@holix/config'\r\nimport type { UserConfig as ViteConfig } from 'vite'\r\nimport { createRequire } from 'node:module'\r\nimport { join } from 'node:path'\r\nimport { pathToFileURL } from 'node:url'\r\n\r\nexport { mergeConfig } from 'vite'\r\n\r\nexport async function resolveViteFromCwd(\r\n cwd: string,\r\n): Promise<typeof import('vite')> {\r\n const _require = createRequire(import.meta.url)\r\n let viteEntry: string\r\n\r\n try {\r\n viteEntry = _require.resolve('vite', {\r\n paths: [cwd],\r\n })\r\n }\r\n catch {\r\n throw new Error(\r\n `[holix] Cannot find \"vite\" in project: ${cwd}\\n`\r\n + `Please install it first: pnpm add -D vite`,\r\n )\r\n }\r\n\r\n try {\r\n // 优先走 ESM\r\n return await import(pathToFileURL(viteEntry).href)\r\n }\r\n catch (err: any) {\r\n // 仅在明确是 CJS 不兼容时 fallback\r\n if (\r\n err?.code === 'ERR_REQUIRE_ESM'\r\n || err?.message?.includes('Cannot use import statement')\r\n ) {\r\n return _require(viteEntry)\r\n }\r\n\r\n throw err\r\n }\r\n}\r\n\r\nexport async function resolveViteConfigFromHolixConfig(cwd: string, holixConfig: HolixConfig): Promise<ViteConfig> {\r\n const outdir = join(holixConfig.outDir || '.holix', 'client')\r\n\r\n const viteConfig: ViteConfig = {\r\n root: cwd,\r\n base: '/',\r\n plugins: [\r\n ...(holixConfig.vitePlugins || []),\r\n ],\r\n resolve: {\r\n alias: holixConfig.alias || {},\r\n },\r\n build: {\r\n outDir: outdir,\r\n rollupOptions: {\r\n external: ['electron'],\r\n output: {\r\n // 可选:控制输出文件名\r\n entryFileNames: '[name].js',\r\n chunkFileNames: 'chunks/[name]-[hash].js',\r\n assetFileNames: 'assets/[name]-[hash][extname]',\r\n },\r\n },\r\n },\r\n }\r\n return viteConfig\r\n}\r\n","import type { HolixConfig } from '@holix/config'\r\nimport { resolveViteConfigFromHolixConfig, resolveViteFromCwd } from './resolve'\r\n\r\nexport async function buildVite(cwd: string, holixConfig: HolixConfig) {\r\n // 从用户项目的 node_modules 中解析 Vite\r\n const vite = await resolveViteFromCwd(cwd)\r\n\r\n // 创建 Vite 服务器配置\r\n const serverConfig = await resolveViteConfigFromHolixConfig(cwd, holixConfig)\r\n\r\n return vite.build(serverConfig)\r\n}\r\n","import { existsSync } from 'node:fs'\r\nimport { rm } from 'node:fs/promises'\r\nimport { platform } from 'node:os'\r\nimport { resolve } from 'node:path'\r\nimport process from 'node:process'\r\nimport { build } from '@holix/builder'\r\nimport { defineCommand } from 'citty'\r\nimport { build as electronBuild, Platform } from 'electron-builder'\r\nimport { loadHolixConfig } from '../config'\r\nimport { generateElectronBuilderConfig } from '../utils/electron-builder-config'\r\nimport { banner, logger } from '../utils/logger'\r\nimport { buildVite } from '../vite/build'\r\n\r\n/**\r\n * 获取当前平台对应的 electron-builder target\r\n */\r\nfunction getPlatformTarget(): 'mac' | 'win' | 'linux' {\r\n const currentPlatform = platform()\r\n switch (currentPlatform) {\r\n case 'darwin':\r\n return 'mac'\r\n case 'win32':\r\n return 'win'\r\n default:\r\n return 'linux'\r\n }\r\n}\r\n\r\nexport const runBuild = defineCommand({\r\n meta: {\r\n name: 'build',\r\n description: 'Build Holix application for production',\r\n },\r\n args: {\r\n clear: {\r\n type: 'boolean',\r\n description: 'clear output directory before build',\r\n default: true,\r\n },\r\n package: {\r\n type: 'boolean',\r\n description: 'package application with electron-builder after build',\r\n default: false,\r\n },\r\n target: {\r\n type: 'string',\r\n description: 'build target platform for packaging: mac, win, linux (default: current platform)',\r\n },\r\n publish: {\r\n type: 'string',\r\n description: 'publish options: never, onTag, onTagOrDraft, always',\r\n default: 'never',\r\n },\r\n },\r\n async run({ args }) {\r\n const rootDir = process.cwd()\r\n banner('🏗️ 构建 Holix 应用程序')\r\n\r\n logger.info('Root directory:', rootDir)\r\n if (args.clear) {\r\n logger.info('Clear output:', 'enabled')\r\n }\r\n\r\n try {\r\n const { config, packageJson } = await loadHolixConfig({\r\n cwd: rootDir,\r\n })\r\n\r\n logger.info('Building client and main processes...')\r\n\r\n await buildVite(rootDir, config)\r\n\r\n await build(config, packageJson, { clean: args.clear })\r\n\r\n logger.success('All builds completed successfully')\r\n\r\n // 如果启用了打包,使用 electron-builder 打包\r\n if (args.package) {\r\n logger.info('\\n📦 Packaging application with electron-builder...')\r\n\r\n const builderConfig = generateElectronBuilderConfig(rootDir, config, packageJson)\r\n const outputDir = resolve(rootDir, builderConfig.directories?.output || 'app-dist')\r\n\r\n // 清理之前的打包输出目录,避免文件占用问题\r\n if (existsSync(outputDir)) {\r\n logger.info('Cleaning previous build output...')\r\n try {\r\n await rm(outputDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 1000 })\r\n logger.success('Previous build output cleaned')\r\n }\r\n catch (cleanError) {\r\n logger.warn('Failed to clean previous build output:', cleanError)\r\n logger.warn('Continuing with build...')\r\n }\r\n }\r\n\r\n // logger.info('Electron builder config:', JSON.stringify(builderConfig, null, 2))\r\n\r\n // 确定打包目标\r\n const targetPlatform = args.target || getPlatformTarget()\r\n\r\n let targets\r\n switch (targetPlatform) {\r\n case 'mac':\r\n targets = Platform.MAC.createTarget()\r\n break\r\n case 'win':\r\n targets = Platform.WINDOWS.createTarget()\r\n break\r\n case 'linux':\r\n targets = Platform.LINUX.createTarget()\r\n break\r\n default:\r\n {\r\n logger.warn(`Unknown platform: ${targetPlatform}, using current platform`)\r\n const currentPlatform = getPlatformTarget()\r\n targets = currentPlatform === 'mac'\r\n ? Platform.MAC.createTarget()\r\n : currentPlatform === 'win'\r\n ? Platform.WINDOWS.createTarget()\r\n : Platform.LINUX.createTarget()\r\n }\r\n }\r\n\r\n // 执行打包\r\n const result = await electronBuild({\r\n targets,\r\n config: builderConfig,\r\n publish: args.publish as any,\r\n })\r\n\r\n logger.success('✅ Packaging completed successfully!')\r\n logger.info('Output directory:', outputDir)\r\n\r\n if (result && result.length > 0) {\r\n logger.success('\\nGenerated files:')\r\n result.forEach((file) => {\r\n logger.info(` - ${file}`)\r\n })\r\n }\r\n }\r\n }\r\n catch (error) {\r\n logger.error('Build failed:', error)\r\n throw error\r\n }\r\n },\r\n})\r\n","import type { HolixConfig } from '@holix/config/dist/index.mjs'\r\nimport { resolveViteConfigFromHolixConfig, resolveViteFromCwd } from './resolve'\r\n\r\n/**\r\n * 创建 Vite 开发服务器(不立即启动)\r\n *\r\n * @param options - Vite 开发服务器选项\r\n * @returns ViteDevServer 实例\r\n *\r\n * @example\r\n * ```ts\r\n * const server = await createViteDevServer({\r\n * cwd: '/path/to/project',\r\n * config: { root: './src' }\r\n * })\r\n *\r\n * // 手动启动\r\n * await server.listen()\r\n * server.printUrls()\r\n * ```\r\n */\r\nexport async function createViteDevServer(cwd: string, holixConfig: HolixConfig) {\r\n // 从用户项目的 node_modules 中解析 Vite\r\n const vite = await resolveViteFromCwd(cwd)\r\n\r\n // 创建 Vite 服务器配置\r\n const serverConfig = await resolveViteConfigFromHolixConfig(cwd, holixConfig)\r\n\r\n // 创建开发服务器(不启动)\r\n return vite.createServer(serverConfig)\r\n}\r\n","import { resolve } from 'node:path'\r\nimport process from 'node:process'\r\nimport { dev } from '@holix/builder'\r\nimport { startElectron } from '@holix/electron'\r\nimport { AsyncBatcher } from '@tanstack/pacer'\r\nimport { defineCommand } from 'citty'\r\nimport { debounce } from 'perfect-debounce'\r\nimport { loadHolixConfig } from '../config'\r\nimport { banner, logger } from '../utils/logger'\r\nimport { createViteDevServer } from '../vite/server'\r\n\r\nexport const runDev = defineCommand({\r\n meta: {\r\n name: 'dev',\r\n description: 'Start Holix development mode (with SSR + Electron hot reload)',\r\n },\r\n args: {\r\n open: {\r\n type: 'boolean',\r\n description: 'auto open Electron window',\r\n default: true,\r\n },\r\n clear: {\r\n type: 'boolean',\r\n description: 'clear output directory before build',\r\n default: true,\r\n },\r\n autoRestart: {\r\n type: 'boolean',\r\n description: 'automatically restart Electron on main process code changes',\r\n default: false,\r\n },\r\n // rebuild: {\r\n // type: 'boolean',\r\n // description: 'rebuild native modules for Electron',\r\n // default: true,\r\n // },\r\n },\r\n async run({ args }) {\r\n const rootDir = process.cwd()\r\n banner('🚀 启动 Holix 开发模式')\r\n\r\n logger.info('Root directory:', rootDir)\r\n logger.info('Auto open:', args.open)\r\n\r\n if (args.clear) {\r\n logger.info('Clear output:', 'enabled')\r\n }\r\n\r\n try {\r\n const { config, packageJson } = await loadHolixConfig({\r\n cwd: rootDir,\r\n })\r\n\r\n const viteServer = await createViteDevServer(rootDir, config)\r\n\r\n const port = config.port ?? 5183\r\n\r\n await viteServer.listen(port)\r\n\r\n logger.info('Building client and main processes...')\r\n\r\n // TODO: 重建 native 模块\r\n // if (args.rebuild) {\r\n // await import('../utils/rebuild').then(({ rebuildNativeModules }) =>\r\n // rebuildNativeModules(rootDir, packageJson),\r\n // )\r\n // logger.success('Native modules rebuilt successfully')\r\n // }\r\n // else {\r\n // logger.warn('Electron version not found in package.json, skipping native module rebuild.')\r\n // }\r\n\r\n const watcher = await dev(config, packageJson, { clean: args.clear })\r\n\r\n logger.success('✓ Client built')\r\n\r\n logger.success('All builds completed successfully')\r\n\r\n if (!packageJson.main) {\r\n logger.warn('No main entry found in package.json, skipping Electron start.')\r\n viteServer.printUrls()\r\n return\r\n }\r\n\r\n // 如果启用 open,启动 Electron 进程\r\n if (args.open && packageJson.main) {\r\n const mainEntry = resolve(rootDir, packageJson.main!)\r\n logger.info('Starting Electron...')\r\n\r\n const electronProcess = await startElectron({\r\n entry: mainEntry,\r\n cwd: rootDir,\r\n env: {\r\n NODE_ENV: 'development',\r\n },\r\n enableIpc: true, // 启用 IPC 通信\r\n })\r\n\r\n logger.success('Electron started')\r\n\r\n viteServer.printUrls()\r\n\r\n // let isRestarting = false\r\n const onExit = debounce((code: number | null) => {\r\n logger.info('Electron process exited with code', code)\r\n watcher.close()\r\n process.exit(code ?? 0)\r\n }, 100)\r\n // 进程退出时的清理函数\r\n const cleanup = async () => {\r\n logger.info('正在关闭服务...')\r\n\r\n // 移除事件监听器,避免重复触发和竞态条件\r\n process.off('SIGINT', cleanup)\r\n process.off('SIGTERM', cleanup)\r\n // 设置强制退出超时(3秒后强制退出)\r\n const forceExitTimeout = setTimeout(() => {\r\n logger.warn('清理超时,强制退出进程...')\r\n process.exit(0)\r\n }, 3000)\r\n\r\n // 并行执行所有清理操作\r\n const cleanupPromises = [\r\n electronProcess.stop().catch(error => logger.error('Failed to close Electron:', error)),\r\n viteServer.close().catch(error => logger.error('Failed to close Vite:', error)),\r\n watcher.close().catch(error => logger.error('Failed to close Watcher:', error)),\r\n ]\r\n\r\n // 等待所有清理完成或超时\r\n await Promise.allSettled(cleanupPromises)\r\n\r\n logger.info('✓ 所有服务已关闭')\r\n\r\n // 清理成功,取消强制退出超时\r\n clearTimeout(forceExitTimeout)\r\n\r\n // 立即退出\r\n process.exit(0)\r\n }\r\n\r\n // // // 监听进程退出信号\r\n process.on('SIGINT', cleanup)\r\n process.on('SIGTERM', cleanup)\r\n\r\n // 注册 IPC 处理器:子进程请求重启\r\n // electronProcess.handleIpc('process:restart', async () => {\r\n // logger.info('Electron process requested restart...')\r\n // if (isRestarting) {\r\n // return { success: false, reason: 'already restarting' }\r\n // }\r\n // isRestarting = true\r\n // electronProcess.off('exit', onExit)\r\n // await electronProcess.restart()\r\n // electronProcess.on('exit', onExit)\r\n // isRestarting = false\r\n // return { success: true }\r\n // })\r\n\r\n const notifyFileChange = debounce(async (event: string[], change: any) => {\r\n logger.info(`File ${change.event} detected: ${event}`)\r\n // 发送文件变更通知到子进程,而不是重启\r\n electronProcess.sendIpc('file:changed', {\r\n path: event,\r\n event: change.event,\r\n timestamp: Date.now(),\r\n })\r\n }, 100)\r\n\r\n const batcher = new AsyncBatcher<string>(\r\n async (items) => {\r\n notifyFileChange(items, { event: 'change' })\r\n },\r\n {\r\n maxSize: 100,\r\n wait: 100,\r\n onError: (error, batch) => {\r\n logger.error('Failed to send update batch:', error, batch)\r\n },\r\n asyncRetryerOptions: {\r\n maxAttempts: 3,\r\n backoff: 'exponential',\r\n baseWait: 1000,\r\n jitter: 0.3,\r\n },\r\n },\r\n )\r\n\r\n if (args.autoRestart) {\r\n watcher.on('change', async (event, _) => {\r\n batcher.addItem(event)\r\n })\r\n }\r\n else {\r\n watcher.close()\r\n }\r\n\r\n electronProcess.on('exit', onExit)\r\n }\r\n else {\r\n watcher.close()\r\n }\r\n }\r\n catch (error) {\r\n logger.error('Build failed:', error)\r\n throw error\r\n }\r\n },\r\n})\r\n","#!/usr/bin/env node\r\nimport { defineCommand, runMain } from 'citty'\r\nimport { runBuild } from './commands/build'\r\nimport { runDev } from './commands/dev'\r\n\r\nconst main = defineCommand({\r\n meta: {\r\n name: 'holix',\r\n version: '0.1.0',\r\n description: 'Holix Application Framework CLI - Build desktop apps with Vue SSR + Electron',\r\n },\r\n args: {\r\n clear: {\r\n type: 'boolean',\r\n description: 'clear output directory before build',\r\n default: true,\r\n },\r\n },\r\n subCommands: {\r\n dev: runDev,\r\n build: runBuild,\r\n },\r\n})\r\n\r\nrunMain(main)\r\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@holix/cli",
3
3
  "type": "module",
4
- "version": "1.0.4",
4
+ "version": "1.0.5",
5
5
  "private": false,
6
6
  "description": "Holix Application Framework CLI",
7
7
  "author": "zhaogongchengsi <zzhanya648@gmail.com>",
@@ -58,7 +58,7 @@
58
58
  "pkg-types": "^1.3.1",
59
59
  "semver": "^7.7.3",
60
60
  "@holix/builder": "1.0.2",
61
- "@holix/electron": "1.0.1",
61
+ "@holix/electron": "1.0.2",
62
62
  "@holix/config": "1.0.0"
63
63
  },
64
64
  "devDependencies": {