@holix/cli 0.1.0 → 0.2.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/config/index.cjs +1 -1
- package/dist/config/index.d.cts +2 -21
- package/dist/config/index.d.cts.map +1 -1
- package/dist/config/index.d.mts +2 -21
- package/dist/config/index.d.mts.map +1 -1
- package/dist/config/index.mjs +1 -1
- package/dist/{config-DF41qZ52.mjs → config-BMXlLU4W.mjs} +7 -8
- package/dist/config-BMXlLU4W.mjs.map +1 -0
- package/dist/{config-BrQgiHmo.cjs → config-DiolnOet.cjs} +6 -7
- package/dist/index.cjs +61 -30
- package/dist/index.mjs +61 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/dist/config-DF41qZ52.mjs.map +0 -1
package/dist/config/index.cjs
CHANGED
package/dist/config/index.d.cts
CHANGED
|
@@ -1,25 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HolixConfig } from "@holix/config";
|
|
2
2
|
import * as pkg_types0 from "pkg-types";
|
|
3
3
|
|
|
4
|
-
//#region ../config/dist/index.d.mts
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Holix 配置 Schema
|
|
8
|
-
* 使用 Zod 定义的类型安全配置结构
|
|
9
|
-
*/
|
|
10
|
-
declare const holixConfigSchema: any;
|
|
11
|
-
/**
|
|
12
|
-
* 导出配置 Schema
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Holix 配置类型(从 Schema 推断)
|
|
17
|
-
*/
|
|
18
|
-
type HolixConfig = z.infer<typeof holixConfigSchema>;
|
|
19
|
-
/**
|
|
20
|
-
* 应用配置类型
|
|
21
|
-
*/
|
|
22
|
-
//#endregion
|
|
23
4
|
//#region src/config/loader.d.ts
|
|
24
5
|
interface LoadHolixOptions {
|
|
25
6
|
cwd?: string;
|
|
@@ -27,7 +8,7 @@ interface LoadHolixOptions {
|
|
|
27
8
|
declare function loadHolixConfig({
|
|
28
9
|
cwd
|
|
29
10
|
}?: LoadHolixOptions): Promise<{
|
|
30
|
-
config:
|
|
11
|
+
config: HolixConfig;
|
|
31
12
|
configFile: string | undefined;
|
|
32
13
|
packageJson: pkg_types0.PackageJson;
|
|
33
14
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/config/loader.ts","../../src/config/index.ts"],"sourcesContent":[],"mappings":";;;;UAsBiB,gBAAA;;;AAAA,iBAIK,eAAA,CAJW;EAAA;AAAA,CAAA,CAAA,EAM9B,gBAN8B,CAAA,EAQhC,OARgC,CAAA;EAIX,MAAA,EA0Ce,WA1CA;EACnC,UAAA,EAAA,MAAA,GAAA,SAAA;EACC,WAAA,EAwC6C,UAAA,CAAA,WAxC7C;CAwCkC,CAAA;;;;;AA9CrC;AAIA;;;;;;;;;;ACPA;;iBAAgB,iBAAA,SAA0B,cAAc"}
|
package/dist/config/index.d.mts
CHANGED
|
@@ -1,25 +1,6 @@
|
|
|
1
|
+
import { HolixConfig } from "@holix/config";
|
|
1
2
|
import * as pkg_types0 from "pkg-types";
|
|
2
|
-
import { z } from "zod";
|
|
3
3
|
|
|
4
|
-
//#region ../config/dist/index.d.mts
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Holix 配置 Schema
|
|
8
|
-
* 使用 Zod 定义的类型安全配置结构
|
|
9
|
-
*/
|
|
10
|
-
declare const holixConfigSchema: any;
|
|
11
|
-
/**
|
|
12
|
-
* 导出配置 Schema
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Holix 配置类型(从 Schema 推断)
|
|
17
|
-
*/
|
|
18
|
-
type HolixConfig = z.infer<typeof holixConfigSchema>;
|
|
19
|
-
/**
|
|
20
|
-
* 应用配置类型
|
|
21
|
-
*/
|
|
22
|
-
//#endregion
|
|
23
4
|
//#region src/config/loader.d.ts
|
|
24
5
|
interface LoadHolixOptions {
|
|
25
6
|
cwd?: string;
|
|
@@ -27,7 +8,7 @@ interface LoadHolixOptions {
|
|
|
27
8
|
declare function loadHolixConfig({
|
|
28
9
|
cwd
|
|
29
10
|
}?: LoadHolixOptions): Promise<{
|
|
30
|
-
config:
|
|
11
|
+
config: HolixConfig;
|
|
31
12
|
configFile: string | undefined;
|
|
32
13
|
packageJson: pkg_types0.PackageJson;
|
|
33
14
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/config/loader.ts","../../src/config/index.ts"],"sourcesContent":[],"mappings":";;;;UAsBiB,gBAAA;;;AAAA,iBAIK,eAAA,CAJW;EAAA;AAAA,CAAA,CAAA,EAM9B,gBAN8B,CAAA,EAQhC,OARgC,CAAA;EAIX,MAAA,EA0Ce,WA1CA;EACnC,UAAA,EAAA,MAAA,GAAA,SAAA;EACC,WAAA,EAwC6C,UAAA,CAAA,WAxC7C;CAwCkC,CAAA;;;;;AA9CrC;AAIA;;;;;;;;;;ACPA;;iBAAgB,iBAAA,SAA0B,cAAc"}
|
package/dist/config/index.mjs
CHANGED
|
@@ -21,11 +21,7 @@ async function loadHolixConfig({ cwd = process.cwd() } = { cwd: process.cwd() })
|
|
|
21
21
|
const { config, configFile } = await loadConfig({
|
|
22
22
|
name: "holix",
|
|
23
23
|
cwd,
|
|
24
|
-
defaultConfig:
|
|
25
|
-
outDir: defaultHolixConfig.outDir,
|
|
26
|
-
preload: defaultHolixConfig.preload,
|
|
27
|
-
plugins: defaultHolixConfig.plugins
|
|
28
|
-
}
|
|
24
|
+
defaultConfig: defaultHolixConfig
|
|
29
25
|
});
|
|
30
26
|
if (config.app && !config.app.id && packageJson.name) config.app.id = normalizePackageName(packageJson.name);
|
|
31
27
|
const validationResult = validateConfig({
|
|
@@ -33,8 +29,11 @@ async function loadHolixConfig({ cwd = process.cwd() } = { cwd: process.cwd() })
|
|
|
33
29
|
directories: config.directories,
|
|
34
30
|
outDir: config.outDir ?? defaultHolixConfig.outDir,
|
|
35
31
|
preload: config.preload ?? defaultHolixConfig.preload,
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
publicDir: config.publicDir ?? defaultHolixConfig.publicDir,
|
|
33
|
+
alias: config.alias ?? defaultHolixConfig.alias,
|
|
34
|
+
port: config.port ?? defaultHolixConfig.port,
|
|
35
|
+
rolldownPlugins: config.rolldownPlugins ?? defaultHolixConfig.rolldownPlugins,
|
|
36
|
+
vitePlugins: config.vitePlugins ?? defaultHolixConfig.vitePlugins
|
|
38
37
|
});
|
|
39
38
|
if (!validationResult.success) {
|
|
40
39
|
const errorMessages = validationResult.error.issues.map((issue) => ` - ${issue.path.join(".")}: ${issue.message}`).join("\n");
|
|
@@ -70,4 +69,4 @@ function defineHolixConfig(config) {
|
|
|
70
69
|
|
|
71
70
|
//#endregion
|
|
72
71
|
export { loadHolixConfig as n, defineHolixConfig as t };
|
|
73
|
-
//# sourceMappingURL=config-
|
|
72
|
+
//# sourceMappingURL=config-BMXlLU4W.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-BMXlLU4W.mjs","names":[],"sources":["../src/config/loader.ts","../src/config/index.ts"],"sourcesContent":["import type { HolixConfig } from '@holix/config'\r\nimport process from 'node:process'\r\nimport { defaultHolixConfig, validateConfig } from '@holix/config'\r\nimport { loadConfig } from 'c12'\r\nimport { readPackageJSON } from 'pkg-types'\r\n\r\n/**\r\n * 规范化包名为 appID 格式\r\n * 将 @scope/name 转换为 scope.name\r\n *\r\n * @example\r\n * normalizePackageName('@holix/core') // 'holix.core'\r\n * normalizePackageName('my-app') // 'my-app'\r\n */\r\nfunction normalizePackageName(name: string): string {\r\n if (name.startsWith('@')) {\r\n // 移除 @ 符号并将 / 替换为 .\r\n return name.slice(1).replace('/', '.')\r\n }\r\n return name\r\n}\r\n\r\nexport interface LoadHolixOptions {\r\n cwd?: string\r\n}\r\n\r\nexport async function loadHolixConfig({\r\n cwd = process.cwd(),\r\n}: LoadHolixOptions = {\r\n cwd: process.cwd(),\r\n}) {\r\n const packageJson = await readPackageJSON(cwd)\r\n\r\n const { config, configFile } = await loadConfig<HolixConfig>({\r\n name: 'holix',\r\n cwd,\r\n defaultConfig: defaultHolixConfig,\r\n })\r\n\r\n // 如果用户配置了 app,但没有设置 id,使用 package.json 的 name\r\n if (config.app && !config.app.id && packageJson.name) {\r\n config.app.id = normalizePackageName(packageJson.name)\r\n }\r\n\r\n // 使用 mergeConfig 合并默认值和用户配置\r\n // 只合并用户未设置的字段\r\n const mergedConfig: HolixConfig = {\r\n app: config.app,\r\n directories: config.directories,\r\n outDir: config.outDir ?? defaultHolixConfig.outDir,\r\n preload: config.preload ?? defaultHolixConfig.preload,\r\n publicDir: config.publicDir ?? defaultHolixConfig.publicDir,\r\n alias: config.alias ?? defaultHolixConfig.alias,\r\n port: config.port ?? defaultHolixConfig.port,\r\n rolldownPlugins: config.rolldownPlugins ?? defaultHolixConfig.rolldownPlugins,\r\n vitePlugins: config.vitePlugins ?? defaultHolixConfig.vitePlugins,\r\n }\r\n\r\n // 验证配置\r\n const validationResult = validateConfig(mergedConfig)\r\n if (!validationResult.success) {\r\n const errorMessages = validationResult.error.issues.map((issue: any) =>\r\n ` - ${issue.path.join('.')}: ${issue.message}`,\r\n ).join('\\n')\r\n throw new Error(`Invalid Holix configuration:\\n${errorMessages}`)\r\n }\r\n\r\n return {\r\n config: validationResult.data as HolixConfig,\r\n configFile,\r\n packageJson, // 返回 packageJson 供 builder 使用\r\n }\r\n}\r\n","import type { HolixConfig } from '@holix/config'\r\n\r\nexport * from './loader'\r\n\r\n/**\r\n * 类型辅助:用于 holix.config.ts\r\n * 提供类型提示和自动完成\r\n *\r\n * @example\r\n * ```ts\r\n * // holix.config.ts\r\n * import { defineHolixConfig } from '@holix/cli/config'\r\n *\r\n * export default defineHolixConfig({\r\n * entry: 'src/index.tsx',\r\n * outDir: 'dist'\r\n * })\r\n * ```\r\n */\r\nexport function defineHolixConfig(config: HolixConfig): HolixConfig {\r\n return config\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAS,qBAAqB,MAAsB;AAClD,KAAI,KAAK,WAAW,IAAI,CAEtB,QAAO,KAAK,MAAM,EAAE,CAAC,QAAQ,KAAK,IAAI;AAExC,QAAO;;AAOT,eAAsB,gBAAgB,EACpC,MAAM,QAAQ,KAAK,KACC,EACpB,KAAK,QAAQ,KAAK,EACnB,EAAE;CACD,MAAM,cAAc,MAAM,gBAAgB,IAAI;CAE9C,MAAM,EAAE,QAAQ,eAAe,MAAM,WAAwB;EAC3D,MAAM;EACN;EACA,eAAe;EAChB,CAAC;AAGF,KAAI,OAAO,OAAO,CAAC,OAAO,IAAI,MAAM,YAAY,KAC9C,QAAO,IAAI,KAAK,qBAAqB,YAAY,KAAK;CAkBxD,MAAM,mBAAmB,eAbS;EAChC,KAAK,OAAO;EACZ,aAAa,OAAO;EACpB,QAAQ,OAAO,UAAU,mBAAmB;EAC5C,SAAS,OAAO,WAAW,mBAAmB;EAC9C,WAAW,OAAO,aAAa,mBAAmB;EAClD,OAAO,OAAO,SAAS,mBAAmB;EAC1C,MAAM,OAAO,QAAQ,mBAAmB;EACxC,iBAAiB,OAAO,mBAAmB,mBAAmB;EAC9D,aAAa,OAAO,eAAe,mBAAmB;EACvD,CAGoD;AACrD,KAAI,CAAC,iBAAiB,SAAS;EAC7B,MAAM,gBAAgB,iBAAiB,MAAM,OAAO,KAAK,UACvD,OAAO,MAAM,KAAK,KAAK,IAAI,CAAC,IAAI,MAAM,UACvC,CAAC,KAAK,KAAK;AACZ,QAAM,IAAI,MAAM,iCAAiC,gBAAgB;;AAGnE,QAAO;EACL,QAAQ,iBAAiB;EACzB;EACA;EACD;;;;;;;;;;;;;;;;;;;;ACpDH,SAAgB,kBAAkB,QAAkC;AAClE,QAAO"}
|
|
@@ -49,11 +49,7 @@ async function loadHolixConfig({ cwd = node_process.default.cwd() } = { cwd: nod
|
|
|
49
49
|
const { config, configFile } = await (0, c12.loadConfig)({
|
|
50
50
|
name: "holix",
|
|
51
51
|
cwd,
|
|
52
|
-
defaultConfig:
|
|
53
|
-
outDir: __holix_config.defaultHolixConfig.outDir,
|
|
54
|
-
preload: __holix_config.defaultHolixConfig.preload,
|
|
55
|
-
plugins: __holix_config.defaultHolixConfig.plugins
|
|
56
|
-
}
|
|
52
|
+
defaultConfig: __holix_config.defaultHolixConfig
|
|
57
53
|
});
|
|
58
54
|
if (config.app && !config.app.id && packageJson.name) config.app.id = normalizePackageName(packageJson.name);
|
|
59
55
|
const validationResult = (0, __holix_config.validateConfig)({
|
|
@@ -61,8 +57,11 @@ async function loadHolixConfig({ cwd = node_process.default.cwd() } = { cwd: nod
|
|
|
61
57
|
directories: config.directories,
|
|
62
58
|
outDir: config.outDir ?? __holix_config.defaultHolixConfig.outDir,
|
|
63
59
|
preload: config.preload ?? __holix_config.defaultHolixConfig.preload,
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
publicDir: config.publicDir ?? __holix_config.defaultHolixConfig.publicDir,
|
|
61
|
+
alias: config.alias ?? __holix_config.defaultHolixConfig.alias,
|
|
62
|
+
port: config.port ?? __holix_config.defaultHolixConfig.port,
|
|
63
|
+
rolldownPlugins: config.rolldownPlugins ?? __holix_config.defaultHolixConfig.rolldownPlugins,
|
|
64
|
+
vitePlugins: config.vitePlugins ?? __holix_config.defaultHolixConfig.vitePlugins
|
|
66
65
|
});
|
|
67
66
|
if (!validationResult.success) {
|
|
68
67
|
const errorMessages = validationResult.error.issues.map((issue) => ` - ${issue.path.join(".")}: ${issue.message}`).join("\n");
|
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_config = require('./config-
|
|
2
|
+
const require_config = require('./config-DiolnOet.cjs');
|
|
3
3
|
let citty = require("citty");
|
|
4
4
|
let node_process = require("node:process");
|
|
5
5
|
node_process = require_config.__toESM(node_process);
|
|
6
6
|
let __holix_builder = require("@holix/builder");
|
|
7
7
|
let consola = require("consola");
|
|
8
|
+
let node_module = require("node:module");
|
|
8
9
|
let node_path = require("node:path");
|
|
10
|
+
let node_url = require("node:url");
|
|
11
|
+
require("vite");
|
|
9
12
|
let __holix_electron = require("@holix/electron");
|
|
10
13
|
let perfect_debounce = require("perfect-debounce");
|
|
11
|
-
let vite = require("vite");
|
|
12
|
-
let node_module = require("node:module");
|
|
13
14
|
|
|
14
15
|
//#region src/utils/logger.ts
|
|
15
16
|
const logger = consola.consola.withTag("holix");
|
|
@@ -17,6 +18,52 @@ function banner(msg) {
|
|
|
17
18
|
logger.box(msg);
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/vite/resolve.ts
|
|
23
|
+
async function resolveViteFromCwd(cwd) {
|
|
24
|
+
const _require = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
25
|
+
let viteEntry;
|
|
26
|
+
try {
|
|
27
|
+
viteEntry = _require.resolve("vite", { paths: [cwd] });
|
|
28
|
+
} catch {
|
|
29
|
+
throw new Error(`[holix] Cannot find "vite" in project: ${cwd}\nPlease install it first: pnpm add -D vite`);
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return await import((0, node_url.pathToFileURL)(viteEntry).href);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
if (err?.code === "ERR_REQUIRE_ESM" || err?.message?.includes("Cannot use import statement")) return _require(viteEntry);
|
|
35
|
+
throw err;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function resolveViteConfigFromHolixConfig(cwd, holixConfig) {
|
|
39
|
+
const outdir = (0, node_path.join)(holixConfig.outDir || ".holix", "client");
|
|
40
|
+
return {
|
|
41
|
+
root: cwd,
|
|
42
|
+
base: "./",
|
|
43
|
+
plugins: [...holixConfig.vitePlugins || []],
|
|
44
|
+
resolve: { alias: holixConfig.alias || {} },
|
|
45
|
+
build: {
|
|
46
|
+
outDir: outdir,
|
|
47
|
+
rollupOptions: {
|
|
48
|
+
external: ["electron"],
|
|
49
|
+
output: {
|
|
50
|
+
entryFileNames: "[name].js",
|
|
51
|
+
chunkFileNames: "chunks/[name]-[hash].js",
|
|
52
|
+
assetFileNames: "assets/[name]-[hash][extname]"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/vite/build.ts
|
|
61
|
+
async function buildVite(cwd, holixConfig) {
|
|
62
|
+
const vite$1 = await resolveViteFromCwd(cwd);
|
|
63
|
+
const serverConfig = await resolveViteConfigFromHolixConfig(cwd, holixConfig);
|
|
64
|
+
return vite$1.build(serverConfig);
|
|
65
|
+
}
|
|
66
|
+
|
|
20
67
|
//#endregion
|
|
21
68
|
//#region src/commands/build.ts
|
|
22
69
|
const runBuild = (0, citty.defineCommand)({
|
|
@@ -38,6 +85,7 @@ const runBuild = (0, citty.defineCommand)({
|
|
|
38
85
|
try {
|
|
39
86
|
const { config, packageJson } = await require_config.loadHolixConfig({ cwd: rootDir });
|
|
40
87
|
logger.info("Building client and main processes...");
|
|
88
|
+
await buildVite(rootDir, config);
|
|
41
89
|
await (0, __holix_builder.build)(config, packageJson, { clean: args.clear });
|
|
42
90
|
logger.success("All builds completed successfully");
|
|
43
91
|
} catch (error) {
|
|
@@ -48,8 +96,7 @@ const runBuild = (0, citty.defineCommand)({
|
|
|
48
96
|
});
|
|
49
97
|
|
|
50
98
|
//#endregion
|
|
51
|
-
//#region src/
|
|
52
|
-
const _require = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
99
|
+
//#region src/vite/server.ts
|
|
53
100
|
/**
|
|
54
101
|
* 创建 Vite 开发服务器(不立即启动)
|
|
55
102
|
*
|
|
@@ -68,23 +115,10 @@ const _require = (0, node_module.createRequire)(require("url").pathToFileURL(__f
|
|
|
68
115
|
* server.printUrls()
|
|
69
116
|
* ```
|
|
70
117
|
*/
|
|
71
|
-
async function createViteDevServer(
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
vite$1 = await import(_require.resolve("vite", { paths: [cwd, (0, node_path.resolve)(cwd, "node_modules")] }));
|
|
76
|
-
} catch {
|
|
77
|
-
console.warn("Vite not found in project dependencies, using built-in version");
|
|
78
|
-
vite$1 = await import("vite");
|
|
79
|
-
}
|
|
80
|
-
const serverConfig = {
|
|
81
|
-
...config,
|
|
82
|
-
root: config.root || cwd
|
|
83
|
-
};
|
|
84
|
-
return vite$1.createServer({
|
|
85
|
-
...serverConfig,
|
|
86
|
-
configFile: false
|
|
87
|
-
});
|
|
118
|
+
async function createViteDevServer(cwd, holixConfig) {
|
|
119
|
+
const vite$1 = await resolveViteFromCwd(cwd);
|
|
120
|
+
const serverConfig = await resolveViteConfigFromHolixConfig(cwd, holixConfig);
|
|
121
|
+
return vite$1.createServer(serverConfig);
|
|
88
122
|
}
|
|
89
123
|
|
|
90
124
|
//#endregion
|
|
@@ -114,12 +148,8 @@ const runDev = (0, citty.defineCommand)({
|
|
|
114
148
|
if (args.clear) logger.info("Clear output:", "enabled");
|
|
115
149
|
try {
|
|
116
150
|
const { config, packageJson } = await require_config.loadHolixConfig({ cwd: rootDir });
|
|
117
|
-
const viteServer = await createViteDevServer(
|
|
118
|
-
|
|
119
|
-
base: "./",
|
|
120
|
-
resolve: { alias: config?.alias || {} }
|
|
121
|
-
}));
|
|
122
|
-
const port = config.vite?.server?.port ?? config.port ?? 5183;
|
|
151
|
+
const viteServer = await createViteDevServer(rootDir, config);
|
|
152
|
+
const port = config.port ?? 5183;
|
|
123
153
|
await viteServer.listen(port);
|
|
124
154
|
viteServer.printUrls();
|
|
125
155
|
logger.info("Building client and main processes...");
|
|
@@ -138,12 +168,13 @@ const runDev = (0, citty.defineCommand)({
|
|
|
138
168
|
cwd: rootDir,
|
|
139
169
|
env: { NODE_ENV: "development" }
|
|
140
170
|
});
|
|
171
|
+
logger.success("Electron started");
|
|
141
172
|
let isRestarting = false;
|
|
142
|
-
const onExit = (code) => {
|
|
173
|
+
const onExit = (0, perfect_debounce.debounce)((code) => {
|
|
143
174
|
logger.info("Electron process exited with code", code);
|
|
144
175
|
watcher.close();
|
|
145
176
|
node_process.default.exit(code ?? 0);
|
|
146
|
-
};
|
|
177
|
+
}, 100);
|
|
147
178
|
const restart = (0, perfect_debounce.debounce)(async () => {
|
|
148
179
|
logger.info("Changes detected. Restarting Electron...");
|
|
149
180
|
if (isRestarting) return;
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as loadHolixConfig } from "./config-
|
|
2
|
+
import { n as loadHolixConfig } from "./config-BMXlLU4W.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { defineCommand, runMain } from "citty";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
import { build, dev } from "@holix/builder";
|
|
7
7
|
import { consola } from "consola";
|
|
8
|
-
import { resolve } from "node:path";
|
|
8
|
+
import { join, resolve } from "node:path";
|
|
9
|
+
import { pathToFileURL } from "node:url";
|
|
10
|
+
import "vite";
|
|
9
11
|
import { startElectron } from "@holix/electron";
|
|
10
12
|
import { debounce } from "perfect-debounce";
|
|
11
|
-
import { mergeConfig } from "vite";
|
|
12
13
|
|
|
13
14
|
//#region src/utils/logger.ts
|
|
14
15
|
const logger = consola.withTag("holix");
|
|
@@ -16,6 +17,52 @@ function banner(msg) {
|
|
|
16
17
|
logger.box(msg);
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/vite/resolve.ts
|
|
22
|
+
async function resolveViteFromCwd(cwd) {
|
|
23
|
+
const _require = createRequire(import.meta.url);
|
|
24
|
+
let viteEntry;
|
|
25
|
+
try {
|
|
26
|
+
viteEntry = _require.resolve("vite", { paths: [cwd] });
|
|
27
|
+
} catch {
|
|
28
|
+
throw new Error(`[holix] Cannot find "vite" in project: ${cwd}\nPlease install it first: pnpm add -D vite`);
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
return await import(pathToFileURL(viteEntry).href);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
if (err?.code === "ERR_REQUIRE_ESM" || err?.message?.includes("Cannot use import statement")) return _require(viteEntry);
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function resolveViteConfigFromHolixConfig(cwd, holixConfig) {
|
|
38
|
+
const outdir = join(holixConfig.outDir || ".holix", "client");
|
|
39
|
+
return {
|
|
40
|
+
root: cwd,
|
|
41
|
+
base: "./",
|
|
42
|
+
plugins: [...holixConfig.vitePlugins || []],
|
|
43
|
+
resolve: { alias: holixConfig.alias || {} },
|
|
44
|
+
build: {
|
|
45
|
+
outDir: outdir,
|
|
46
|
+
rollupOptions: {
|
|
47
|
+
external: ["electron"],
|
|
48
|
+
output: {
|
|
49
|
+
entryFileNames: "[name].js",
|
|
50
|
+
chunkFileNames: "chunks/[name]-[hash].js",
|
|
51
|
+
assetFileNames: "assets/[name]-[hash][extname]"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/vite/build.ts
|
|
60
|
+
async function buildVite(cwd, holixConfig) {
|
|
61
|
+
const vite = await resolveViteFromCwd(cwd);
|
|
62
|
+
const serverConfig = await resolveViteConfigFromHolixConfig(cwd, holixConfig);
|
|
63
|
+
return vite.build(serverConfig);
|
|
64
|
+
}
|
|
65
|
+
|
|
19
66
|
//#endregion
|
|
20
67
|
//#region src/commands/build.ts
|
|
21
68
|
const runBuild = defineCommand({
|
|
@@ -37,6 +84,7 @@ const runBuild = defineCommand({
|
|
|
37
84
|
try {
|
|
38
85
|
const { config, packageJson } = await loadHolixConfig({ cwd: rootDir });
|
|
39
86
|
logger.info("Building client and main processes...");
|
|
87
|
+
await buildVite(rootDir, config);
|
|
40
88
|
await build(config, packageJson, { clean: args.clear });
|
|
41
89
|
logger.success("All builds completed successfully");
|
|
42
90
|
} catch (error) {
|
|
@@ -47,8 +95,7 @@ const runBuild = defineCommand({
|
|
|
47
95
|
});
|
|
48
96
|
|
|
49
97
|
//#endregion
|
|
50
|
-
//#region src/
|
|
51
|
-
const _require = createRequire(import.meta.url);
|
|
98
|
+
//#region src/vite/server.ts
|
|
52
99
|
/**
|
|
53
100
|
* 创建 Vite 开发服务器(不立即启动)
|
|
54
101
|
*
|
|
@@ -67,23 +114,10 @@ const _require = createRequire(import.meta.url);
|
|
|
67
114
|
* server.printUrls()
|
|
68
115
|
* ```
|
|
69
116
|
*/
|
|
70
|
-
async function createViteDevServer(
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
vite = await import(_require.resolve("vite", { paths: [cwd, resolve(cwd, "node_modules")] }));
|
|
75
|
-
} catch {
|
|
76
|
-
console.warn("Vite not found in project dependencies, using built-in version");
|
|
77
|
-
vite = await import("vite");
|
|
78
|
-
}
|
|
79
|
-
const serverConfig = {
|
|
80
|
-
...config,
|
|
81
|
-
root: config.root || cwd
|
|
82
|
-
};
|
|
83
|
-
return vite.createServer({
|
|
84
|
-
...serverConfig,
|
|
85
|
-
configFile: false
|
|
86
|
-
});
|
|
117
|
+
async function createViteDevServer(cwd, holixConfig) {
|
|
118
|
+
const vite = await resolveViteFromCwd(cwd);
|
|
119
|
+
const serverConfig = await resolveViteConfigFromHolixConfig(cwd, holixConfig);
|
|
120
|
+
return vite.createServer(serverConfig);
|
|
87
121
|
}
|
|
88
122
|
|
|
89
123
|
//#endregion
|
|
@@ -113,12 +147,8 @@ const runDev = defineCommand({
|
|
|
113
147
|
if (args.clear) logger.info("Clear output:", "enabled");
|
|
114
148
|
try {
|
|
115
149
|
const { config, packageJson } = await loadHolixConfig({ cwd: rootDir });
|
|
116
|
-
const viteServer = await createViteDevServer(
|
|
117
|
-
|
|
118
|
-
base: "./",
|
|
119
|
-
resolve: { alias: config?.alias || {} }
|
|
120
|
-
}));
|
|
121
|
-
const port = config.vite?.server?.port ?? config.port ?? 5183;
|
|
150
|
+
const viteServer = await createViteDevServer(rootDir, config);
|
|
151
|
+
const port = config.port ?? 5183;
|
|
122
152
|
await viteServer.listen(port);
|
|
123
153
|
viteServer.printUrls();
|
|
124
154
|
logger.info("Building client and main processes...");
|
|
@@ -137,12 +167,13 @@ const runDev = defineCommand({
|
|
|
137
167
|
cwd: rootDir,
|
|
138
168
|
env: { NODE_ENV: "development" }
|
|
139
169
|
});
|
|
170
|
+
logger.success("Electron started");
|
|
140
171
|
let isRestarting = false;
|
|
141
|
-
const onExit = (code) => {
|
|
172
|
+
const onExit = debounce((code) => {
|
|
142
173
|
logger.info("Electron process exited with code", code);
|
|
143
174
|
watcher.close();
|
|
144
175
|
process.exit(code ?? 0);
|
|
145
|
-
};
|
|
176
|
+
}, 100);
|
|
146
177
|
const restart = debounce(async () => {
|
|
147
178
|
logger.info("Changes detected. Restarting Electron...");
|
|
148
179
|
if (isRestarting) return;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["vite: typeof import('vite')","serverConfig: ViteConfig"],"sources":["../src/utils/logger.ts","../src/commands/build.ts","../src/utils/vite.ts","../src/commands/dev.ts","../src/index.ts"],"sourcesContent":["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 process from 'node:process'\r\nimport { build } from '@holix/builder'\r\nimport { defineCommand } from 'citty'\r\nimport { loadHolixConfig } from '../config'\r\nimport { banner, logger } from '../utils/logger'\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 },\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 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 build(config, packageJson, { clean: args.clear })\r\n\r\n logger.success('All builds completed successfully')\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 { UserConfig as ViteConfig, ViteDevServer } from 'vite'\r\nimport { createRequire } from 'node:module'\r\nimport { resolve } from 'node:path'\r\nimport process from 'node:process'\r\n\r\nconst _require = createRequire(import.meta.url)\r\n\r\n/**\r\n * Vite 开发服务器选项\r\n */\r\nexport interface ViteDevServerOptions {\r\n /**\r\n * 工作目录\r\n * @default process.cwd()\r\n */\r\n cwd?: string\r\n\r\n /**\r\n * Vite 配置\r\n */\r\n config?: ViteConfig\r\n\r\n /**\r\n * 服务器端口\r\n * @default 5173\r\n */\r\n port?: number\r\n}\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(\r\n options: ViteDevServerOptions = {},\r\n): Promise<ViteDevServer> {\r\n const {\r\n cwd = process.cwd(),\r\n config = {},\r\n } = options\r\n\r\n // 从用户项目的 node_modules 中解析 Vite\r\n let vite: typeof import('vite')\r\n\r\n try {\r\n const vitePath = _require.resolve('vite', {\r\n paths: [cwd, resolve(cwd, 'node_modules')],\r\n })\r\n vite = await import(vitePath)\r\n }\r\n catch {\r\n console.warn('Vite not found in project dependencies, using built-in version')\r\n vite = await import('vite')\r\n }\r\n\r\n // 创建 Vite 服务器配置\r\n const serverConfig: ViteConfig = {\r\n ...config,\r\n root: config.root || cwd,\r\n }\r\n\r\n // 创建开发服务器(不启动)\r\n return vite.createServer({\r\n ...serverConfig,\r\n configFile: false,\r\n })\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 { defineCommand } from 'citty'\r\nimport { debounce } from 'perfect-debounce'\r\nimport { mergeConfig } from 'vite'\r\nimport { loadHolixConfig } from '../config'\r\nimport { banner, logger } from '../utils/logger'\r\nimport { createViteDevServer } from '../utils/vite'\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 },\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(mergeConfig(config.vite, {\r\n root: rootDir,\r\n base: './',\r\n resolve: {\r\n alias: config?.alias || { },\r\n },\r\n }))\r\n\r\n const port = config.vite?.server?.port ?? config.port ?? 5183\r\n\r\n await viteServer.listen(port)\r\n\r\n viteServer.printUrls()\r\n\r\n logger.info('Building client and main processes...')\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 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 })\r\n\r\n let isRestarting = false\r\n\r\n const onExit = (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 }\r\n\r\n const restart = debounce(async () => {\r\n logger.info('Changes detected. Restarting Electron...')\r\n if (isRestarting) {\r\n return\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 })\r\n\r\n watcher.on('change', async (event, change) => {\r\n logger.info(`File ${change.event} detected: ${event}`)\r\n restart()\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"],"sources":["../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 { 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 process from 'node:process'\r\nimport { build } from '@holix/builder'\r\nimport { defineCommand } from 'citty'\r\nimport { loadHolixConfig } from '../config'\r\nimport { banner, logger } from '../utils/logger'\r\nimport { buildVite } from '../vite/build'\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 },\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 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 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 { 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 },\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 viteServer.printUrls()\r\n\r\n logger.info('Building client and main processes...')\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 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 })\r\n\r\n logger.success('Electron started')\r\n\r\n let isRestarting = false\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 const restart = debounce(async () => {\r\n logger.info('Changes detected. Restarting Electron...')\r\n if (isRestarting) {\r\n return\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 })\r\n\r\n watcher.on('change', async (event, change) => {\r\n logger.info(`File ${change.event} detected: ${event}`)\r\n restart()\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": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Holix Application Framework CLI",
|
|
7
7
|
"author": "zhaogongchengsi <zzhanya648@gmail.com>",
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
"exports": {
|
|
26
26
|
".": {
|
|
27
27
|
"types": "./dist/index.d.ts",
|
|
28
|
-
"import": "./dist/index.
|
|
28
|
+
"import": "./dist/index.mjs",
|
|
29
29
|
"require": "./dist/index.cjs"
|
|
30
30
|
},
|
|
31
31
|
"./config": {
|
|
32
32
|
"types": "./dist/config/index.d.ts",
|
|
33
|
-
"import": "./dist/config/index.
|
|
33
|
+
"import": "./dist/config/index.mjs",
|
|
34
34
|
"require": "./dist/config/index.cjs"
|
|
35
35
|
}
|
|
36
36
|
},
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"main": "./dist/index.mjs",
|
|
41
41
|
"types": "./dist/index.d.ts",
|
|
42
42
|
"bin": {
|
|
43
|
-
"holix": "./dist/index.
|
|
43
|
+
"holix": "./dist/index.mjs"
|
|
44
44
|
},
|
|
45
45
|
"files": [
|
|
46
46
|
"dist"
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"pathe": "^2.0.3",
|
|
54
54
|
"perfect-debounce": "^2.0.0",
|
|
55
55
|
"pkg-types": "^1.3.1",
|
|
56
|
-
"@holix/
|
|
57
|
-
"@holix/
|
|
58
|
-
"@holix/electron": "0.
|
|
56
|
+
"@holix/config": "0.2.0",
|
|
57
|
+
"@holix/builder": "0.2.0",
|
|
58
|
+
"@holix/electron": "0.2.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@types/node": "^24.9.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config-DF41qZ52.mjs","names":[],"sources":["../src/config/loader.ts","../src/config/index.ts"],"sourcesContent":["import type { HolixConfig } from '@holix/config'\r\nimport type { UserConfig as ViteUserConfig } from 'vite'\r\nimport process from 'node:process'\r\nimport { defaultHolixConfig, validateConfig } from '@holix/config'\r\nimport { loadConfig } from 'c12'\r\nimport { readPackageJSON } from 'pkg-types'\r\n\r\n/**\r\n * 规范化包名为 appID 格式\r\n * 将 @scope/name 转换为 scope.name\r\n *\r\n * @example\r\n * normalizePackageName('@holix/core') // 'holix.core'\r\n * normalizePackageName('my-app') // 'my-app'\r\n */\r\nfunction normalizePackageName(name: string): string {\r\n if (name.startsWith('@')) {\r\n // 移除 @ 符号并将 / 替换为 .\r\n return name.slice(1).replace('/', '.')\r\n }\r\n return name\r\n}\r\n\r\nexport interface LoadHolixOptions {\r\n cwd?: string\r\n}\r\n\r\nexport async function loadHolixConfig({\r\n cwd = process.cwd(),\r\n}: LoadHolixOptions = {\r\n cwd: process.cwd(),\r\n}) {\r\n const packageJson = await readPackageJSON(cwd)\r\n\r\n const { config, configFile } = await loadConfig<HolixConfig>({\r\n name: 'holix',\r\n cwd,\r\n defaultConfig: {\r\n outDir: defaultHolixConfig.outDir,\r\n preload: defaultHolixConfig.preload,\r\n plugins: defaultHolixConfig.plugins,\r\n // 不设置 app 和 directories 的默认值,让用户配置决定\r\n },\r\n })\r\n\r\n // 如果用户配置了 app,但没有设置 id,使用 package.json 的 name\r\n if (config.app && !config.app.id && packageJson.name) {\r\n config.app.id = normalizePackageName(packageJson.name)\r\n }\r\n\r\n // 使用 mergeConfig 合并默认值和用户配置\r\n // 只合并用户未设置的字段\r\n const mergedConfig: HolixConfig = {\r\n app: config.app,\r\n directories: config.directories,\r\n outDir: config.outDir ?? defaultHolixConfig.outDir,\r\n preload: config.preload ?? defaultHolixConfig.preload,\r\n plugins: config.plugins ?? defaultHolixConfig.plugins,\r\n vite: config.vite ?? defaultHolixConfig.vite,\r\n }\r\n\r\n // 验证配置\r\n const validationResult = validateConfig(mergedConfig)\r\n if (!validationResult.success) {\r\n const errorMessages = validationResult.error.issues.map((issue: any) =>\r\n ` - ${issue.path.join('.')}: ${issue.message}`,\r\n ).join('\\n')\r\n throw new Error(`Invalid Holix configuration:\\n${errorMessages}`)\r\n }\r\n\r\n return {\r\n config: validationResult.data,\r\n configFile,\r\n packageJson, // 返回 packageJson 供 builder 使用\r\n }\r\n}\r\n","import type { HolixConfig } from '@holix/config'\r\n\r\nexport * from './loader'\r\n\r\n/**\r\n * 类型辅助:用于 holix.config.ts\r\n * 提供类型提示和自动完成\r\n *\r\n * @example\r\n * ```ts\r\n * // holix.config.ts\r\n * import { defineHolixConfig } from '@holix/cli/config'\r\n *\r\n * export default defineHolixConfig({\r\n * entry: 'src/index.tsx',\r\n * outDir: 'dist'\r\n * })\r\n * ```\r\n */\r\nexport function defineHolixConfig(config: HolixConfig): HolixConfig {\r\n return config\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;AAeA,SAAS,qBAAqB,MAAsB;AAClD,KAAI,KAAK,WAAW,IAAI,CAEtB,QAAO,KAAK,MAAM,EAAE,CAAC,QAAQ,KAAK,IAAI;AAExC,QAAO;;AAOT,eAAsB,gBAAgB,EACpC,MAAM,QAAQ,KAAK,KACC,EACpB,KAAK,QAAQ,KAAK,EACnB,EAAE;CACD,MAAM,cAAc,MAAM,gBAAgB,IAAI;CAE9C,MAAM,EAAE,QAAQ,eAAe,MAAM,WAAwB;EAC3D,MAAM;EACN;EACA,eAAe;GACb,QAAQ,mBAAmB;GAC3B,SAAS,mBAAmB;GAC5B,SAAS,mBAAmB;GAE7B;EACF,CAAC;AAGF,KAAI,OAAO,OAAO,CAAC,OAAO,IAAI,MAAM,YAAY,KAC9C,QAAO,IAAI,KAAK,qBAAqB,YAAY,KAAK;CAexD,MAAM,mBAAmB,eAVS;EAChC,KAAK,OAAO;EACZ,aAAa,OAAO;EACpB,QAAQ,OAAO,UAAU,mBAAmB;EAC5C,SAAS,OAAO,WAAW,mBAAmB;EAC9C,SAAS,OAAO,WAAW,mBAAmB;EAC9C,MAAM,OAAO,QAAQ,mBAAmB;EACzC,CAGoD;AACrD,KAAI,CAAC,iBAAiB,SAAS;EAC7B,MAAM,gBAAgB,iBAAiB,MAAM,OAAO,KAAK,UACvD,OAAO,MAAM,KAAK,KAAK,IAAI,CAAC,IAAI,MAAM,UACvC,CAAC,KAAK,KAAK;AACZ,QAAM,IAAI,MAAM,iCAAiC,gBAAgB;;AAGnE,QAAO;EACL,QAAQ,iBAAiB;EACzB;EACA;EACD;;;;;;;;;;;;;;;;;;;;ACvDH,SAAgB,kBAAkB,QAAkC;AAClE,QAAO"}
|