@ikaros-cli/ikaros 2.1.3 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _rspack_core0 from "@rspack/core";
2
2
  import { Configuration, DefinePluginOptions, LightningcssLoaderOptions, Loader, ModuleFederationPluginOptions, Plugin, RuleSetRule, WatchOptions, rspack } from "@rspack/core";
3
3
  import * as _rspack_dev_server0 from "@rspack/dev-server";
4
- import * as https0 from "https";
4
+ import * as https from "https";
5
5
 
6
6
  //#region src/types/env.d.ts
7
7
  interface ImportMetaBaseEnv {
@@ -12,96 +12,21 @@ interface ImportMetaBaseEnv {
12
12
  /** 平台 */
13
13
  PLATFORM: 'web' | 'desktopClient';
14
14
  }
15
- type ImportMetaEnv = Record<string, any>;
15
+ type ImportMetaEnv = Record<string, string | boolean | undefined>;
16
16
  interface ImportMeta {
17
17
  readonly env: Readonly<ImportMetaEnv & ImportMetaBaseEnv>;
18
18
  }
19
19
  //#endregion
20
- //#region src/node/compile/core/base-compile-service.d.ts
21
- type PackageJson = {
22
- name: string;
23
- version: string;
24
- };
25
- /** 命令 */
26
- declare enum Command {
27
- SERVER = "server",
28
- BUILD = "build",
29
- }
30
- /** 命令选项 */
31
- type CompileOptions = {
32
- /** 模式 */
33
- readonly mode?: string;
34
- /** 平台 */
35
- readonly platform: ImportMetaBaseEnv['PLATFORM'];
36
- };
37
- type CompileServeParame = {
38
- command: Command;
39
- options: CompileOptions;
40
- configFile?: string;
41
- onBuildStatus?: (status: {
42
- success: boolean;
43
- port?: number;
44
- message?: string;
45
- }) => void;
46
- };
47
- declare abstract class BaseCompileService {
48
- /** 构建类型 */
49
- readonly command: Command;
50
- /** cli上下文空间 */
51
- readonly context: string;
52
- /** 选项 */
53
- readonly options: CompileOptions;
54
- /** 基于工作目录的Require */
55
- readonly contextRequire: NodeRequire;
56
- private _env;
57
- /** 配置文件 */
58
- readonly configFile?: string;
59
- /** env */
60
- private set env(value);
61
- get env(): ConfigEnvPre["env"];
62
- private _contextPkg?;
63
- /** 用户配置 */
64
- userConfig?: UserConfig;
65
- /** 工作目录的 package.json */
66
- private set contextPkg(value);
67
- get contextPkg(): PackageJson | undefined;
68
- /** 是否为electron环境 */
69
- get isElectron(): boolean;
70
- constructor(parame: CompileServeParame);
71
- static create<T extends BaseCompileService, P extends CompileServeParame>(this: new (params: P) => T, params: P): Promise<T>;
72
- private initialize;
73
- protected onAfterConfigLoaded(): Promise<void>;
74
- /** 基于工作目录的定位 */
75
- protected resolveContext: (...paths: string[]) => string;
76
- private initContextPkg;
77
- private initEnv;
78
- private loadUserConfig;
79
- /** 检索工作目录的模块路径 */
80
- protected resolveContextModule(id: string): string | undefined;
81
- /** 加载模块工作目录的模块 */
82
- protected loadContextModule<T>(id: string): T;
83
- /**
84
- * 获取配置文件
85
- * @param configFile 配置文件路径
86
- */
87
- protected getUserConfig(): Promise<UserConfig | undefined>;
88
- protected startCompile(): Promise<void>;
89
- /** 生命周期抽象方法:dev 启动 */
90
- protected abstract dev(): unknown | Promise<unknown>;
91
- /** 生命周期抽象方法:build 启动 */
92
- protected abstract build(): unknown | Promise<unknown>;
93
- }
94
- //#endregion
95
- //#region src/node/utils/css-loaders-helper.d.ts
20
+ //#region src/node/bundler/rspack/css-loaders-helper.d.ts
96
21
  interface CssLoaderOptions {
97
22
  lightningcss?: LightningcssLoaderOptions;
98
23
  sourceMap?: boolean;
99
- less?: Record<string, any>;
100
- sass?: Record<string, any>;
101
- stylus?: Record<string, any>;
24
+ less?: Record<string, unknown>;
25
+ sass?: Record<string, unknown>;
26
+ stylus?: Record<string, unknown>;
102
27
  }
103
28
  //#endregion
104
- //#region src/node/utils/loader-plugin-helper.d.ts
29
+ //#region src/node/bundler/rspack/loader-plugin-helper.d.ts
105
30
  type ListItemType = RuleSetRule | Plugin;
106
31
  type RspackExperiments = {
107
32
  import: Record<string, unknown>[];
@@ -165,6 +90,130 @@ type Pages = {
165
90
  };
166
91
  };
167
92
  //#endregion
93
+ //#region src/node/bundler/types.d.ts
94
+ interface BuildStatus {
95
+ success: boolean;
96
+ message?: string;
97
+ port?: number;
98
+ /** 预留多目标结构 */
99
+ target?: 'web' | 'renderer' | 'main' | 'preload';
100
+ }
101
+ /**
102
+ * 编译器适配器接口
103
+ *
104
+ * 泛型参数 TConfig 默认为 unknown,core 层按 BundlerAdapter(即 BundlerAdapter<unknown>)对待;
105
+ * adapter 实现内部可指定具体类型以获得强类型约束。
106
+ * 例如:class RspackAdapter implements BundlerAdapter<Configuration> { ... }
107
+ */
108
+ interface BundlerAdapter<TConfig = unknown> {
109
+ /** 编译器标识 */
110
+ readonly name: 'rspack' | 'vite';
111
+ /**
112
+ * 根据编译参数生成编译器配置
113
+ */
114
+ createConfig(params: CreateConfigParams): TConfig | Promise<TConfig>;
115
+ /**
116
+ * 启动开发服务器
117
+ */
118
+ runDev(config: TConfig, options: BundlerDevOptions): Promise<void>;
119
+ /**
120
+ * 执行生产构建
121
+ */
122
+ runBuild(config: TConfig, options: BundlerBuildOptions): Promise<string | undefined>;
123
+ }
124
+ interface CreateConfigParams {
125
+ command: 'server' | 'build';
126
+ mode?: string;
127
+ env: Record<string, unknown>;
128
+ context: string;
129
+ contextPkg?: {
130
+ name: string;
131
+ version: string;
132
+ };
133
+ userConfig?: UserConfig;
134
+ pages: Pages;
135
+ base: string;
136
+ port: number;
137
+ browserslist: string;
138
+ isElectron: boolean;
139
+ isVue: boolean;
140
+ isReact: boolean;
141
+ resolveContext: (...paths: string[]) => string;
142
+ }
143
+ interface BundlerDevOptions {
144
+ port?: number;
145
+ onBuildStatus?: (status: BuildStatus) => void;
146
+ }
147
+ interface BundlerBuildOptions {
148
+ onBuildStatus?: (status: BuildStatus) => void;
149
+ }
150
+ //#endregion
151
+ //#region src/node/compile/compile-context.d.ts
152
+ type PackageJson = {
153
+ name: string;
154
+ version: string;
155
+ };
156
+ /** 命令 */
157
+ declare enum Command {
158
+ SERVER = "server",
159
+ BUILD = "build"
160
+ }
161
+ /** 命令选项 */
162
+ type CompileOptions = {
163
+ /** 模式 */readonly mode?: string; /** 平台 */
164
+ readonly platform: ImportMetaBaseEnv['PLATFORM'];
165
+ };
166
+ type CompileServeParams = {
167
+ command: Command;
168
+ options: CompileOptions;
169
+ configFile?: string; /** 工作目录,默认 process.cwd() */
170
+ context?: string;
171
+ onBuildStatus?: (status: BuildStatus) => void;
172
+ };
173
+ /**
174
+ * 编译上下文
175
+ *
176
+ * 由 createCompileContext() 工厂函数创建,以组合方式提供给 Platform/Bundler 使用。
177
+ */
178
+ interface CompileContext {
179
+ /** 工作目录 */
180
+ readonly context: string;
181
+ /** 命令 */
182
+ readonly command: Command;
183
+ /** CLI 选项 */
184
+ readonly options: CompileOptions;
185
+ /** 环境变量 */
186
+ readonly env: Record<string, unknown>;
187
+ /** 用户配置(可在 resolvePreConfig 阶段被更新) */
188
+ userConfig?: UserConfig;
189
+ /** 工作目录 package.json */
190
+ readonly contextPkg?: PackageJson;
191
+ /** 基于工作目录的路径解析 */
192
+ readonly resolveContext: (...paths: string[]) => string;
193
+ /** 加载工作目录模块 */
194
+ readonly loadContextModule: <T>(id: string) => T;
195
+ /** 检索工作目录模块路径 */
196
+ readonly resolveContextModule: (id: string) => string | undefined;
197
+ /** 基于工作目录的 require(供需要完整 NodeRequire 的场景使用) */
198
+ readonly contextRequire: NodeRequire;
199
+ /** 是否 Electron */
200
+ readonly isElectron: boolean;
201
+ /** 配置文件路径 */
202
+ readonly configFile?: string;
203
+ /** 构建状态回调 */
204
+ onBuildStatus?: (status: BuildStatus) => void;
205
+ }
206
+ /**
207
+ * 创建编译上下文
208
+ *
209
+ * 替代 BaseCompileService 的构造函数 + initialize() 流程:
210
+ * 1. 设置工作目录和选项
211
+ * 2. 加载 package.json
212
+ * 3. 加载环境变量
213
+ * 4. 加载并验证用户配置
214
+ */
215
+ declare function createCompileContext(params: CompileServeParams): Promise<CompileContext>;
216
+ //#endregion
168
217
  //#region src/node/plugins/cdn-plugin.d.ts
169
218
  interface CdnModule {
170
219
  name: string;
@@ -185,7 +234,7 @@ interface CdnPluginOptions {
185
234
  crossOrigin?: boolean | string;
186
235
  }
187
236
  //#endregion
188
- //#region src/node/user-config.d.ts
237
+ //#region src/node/config/user-config.d.ts
189
238
  type Bundler = 'rspack' | 'vite';
190
239
  interface ElectronConfig {
191
240
  main?: {
@@ -315,7 +364,7 @@ interface UserConfig {
315
364
  * @see {@link https://webpack.js.org/configuration/dev-server/#devserverhttps}
316
365
  * @default false
317
366
  */
318
- https?: boolean | https0.ServerOptions;
367
+ https?: boolean | https.ServerOptions;
319
368
  };
320
369
  /**
321
370
  * css loader 配置
@@ -402,16 +451,95 @@ type UserConfigWebExport = UserConfig | Promise<UserConfig> | UserConfigFn<UserC
402
451
  /** 辅助工具函数 */
403
452
  declare const defineConfig: (config: UserConfigWebExport) => UserConfigWebExport;
404
453
  //#endregion
405
- //#region src/node/compile/web/web-compile-service.d.ts
406
- declare class WebCompileService extends BaseCompileService {
407
- private port;
408
- private viteAdapter?;
409
- private onBuildStatus?;
410
- constructor(parame: CompileServeParame);
411
- protected dev(): Promise<void>;
412
- protected build(): Promise<void>;
413
- private prepare;
414
- getDevPort(): number;
454
+ //#region src/node/compile/compile-pipeline.d.ts
455
+ /**
456
+ * 统一编译管线
457
+ *
458
+ * 线性流程:
459
+ * 1. createCompileContext — 加载 pkg、env、config
460
+ * 2. createPlatformAdapter — 根据 platform 创建平台适配器
461
+ * 3. resolvePreConfig — 解析平台预配置(port、pages 等)
462
+ * 4. createBundlerAdapter — 根据 bundler 创建编译器适配器
463
+ * 5. platform.compile — 通过平台适配器执行编译
464
+ */
465
+ declare function runCompile(params: CompileServeParams): Promise<void>;
466
+ //#endregion
467
+ //#region src/node/platform/types.d.ts
468
+ /**
469
+ * 平台预配置
470
+ *
471
+ * 由 PlatformAdapter.resolvePreConfig() 返回,包含平台相关的配置解析结果。
472
+ * 与 WebPreConfig 形状一致,作为 platform 层的规范类型。
473
+ */
474
+ interface PlatformPreConfig {
475
+ userConfig?: UserConfig;
476
+ base: string;
477
+ target: 'pc' | 'mobile';
478
+ pages: Pages;
479
+ port: number;
480
+ browserslist: string;
481
+ isVue: boolean;
482
+ isReact: boolean;
483
+ }
484
+ /**
485
+ * 平台适配器接口
486
+ *
487
+ * 抽象出 Web / Desktop 两种平台的编译职责:
488
+ * - resolvePreConfig: 解析平台相关的预配置(port、browserslist、pages 等)
489
+ * - compile: 执行编译(Web 直接调用 bundler;Desktop 需要编排 main/preload/renderer)
490
+ */
491
+ interface PlatformAdapter {
492
+ /** 平台标识 */
493
+ readonly name: 'web' | 'desktopClient';
494
+ /**
495
+ * 解析平台相关的预配置
496
+ *
497
+ * - Web 平台:确定 port、browserslist、pages、检测 Vue/React 等
498
+ * - Desktop 平台:同上(用于 renderer),内部另行处理 main/preload
499
+ */
500
+ resolvePreConfig(ctx: CompileContext): Promise<PlatformPreConfig>;
501
+ /**
502
+ * 执行编译
503
+ *
504
+ * - Web 平台:直接调用 bundler.createConfig + runDev/runBuild
505
+ * - Desktop 平台:包装 main/preload/renderer 三目标编排
506
+ *
507
+ * @param bundler 编译器适配器(由 pipeline 根据 userConfig.bundler 创建)
508
+ * @param params 编译参数
509
+ */
510
+ compile(bundler: BundlerAdapter, params: PlatformCompileParams): Promise<void>;
511
+ }
512
+ interface PlatformCompileParams {
513
+ /** 当前命令 */
514
+ command: 'server' | 'build';
515
+ /** 平台预配置(由 resolvePreConfig 返回) */
516
+ preConfig: PlatformPreConfig;
517
+ /** 编译上下文 */
518
+ compileContext: CompileContext;
519
+ }
520
+ //#endregion
521
+ //#region src/node/platform/platform-factory.d.ts
522
+ /**
523
+ * 根据平台类型创建平台适配器实例
524
+ *
525
+ * 这是 platform 分支逻辑唯一存在的地方。
526
+ * - 'web': 直接实例化内部的 WebPlatformAdapter
527
+ * - 'desktopClient': 懒加载 @ikaros-cli/ikaros-platform-desktop-client 包
528
+ */
529
+ declare function createPlatformAdapter(platform: string): PlatformAdapter;
530
+ //#endregion
531
+ //#region src/node/platform/web/web-platform.d.ts
532
+ /**
533
+ * Web 平台适配器
534
+ *
535
+ * 实现 PlatformAdapter 接口,替代原来的 WebCompileService。
536
+ * - resolvePreConfig: 委托给 resolveWebPreConfig 解析 port/pages/browserslist 等
537
+ * - compile: 通过 BundlerAdapter 创建配置并执行 dev/build
538
+ */
539
+ declare class WebPlatformAdapter implements PlatformAdapter {
540
+ readonly name: "web";
541
+ resolvePreConfig(ctx: CompileContext): Promise<PlatformPreConfig>;
542
+ compile(bundler: BundlerAdapter, params: PlatformCompileParams): Promise<void>;
415
543
  }
416
544
  //#endregion
417
545
  //#region src/node/compile/web/resolve-web-preconfig.d.ts
@@ -425,64 +553,23 @@ type WebPreConfig = {
425
553
  isVue: boolean;
426
554
  isReact: boolean;
427
555
  };
428
- //#endregion
429
- //#region src/node/utils/optional-vite.d.ts
430
- type OptionalViteAdapter = {
431
- createWebViteConfig: (params: {
432
- command: 'server' | 'build';
433
- mode?: string;
434
- env: Record<string, unknown>;
435
- context: string;
436
- userConfig?: Record<string, unknown>;
437
- pages: Record<string, {
438
- html: string;
439
- entry: string;
440
- }>;
441
- base: string;
442
- port: number;
443
- isElectron: boolean;
444
- resolveContext: (...paths: string[]) => string;
445
- }) => unknown;
446
- runViteBuild: (config: unknown, options?: {
447
- onBuildStatus?: (status: {
448
- success: boolean;
449
- port?: number;
450
- message?: string;
451
- }) => void;
452
- }) => Promise<string | undefined>;
453
- startViteDevServer: (config: unknown, options?: {
454
- port?: number;
455
- onBuildStatus?: (status: {
456
- success: boolean;
457
- port?: number;
458
- message?: string;
459
- }) => void;
460
- }) => Promise<unknown>;
461
- };
462
- declare const loadOptionalViteAdapter: (params: {
463
- loadContextModule: <T>(id: string) => T;
464
- }) => OptionalViteAdapter;
465
- //#endregion
466
- //#region src/node/compile/web/prepare-web-compile.d.ts
467
- type PrepareWebCompileParams = {
556
+ type ResolveWebPreConfigParams = {
468
557
  command: Command;
469
- options: CompileOptions;
470
- env: DefinePluginOptions;
471
- context: string;
472
- contextPkg?: PackageJson;
473
- userConfig?: UserConfig;
474
- isElectron: boolean;
558
+ context?: string;
475
559
  resolveContext: (...paths: string[]) => string;
476
- loadViteAdapter?: () => OptionalViteAdapter;
477
- };
478
- type PrepareWebCompileResult = {
479
- bundler: NonNullable<UserConfig['bundler']>;
480
- config: Configuration | unknown;
481
- pre: WebPreConfig;
560
+ getUserConfig: () => Promise<UserConfig | undefined>;
561
+ isElectron?: boolean;
482
562
  };
483
- declare const prepareWebCompile: (params: PrepareWebCompileParams) => Promise<PrepareWebCompileResult>;
563
+ declare const resolveWebPreConfig: (params: ResolveWebPreConfigParams) => Promise<WebPreConfig>;
484
564
  //#endregion
485
- //#region src/node/utils/logger.d.ts
565
+ //#region src/node/shared/logger.d.ts
566
+ /**
567
+ * 日志系统
568
+ *
569
+ * 每次调用返回同一组方法,事件数组内聚在闭包内,避免模块级可变状态。
570
+ * 注意:多次调用 LoggerSystem() 会创建独立的事件数组。
571
+ * 如需共享状态,请在模块级缓存调用结果。
572
+ */
486
573
  declare const LoggerSystem: () => {
487
574
  done: ({
488
575
  text,
@@ -524,19 +611,35 @@ declare const LoggerSystem: () => {
524
611
  eventArray: string[];
525
612
  };
526
613
  //#endregion
527
- //#region src/node/utils/rspack-runner.d.ts
528
- type BuildStatus = {
614
+ //#region src/node/shared/check-env.d.ts
615
+ /**
616
+ * 断言 Node.js 版本满足最低要求
617
+ *
618
+ * @param minMajor - 最低的主版本号
619
+ * @throws 当 Node.js 版本低于要求时终止进程
620
+ */
621
+ declare function assertNodeVersion(minMajor: number): void;
622
+ /**
623
+ * 检查 Node.js 版本是否满足最低要求(不终止进程,抛出错误)
624
+ *
625
+ * @param minMajor - 最低的主版本号
626
+ * @throws Error 当 Node.js 版本低于要求时
627
+ */
628
+ declare function checkNodeVersion(minMajor: number): void;
629
+ //#endregion
630
+ //#region src/node/bundler/rspack/rspack-runner.d.ts
631
+ type BuildStatus$1 = {
529
632
  success: boolean;
530
633
  port?: number;
531
634
  message?: string;
532
635
  };
533
636
  type WatchRspackBuildOptions = WatchOptions & {
534
- onBuildStatus?: (status: BuildStatus) => void;
637
+ onBuildStatus?: (status: BuildStatus$1) => void;
535
638
  };
536
639
  declare const runRspackBuild: (config: Configuration | Configuration[], options?: WatchRspackBuildOptions) => Promise<string | undefined>;
537
640
  declare const watchRspackBuild: (config: Configuration | Configuration[], options?: WatchRspackBuildOptions) => Promise<string | undefined>;
538
641
  //#endregion
539
- //#region src/node/utils/const.d.ts
642
+ //#region src/node/shared/constants.d.ts
540
643
  declare const extensions: string[];
541
644
  /**
542
645
  * 基于cli的绝对定位
@@ -544,4 +647,54 @@ declare const extensions: string[];
544
647
  */
545
648
  declare const resolveCLI: (...paths: string[]) => string;
546
649
  //#endregion
547
- export { BaseCompileService, Bundler, Command, type CompileOptions, type CompileServeParame, ConfigEnvPre, CreateLoader, CreatePlugins, ElectronConfig, LoggerSystem, ModuleFederationOptions, type OptionalViteAdapter, type PackageJson, UserConfig, UserConfigFn, UserConfigWebExport, WebCompileService, defineConfig, extensions, loadOptionalViteAdapter, prepareWebCompile, resolveCLI, runRspackBuild, watchRspackBuild };
650
+ //#region src/node/bundler/bundler-factory.d.ts
651
+ interface CreateBundlerAdapterParams {
652
+ /** 编译器类型 */
653
+ bundler: 'rspack' | 'vite';
654
+ /** 基于工作目录加载模块的能力(ViteAdapterLoader 需要) */
655
+ loadContextModule: <T>(id: string) => T;
656
+ }
657
+ /**
658
+ * 根据 bundler 类型创建编译器适配器实例
659
+ *
660
+ * 这是 bundler 分支逻辑唯一存在的地方。
661
+ * 新增 bundler 只需在此处增加 case + 实现 BundlerAdapter 接口。
662
+ */
663
+ declare function createBundlerAdapter(params: CreateBundlerAdapterParams): BundlerAdapter;
664
+ //#endregion
665
+ //#region src/node/bundler/rspack/rspack-adapter.d.ts
666
+ /**
667
+ * Rspack 编译器适配器
668
+ *
669
+ * 实现 BundlerAdapter<Configuration>,将现有 rspack 相关逻辑封装为统一接口
670
+ */
671
+ declare class RspackAdapter implements BundlerAdapter<Configuration> {
672
+ readonly name: "rspack";
673
+ createConfig(params: CreateConfigParams): Configuration;
674
+ runDev(config: Configuration, options: BundlerDevOptions): Promise<void>;
675
+ runBuild(config: Configuration, options: BundlerBuildOptions): Promise<string | undefined>;
676
+ }
677
+ //#endregion
678
+ //#region src/node/bundler/vite/vite-adapter-loader.d.ts
679
+ /**
680
+ * Vite 编译器适配器(懒加载代理)
681
+ *
682
+ * 通过 loadContextModule 动态加载 @ikaros-cli/ikaros-bundler-vite,
683
+ * 实例化其导出的 ViteBundlerAdapter,直接代理 BundlerAdapter 接口。
684
+ *
685
+ * adapter 实例由 BundlerFactory 创建并统一持有,无需外部手动缓存。
686
+ */
687
+ declare class ViteAdapterLoader implements BundlerAdapter<unknown> {
688
+ readonly name: "vite";
689
+ private adapter;
690
+ private readonly loadContextModule;
691
+ constructor(params: {
692
+ loadContextModule: <T>(id: string) => T;
693
+ });
694
+ private ensureAdapter;
695
+ createConfig(params: CreateConfigParams): unknown | Promise<unknown>;
696
+ runDev(config: unknown, options: BundlerDevOptions): Promise<void>;
697
+ runBuild(config: unknown, options: BundlerBuildOptions): Promise<string | undefined>;
698
+ }
699
+ //#endregion
700
+ export { type BuildStatus, Bundler, type BundlerAdapter, type BundlerBuildOptions, type BundlerDevOptions, Command, type CompileContext, type CompileOptions, type CompileServeParams, ConfigEnvPre, type CreateBundlerAdapterParams, type CreateConfigParams, CreateLoader, CreatePlugins, ElectronConfig, LoggerSystem, ModuleFederationOptions, type PackageJson, type PlatformAdapter, type PlatformCompileParams, type PlatformPreConfig, type ResolveWebPreConfigParams, RspackAdapter, UserConfig, UserConfigFn, UserConfigWebExport, ViteAdapterLoader, WebPlatformAdapter, type WebPreConfig, assertNodeVersion, checkNodeVersion, createBundlerAdapter, createCompileContext, createPlatformAdapter, defineConfig, extensions, resolveCLI, resolveWebPreConfig, runCompile, runRspackBuild, watchRspackBuild };
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import{createRequire as e}from"node:module";import{Option as t,program as n}from"commander";import r,{dirname as i,extname as a,join as o,resolve as s}from"node:path";import c,{pathToFileURL as l}from"node:url";import u from"node:fs";import d,{readFile as f}from"node:fs/promises";import{isFunction as p,isString as m}from"es-toolkit";import{isArray as h,isEmpty as g,isObject as _}from"es-toolkit/compat";import v from"fs/promises";import{z as y}from"zod/v4";import b,{join as x}from"path";import S from"fs-extra";import{config as C}from"dotenv";import w from"chalk";import{parse as ee}from"yaml";import{transform as te}from"oxc-transform";import{rspack as T}from"@rspack/core";import{RspackDevServer as ne}from"@rspack/dev-server";import re from"node:os";import E from"pretty-bytes";import ie from"easy-table";import ae from"cli-cursor";import oe from"node:process";import{RsdoctorRspackPlugin as se}from"@rsdoctor/rspack-plugin";import ce from"compression-webpack-plugin";import{ModuleFederationPlugin as le}from"@module-federation/enhanced/rspack";import{detect as ue}from"detect-port";var de=`@ikaros-cli/ikaros`,D=`2.1.3`;const O=(e,t)=>{let n=e,r=t;for(let e of Object.keys(r)){let t=r[e],i=n[e];_(t)&&_(i)?n[e]=O(i,t):n[e]=t}return e};async function k(e){try{let t=x(process.cwd(),`node_modules`,e);return await v.access(t,v.constants.F_OK),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}const fe={target:y.enum([`pc`,`mobile`]).optional().default(`pc`),pages:y.custom().optional(),enablePages:y.union([y.array(y.string()),y.literal(!1)]).optional(),define:y.custom().optional(),build:y.object({base:y.string().optional().default(`/`),assetsDir:y.string().optional(),sourceMap:y.boolean().optional().default(!1),outDirName:y.string().optional().default(`dist`)}).optional(),resolve:y.object({alias:y.record(y.string(),y.string()).optional(),extensions:y.array(y.string()).optional()}).optional(),server:y.object({port:y.number().int().min(1024).max(65535).optional()}).optional(),electron:y.unknown().optional()},pe=y.object({bundler:y.custom().optional().default(`rspack`).refine(e=>e===`rspack`,{message:`bundler must be 'rspack' for rspack config`}),...fe,moduleFederation:y.union([y.custom(),y.array(y.custom())]).optional(),plugins:y.union([y.custom(),y.array(y.custom())]).optional(),loaders:y.array(y.custom()).optional(),experiments:y.custom().optional(),cdnOptions:y.custom().optional(),server:y.object({port:y.number().int().min(1024).max(65535).optional(),proxy:y.custom().optional(),https:y.union([y.boolean(),y.record(y.string(),y.unknown())]).optional().default(!1)}).optional(),css:y.object({lightningcssOptions:y.record(y.string(),y.unknown()).optional(),sourceMap:y.boolean().optional(),lessOptions:y.record(y.string(),y.unknown()).optional(),sassOptions:y.record(y.string(),y.unknown()).optional(),stylusOptions:y.record(y.string(),y.unknown()).optional()}).optional(),build:y.object({base:y.string().optional().default(`/`),assetsDir:y.string().optional(),gzip:y.boolean().optional().default(!1),sourceMap:y.boolean().optional().default(!1),outDirName:y.string().optional().default(`dist`),outReport:y.boolean().optional().default(!1),cache:y.boolean().optional().default(!1),dependencyCycleCheck:y.boolean().optional().default(!1)}).optional()}),me=y.object({bundler:y.literal(`vite`),...fe,server:y.object({port:y.number().int().min(1024).max(65535).optional(),proxy:y.record(y.string(),y.unknown()).optional(),https:y.union([y.boolean(),y.record(y.string(),y.unknown())]).optional()}).optional(),vite:y.object({plugins:y.unknown().optional()}).strict().optional()}).passthrough().superRefine((e,t)=>{for(let n of[`plugins`,`loaders`,`experiments`,`cdnOptions`,`moduleFederation`,`css`]){let r=e;n in r&&r[n]!==void 0&&t.addIssue({code:y.ZodIssueCode.custom,path:[n],message:`bundler='vite' 时不支持 ${String(n)},请使用 vite.plugins 或 Vite 原生配置能力`})}}),A=y.union([me,pe]),j=[],M=()=>{let e=(e,t)=>({DONE:w.bgGreen.white,ERROR:w.bgRed.white,OKAY:w.bgBlue.white,WARNING:w.bgYellow.white,INFO:w.bgCyan.white})[e](` ${e} `)+` ${t}`;return{done:({text:t,onlyText:n})=>{if(n)return e(`DONE`,t);console.log(e(`DONE`,t))},error:({text:t,onlyText:n})=>{if(n)return e(`ERROR`,t);console.error(e(`ERROR`,t))},okay:({text:t,onlyText:n})=>{if(n)return e(`OKAY`,t);console.log(e(`OKAY`,t))},warning:({text:t,onlyText:n})=>{if(n)return e(`WARNING`,t);console.warn(e(`WARNING`,t))},info:({text:t,onlyText:n})=>{if(n)return e(`INFO`,t);console.info(e(`INFO`,t))},emitEvent:e=>{let t=new Date().toLocaleTimeString(`en-US`,{hour12:!1}).split(` `)[0];j.push(`[${t}] ${e}`)},clearEventArray:()=>{j.length=0},eventArray:j}},N=e=>e?x(P,`env`,`.env.${e}`):x(P,`env`,`.env`),he=async e=>{let{warning:t,emitEvent:n}=M();if(!await S.pathExists(x(P,`env`)))return n(t({text:`env folder not found`,onlyText:!0})),!1;if(e){if(!await S.pathExists(N(e)))return n(t({text:`.env.${e} file not found`,onlyText:!0})),!1}else return await S.pathExists(N())?!0:(n(t({text:`.env file not found`,onlyText:!0})),!1);return!0},P=process.cwd(),ge=async e=>await he(e)?e?C({path:N(e),quiet:!0}).parsed??{}:C({path:N(),quiet:!0}).parsed??{}:{};async function _e(e,t){let{code:n,errors:r}=await te(e,await f(e,`utf-8`),{lang:t?`ts`:`js`});if(r.length>0)throw Error(`Transformation failed: `+r.map(e=>e.message).join(`, `));return{code:n}}async function ve(e,t){let n=`${e}.timestamp-${Date.now()}-${Math.random().toString(16).slice(2)}`,r=`${n}.mjs`,i=`${l(n)}.mjs`;await d.writeFile(r,t);try{return(await import(i)).default}finally{await d.unlink(r)}}async function ye(e,t=!1){let{code:n}=await _e(e,t);return ve(e,n)}const F=new Map;F.set(`.mjs`,async e=>(await import(l(e).href)).default),F.set(`.ts`,async e=>await ye(e,!0)),F.set(`.json`,async e=>await S.readJson(e)),F.set(`.yaml`,async e=>ee(await d.readFile(e,`utf8`)));async function be({configFile:e}){let t,n=process.cwd(),r=`ikaros.config`,c=[`ts`,`mjs`,`json`,`yaml`].map(e=>`${o(n,r)}.${e}`),l=(await Promise.all(c.map(e=>S.pathExists(e)))).findIndex(Boolean);if(!(l<0)){if(t=a(c[l]),n=s(n,`${r}${t}`),e&&(n=i(e),t=a(e)),!F.has(t))throw Error(`No configuration file ! `);return F.get(t)(n)}}let I=function(e){return e.SERVER=`server`,e.BUILD=`build`,e}({});var L=class{set env(e){this._env=e}get env(){return this._env}set contextPkg(e){this._contextPkg=e}get contextPkg(){return this._contextPkg}get isElectron(){return this.options.platform===`desktopClient`}constructor(t){this.resolveContext=(...e)=>o(this.context,...e);let{command:n,options:r,configFile:i}=t;this.command=n,this.options=r,this.configFile=i,this.context=process.cwd(),this.contextRequire=e(o(this.context,`./`))}static async create(e){let t=new this(e);return await t.initialize(),t}async initialize(){await this.initContextPkg(),await this.initEnv(),await this.loadUserConfig(),await this.onAfterConfigLoaded(),await this.startCompile()}async onAfterConfigLoaded(){}async initContextPkg(){let e=this.resolveContext(`package.json`);try{await d.access(e,u.constants.F_OK)}catch{return}this.contextPkg=JSON.parse(await d.readFile(e,{encoding:`utf8`}))}async initEnv(){let{platform:e,mode:t}=this.options,n={PLATFORM:e,MODE:t},r=await ge(t);this.env={...n,...r}}async loadUserConfig(){this.userConfig=await this.getUserConfig()}resolveContextModule(e){try{return this.contextRequire.resolve(e)}catch{return}}loadContextModule(e){return this.contextRequire(e)}async getUserConfig(){let{configFile:e}=this,t=await be({configFile:e});if(t){if(p(t)){let e={mode:this.options.mode??``,env:{...this.env,PLATFORM:this.options.platform,MODE:this.options.mode??this.env?.MODE},command:this.command};return A.parse(await t(e))}if(_(t))return A.parse(t)}}async startCompile(){switch(this.command){case I.SERVER:await this.dev();break;case I.BUILD:await this.build();break;default:break}}};const R=e=>{let t=`Build failed with errors.
2
- `;return e.toString({chunks:!1,colors:!0}).split(/\r?\n/).forEach(e=>{t+=` ${e}\n`}),t},z=(e,t)=>{let{onBuildStatus:n}=t??{};return new Promise((t,r)=>{let i=T(e);i.run((e,a)=>{i.close(i=>{let o=e||i;if(o)return n?.({success:!1,message:o.message||`build error`}),r(o);if(a?.hasErrors()){let e=R(a);return n?.({success:!1,message:e}),r(Error(e))}let s=a?.toString({chunks:!1,colors:!0});return n?.({success:!0,message:s}),t(s)})})})},xe=async(e,t)=>{let{port:n,onBuildStatus:r}=t??{},i=T(e),a=new ne(e.devServer,i);await new Promise((e,t)=>{a.startCallback(i=>i?(r?.({success:!1,port:n,message:i.message}),t(i)):(r?.({success:!0,port:n}),e()))})},Se=(e,t)=>{let{onBuildStatus:n,...r}=t??{};return new Promise((t,i)=>{T(e).watch({ignored:/node_modules/,aggregateTimeout:300,poll:!1,...r},(e,r)=>{if(e)return n?.({success:!1,message:e.message||`watch build error`}),i(e);if(r?.hasErrors()){let e=R(r);return n?.({success:!1,message:e}),i(Error(e))}let a=r?.toString({chunks:!1,colors:!0});return n?.({success:!0,message:a}),t(a)})})},B=x(process.cwd(),`./`),V=[`...`,`.mjs`,`.jsx`,`.ts`,`.tsx`];x(B,`tsconfig.json`);const H=c.fileURLToPath(new c.URL(`../`,import.meta.url)),Ce=e(H),U=(...e)=>x(H,...e),W=(e,t)=>({loader:e.includes(`builtin`)?e:Ce.resolve(e),options:t}),we=(e,t)=>{let{lightningcss:n,sourceMap:r}=t??{},i=W(`builtin:lightningcss-loader`,{...n}),a=(e,n)=>{let a=[i],o=t&&t[`${e}`];return e&&e!==`css`&&a.push(W(`${e}-loader`,Object.assign(o??{},n,{sourceMap:r}))),a};return{less:a(`less`),sass:a(`sass`,{sassOptions:{indentedSyntax:!0,api:`modern-compiler`}}),scss:a(`sass`,{sassOptions:{api:`modern-compiler`}}),stylus:a(`stylus`),styl:a(`stylus`),css:a(`css`)}},Te=(e,t)=>{let n=we(e,t);return Object.entries(n).map(([e,t])=>({test:RegExp(`\\.${e}$`),use:t,type:`css/auto`}))};var G=class{constructor({env:e=`development`,mode:t=``}){this.list=[],this.env=`development`,this.mode=``,this.isDev=!0,this.env=e,this.mode=t,this.isDev=e===`development`}add(e){return e&&(h(e)?this.list=this.list.concat(e):this.list.push(e)),this}end(){return this.list}},K=class extends G{constructor({env:e=`development`,mode:t=``}){super({env:e,mode:t}),this.defaultScriptLoader=e=>[{test:/\.m?ts$/i,loader:`builtin:swc-loader`,options:{jsc:{parser:{syntax:`typescript`}}},type:`javascript/auto`,exclude:[x(B,`node_modules`)]},{test:/\.m?js$/i,loader:`builtin:swc-loader`,options:{isModule:`unknown`,rspackExperiments:e},type:`javascript/auto`,exclude:[x(B,`node_modules`)]}],this.defaultResourceLoader=[{test:/\.(png|jpe?g|gif|svg|ico)(\?.*)?$/,type:`asset/resource`,generator:{filename:this.isDev?`[id][ext]`:`assets/img/[contenthash][ext]`}},{test:/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,type:`asset/resource`,generator:{filename:this.isDev?`[id][ext]`:`assets/media/[contenthash][ext]`}},{test:/\.(woff2?|eot|ttf|otf)(\?.*)?$/,type:`asset/resource`,generator:{filename:this.isDev?`[id][ext]`:`assets/fonts/[contenthash][ext]`}}]}useDefaultCssLoader(e){return Te(this.env,e).forEach(e=>this.add(e)),this}useDefaultScriptLoader(e){return this.add(this.defaultScriptLoader(e)),this}useDefaultResourceLoader(){return this.defaultResourceLoader.forEach(e=>this.add(e)),this}},q=class extends G{constructor({env:e=`development`,mode:t=``}){super({env:e,mode:t})}useDefaultEnvPlugin(e){let{frameworkEnv:t={},extEnv:n={},env:r={}}=e??{};return this.add(De({frameworkEnv:t,extEnv:n,env:r})),this}useCopyPlugin(){return this.env===`production`&&this.add(new T.CopyRspackPlugin({patterns:[{context:x(B,`public`),from:`./`,noErrorOnMissing:!0,globOptions:{ignore:[`**/index.html`,`.*`]}}]})),this}useHtmlPlugin(e){return this.add(new T.HtmlRspackPlugin({template:e??x(B,`index.html`)})),this}},Ee=class{constructor({pages:e,enablePages:t}){this.pages=e,this.enablePages=t,this.getEnablePages()}create(){let e={},t=[];return Object.keys(this.pages).forEach(n=>{e[n]={import:this.pages[n].entry,library:this.pages[n].library},t.push(new T.HtmlRspackPlugin({template:this.pages[n].html,filename:`${n}.html`,chunks:[n],scriptLoading:`blocking`,...this.pages[n].options}))}),{entry:e,plugins:t}}getEnablePages(){let{warning:e,emitEvent:t}=M();if(!g(this.pages)&&h(this.enablePages)){let n={},r=[];if(this.enablePages.forEach(e=>{this.pages[e]?n[e]=this.pages[e]:r.push(e)}),g(r)&&t(e({text:`当前设置页面${r.join()}不存在`,onlyText:!0})),g(n))return;this.pages=n}}};const De=({frameworkEnv:e={},extEnv:t={},env:n={}})=>{let r=Object.assign({},O(t,n)),i=Object.fromEntries(Object.entries(r).map(([e,t])=>[`import.meta.env.${e}`,JSON.stringify(t)])),a=Object.fromEntries(Object.entries({...i,...e}).map(([e,t])=>[e,t]));return new T.DefinePlugin(a)},J={name:de,version:D},Y=`@rspack/ikaros-stats-plugin`,X=w.hex(`#222222`);var Oe=class{constructor(e){this.startCompileHrtime=void 0,this.userConfig=e}apply(e){this.compiler=e,this.isDev=e.options.mode===`development`,new T.ProgressPlugin().apply(e),ae.hide(),this.isDev?this.initDevHook():this.initProdHook()}updateStartCompileTime(){this.startCompileHrtime=oe.hrtime()}getCurrentEndCompileTime(){let e=oe.hrtime(this.startCompileHrtime);return(e[0]*1e9+e[1])/1e6}getError(e){let{errors:t,errorsCount:n=0}=e;if(!(!t||n===0))return t.map(e=>`${X.bgRed(` ERROR `)} ${e.message.trim()}`).join(`
1
+ import{createRequire as e}from"node:module";import{Option as t,program as n}from"commander";import{rspack as r}from"@rspack/core";import{isFunction as i,isString as a}from"es-toolkit";import o,{dirname as s,extname as c,join as l,resolve as u}from"node:path";import d,{join as f}from"path";import p,{pathToFileURL as m}from"node:url";import{isArray as h,isEmpty as g,isObject as _}from"es-toolkit/compat";import v from"chalk";import y from"fs/promises";import b from"node:os";import x from"pretty-bytes";import S from"easy-table";import C from"cli-cursor";import w from"node:process";import{RsdoctorRspackPlugin as T}from"@rsdoctor/rspack-plugin";import ee from"compression-webpack-plugin";import{ModuleFederationPlugin as E}from"@module-federation/enhanced/rspack";import te from"node:fs";import D,{readFile as ne}from"node:fs/promises";import{z as O}from"zod/v4";import k from"fs-extra";import{config as re}from"dotenv";import{parse as ie}from"yaml";import{transform as ae}from"oxc-transform";import{RspackDevServer as oe}from"@rspack/dev-server";import{detect as se}from"detect-port";var ce=`@ikaros-cli/ikaros`,A=`2.2.1`;const j=f(process.cwd(),`./`),M=[`...`,`.mjs`,`.jsx`,`.ts`,`.tsx`];f(j,`tsconfig.json`);const N=p.fileURLToPath(new p.URL(`../`,import.meta.url)),le=e(N),P=(...e)=>f(N,...e),F=(e,t)=>({loader:e.includes(`builtin`)?e:le.resolve(e),options:t}),ue=(e,t)=>{let{lightningcss:n,sourceMap:r}=t??{},i=F(`builtin:lightningcss-loader`,{...n}),a=(e,n)=>{let a=[i],o=t&&t[`${e}`];return e&&e!==`css`&&a.push(F(`${e}-loader`,Object.assign(o??{},n,{sourceMap:r}))),a};return{less:a(`less`),sass:a(`sass`,{sassOptions:{indentedSyntax:!0,api:`modern-compiler`}}),scss:a(`sass`,{sassOptions:{api:`modern-compiler`}}),stylus:a(`stylus`),styl:a(`stylus`),css:a(`css`)}},de=(e,t)=>{let n=ue(e,t);return Object.entries(n).map(([e,t])=>({test:RegExp(`\\.${e}$`),use:t,type:`css/auto`}))},fe={DONE:v.bgGreen.white,ERROR:v.bgRed.white,OKAY:v.bgBlue.white,WARNING:v.bgYellow.white,INFO:v.bgCyan.white},pe=(e,t)=>fe[e](` ${e} `)+` ${t}`,I=(e,t)=>({text:n,onlyText:r})=>{let i=pe(e,n);if(r)return i;t(i)},L=(()=>{let e=[],t={done:I(`DONE`,console.log),error:I(`ERROR`,console.error),okay:I(`OKAY`,console.log),warning:I(`WARNING`,console.warn),info:I(`INFO`,console.info),emitEvent:t=>{let n=new Date().toLocaleTimeString(`en-US`,{hour12:!1}).split(` `)[0];e.push(`[${n}] ${t}`)},clearEventArray:()=>{e.length=0},eventArray:e};return()=>t})(),R=(e,t)=>{let n=e,r=t;for(let e of Object.keys(r)){let t=r[e],i=n[e];_(t)&&_(i)?n[e]=R(i,t):n[e]=t}return e};async function z(e,t=process.cwd()){try{let n=f(t,`node_modules`,e);return await y.access(n,y.constants.F_OK),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}var B=class{constructor({env:e=`development`,mode:t=``}){this.list=[],this.env=`development`,this.mode=``,this.isDev=!0,this.env=e,this.mode=t,this.isDev=e===`development`}add(e){return e&&(h(e)?this.list=this.list.concat(e):this.list.push(e)),this}end(){return this.list}},V=class extends B{constructor({env:e=`development`,mode:t=``}){super({env:e,mode:t}),this.defaultScriptLoader=e=>[{test:/\.m?ts$/i,loader:`builtin:swc-loader`,options:{jsc:{parser:{syntax:`typescript`}}},type:`javascript/auto`,exclude:[f(j,`node_modules`)]},{test:/\.m?js$/i,loader:`builtin:swc-loader`,options:{isModule:`unknown`,rspackExperiments:e},type:`javascript/auto`,exclude:[f(j,`node_modules`)]}],this.defaultResourceLoader=[{test:/\.(png|jpe?g|gif|svg|ico)(\?.*)?$/,type:`asset/resource`,generator:{filename:this.isDev?`[id][ext]`:`assets/img/[contenthash][ext]`}},{test:/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,type:`asset/resource`,generator:{filename:this.isDev?`[id][ext]`:`assets/media/[contenthash][ext]`}},{test:/\.(woff2?|eot|ttf|otf)(\?.*)?$/,type:`asset/resource`,generator:{filename:this.isDev?`[id][ext]`:`assets/fonts/[contenthash][ext]`}}]}useDefaultCssLoader(e){return de(this.env,e).forEach(e=>this.add(e)),this}useDefaultScriptLoader(e){return this.add(this.defaultScriptLoader(e)),this}useDefaultResourceLoader(){return this.defaultResourceLoader.forEach(e=>this.add(e)),this}},H=class extends B{constructor({env:e=`development`,mode:t=``}){super({env:e,mode:t})}useDefaultEnvPlugin(e){let{frameworkEnv:t={},extEnv:n={},env:r={}}=e??{};return this.add(he({frameworkEnv:t,extEnv:n,env:r})),this}useCopyPlugin(){return this.env===`production`&&this.add(new r.CopyRspackPlugin({patterns:[{context:f(j,`public`),from:`./`,noErrorOnMissing:!0,globOptions:{ignore:[`**/index.html`,`.*`]}}]})),this}useHtmlPlugin(e){return this.add(new r.HtmlRspackPlugin({template:e??f(j,`index.html`)})),this}},me=class{constructor({pages:e,enablePages:t}){this.pages=e,this.enablePages=t,this.getEnablePages()}create(){let e={},t=[];return Object.keys(this.pages).forEach(n=>{e[n]={import:this.pages[n].entry,library:this.pages[n].library},t.push(new r.HtmlRspackPlugin({template:this.pages[n].html,filename:`${n}.html`,chunks:[n],scriptLoading:`blocking`,...this.pages[n].options}))}),{entry:e,plugins:t}}getEnablePages(){let{warning:e,emitEvent:t}=L();if(!g(this.pages)&&h(this.enablePages)){let n={},r=[];if(this.enablePages.forEach(e=>{this.pages[e]?n[e]=this.pages[e]:r.push(e)}),g(r)&&t(e({text:`当前设置页面${r.join()}不存在`,onlyText:!0})),g(n))return;this.pages=n}}};const he=({frameworkEnv:e={},extEnv:t={},env:n={}})=>{let i=Object.assign({},R(t,n)),a=Object.fromEntries(Object.entries(i).map(([e,t])=>[`import.meta.env.${e}`,JSON.stringify(t)])),o=Object.fromEntries(Object.entries({...a,...e}).map(([e,t])=>[e,t]));return new r.DefinePlugin(o)},U={name:ce,version:A},W=`@rspack/ikaros-stats-plugin`,G=v.hex(`#222222`);var ge=class{constructor(e){this.startCompileHrtime=void 0,this.userConfig=e}apply(e){this.compiler=e,this.isDev=e.options.mode===`development`,new r.ProgressPlugin().apply(e),C.hide(),this.isDev?this.initDevHook():this.initProdHook()}updateStartCompileTime(){this.startCompileHrtime=w.hrtime()}getCurrentEndCompileTime(){let e=w.hrtime(this.startCompileHrtime);return(e[0]*1e9+e[1])/1e6}getError(e){let{errors:t,errorsCount:n=0}=e;if(!(!t||n===0))return t.map(e=>`${G.bgRed(` ERROR `)} ${e.message.trim()}`).join(`
3
2
 
4
- `)}getWarn(e){let{warnings:t,warningsCount:n=0}=e;if(!(!t||n===0))return t.map(e=>`${X.bgYellow(` WARN `)} ${e.message.trim()}`).join(`
3
+ `)}getWarn(e){let{warnings:t,warningsCount:n=0}=e;if(!(!t||n===0))return t.map(e=>`${G.bgYellow(` WARN `)} ${e.message.trim()}`).join(`
5
4
 
6
- `)}getEndTips(e,t){let{gray:n,cyan:r,red:i,green:a,yellow:o}=w,{errorsCount:s=-1,warningsCount:c=-1}=e,l=(t/1e3).toFixed(2);return n(s>0?`${r(J.name)} compiled with${i(` ${s} error`)}`:c>0?`compile ${a(`success`)} and with ${o(`${c} warning`)}, time: ${l}s`:`compile ${a(`success`)}, time: ${l}s.`)}getTableInfo(e){let{assets:t}=e;if(!t||t.length===0)return;let n=new ie,r=this.userConfig?.build?.gzip??!1,i=0,a=0,o=!1;for(let e=0;e<t.length;e++){let{name:s,size:c,related:l,info:u}=t[e];if(u.development)continue;let d=r&&h(l)?l.find(e=>e.type===`gzipped`).size:0;if(i+=c,a+=d,t.length>20&&e>=4&&e<t.length-1-4){o||(o=!0,n.cell(`name`,`....`),n.cell(`size`,`....`),r&&n.cell(`gzip`,`....`),n.newRow());continue}n.cell(`name`,s),n.cell(`size`,E(c)),r&&n.cell(`gzip`,E(d)),n.newRow()}return n.pushDelimeter(),n.cell(`name`,`There are ${t.length} files`),n.cell(`size`,E(i)),r&&n.cell(`gzip`,E(a)),n.newRow(),w.cyan.dim(n.toString().trim())}getHostList(){let{userConfig:e,compiler:t}=this,{devServer:n}=t.options,i=n?.server===`https`||typeof n?.server==`object`,a=Number(n?.port),o=[],s=``,c=Object.values(re.networkInterfaces());if(e){s=e.build?.base??``,(!s||s===`auto`)&&(s=`/`);let t=Object.keys(e?.pages||{})[0];t&&t!==`index`?s=r.join(s,`${t}.html`):s.endsWith(`/`)||(s+=`/`)}for(let e of c){let{address:t}=e?.find(e=>e.family===`IPv4`)||{};t&&o.push(t)}o.sort((e,t)=>{let n=e.split(`.`),r=t.split(`.`);for(let[t]of n.entries())if(e[t]!==r[t])return Number(r[t])-Number(e[t]);return 0});let l=o.indexOf(`127.0.0.1`);return l!==-1&&(o.splice(l,1),o.unshift(`localhost`)),o=o.map(e=>(i?(e=`https://${e}`,a!==443&&(e=e+`:`+a)):(e=`http://`+e,a!==80&&(e=e+`:`+a)),new URL(s,e).href)),o}initDevHook(){let{compiler:e}=this,t=this.getHostList(),{blue:n,cyan:r,gray:i}=w;e.hooks.environment.intercept({name:Y}),e.hooks.watchRun.intercept({name:Y,call:()=>{this.updateStartCompileTime()}}),e.hooks.done.intercept({name:Y,call:e=>{console.clear();let a=e.toJson({preset:`errors-warnings`,colors:!0}),{eventArray:o}=M(),{errorsCount:s=0,warningsCount:c=0}=a;if(s>0)console.log(this.getError(a)),console.log();else{c>0&&(console.log(this.getWarn(a)),console.log()),o.length>0&&(console.log(o.map(e=>e).join(`
7
- `)),console.log());let{name:e,version:s}=J,l=`${r(`${e} v${s}`)} entry address:\n\n`;for(let e of t)l+=n(` ${e}\n`);console.log(i(l))}console.log(this.getEndTips(a,this.getCurrentEndCompileTime())),console.log()}})}initProdHook(){let{compiler:e}=this,t;e.hooks.environment.intercept({name:Y,call:()=>{console.log(w.gray(`start build...`)),this.updateStartCompileTime()}}),e.hooks.done.intercept({name:Y,call:e=>{t=e.toJson({preset:`normal`,colors:!0,assetsSort:`size`})}}),e.cache.hooks.shutdown.intercept({name:Y,done:()=>{let{errorsCount:e=0,warningsCount:n=0}=t;console.log(),e>0?(console.log(this.getError(t)),console.log()):(n>0&&(console.log(this.getWarn(t)),console.log()),console.log(this.getTableInfo(t)),console.log()),console.log(this.getEndTips(t,this.getCurrentEndCompileTime()))}})}};const Z=`@rspack/ikaros-cdn-plugin`,ke=/:([a-z]+)/gi;var Ae=class{constructor(e){this.isDev=!1,this.options={prodUrl:`https://unpkg.com/:name@:version/:path`,devUrl:`:name/:path`,crossOrigin:!1,...e}}apply(e){this.compiler=e,this.isDev=e.options.mode===`development`,this.handleExternals(),e.hooks.compilation.tap(Z,e=>{T.HtmlRspackPlugin.getCompilationHooks(e).alterAssetTags.tapAsync(Z,(e,t)=>{try{this.injectResources(e),t(null,e)}catch(e){t(e)}})})}handleExternals(){let e=this.compiler.options.externals||{};this.options.modules.filter(e=>!e.cssOnly).forEach(t=>{e[t.name]=t.var||t.name}),this.compiler.options.externals=e}injectResources(e){let t=this.options.modules,n=[];t.forEach(e=>{this.getStyles(e).forEach(e=>{n.push({tagName:`link`,voidTag:!0,attributes:{rel:`stylesheet`,href:e,...this.options.crossOrigin&&{crossorigin:this.options.crossOrigin}}})})}),t.filter(e=>!e.cssOnly).forEach(e=>{this.getScripts(e).forEach(e=>{n.push({tagName:`script`,voidTag:!0,attributes:{src:e,...this.options.crossOrigin&&{crossorigin:this.options.crossOrigin}}})})}),e.assetTags&&(e.assetTags.styles.unshift(...n.filter(e=>e.tagName===`link`)),e.assetTags.scripts.unshift(...n.filter(e=>e.tagName===`script`)))}getStyles(e){let t=[...e.styles||[]];return e.style&&t.unshift(e.style),t.map(t=>this.generateUrl(e,t))}getScripts(e){let t=[...e.paths||[]];return e.path&&t.unshift(e.path),t.map(t=>this.generateUrl(e,t))}joinUrl(e,t){return e=e.replace(/\/+$/,``),t=t.replace(/^\/+/,``),`${e}/${t}`}generateUrl(e,t){let n=this.isDev?e.devUrl||this.options.devUrl:e.prodUrl||this.options.prodUrl;return n.match(ke)?n.replace(ke,(n,r)=>{switch(r){case`name`:return e.name;case`version`:return e.version||this.getModuleVersion(e.name);case`path`:return t;default:return n}}):this.joinUrl(n,t)}getModuleVersion(t){try{return e(b.join(process.cwd(),`node_modules`))(b.join(t,`package.json`)).version}catch{return console.warn(w.yellow(`[${Z}] 无法获取模块 "${t}" 的版本信息`)),`latest`}}},je=class{constructor(e){this.options=e}createSourceMapPlugin(){let{isDev:e,userConfig:t}=this.options;if(e)return new T.EvalSourceMapDevToolPlugin({columns:!1,module:!0});if(t?.build?.sourceMap??!1)return new T.SourceMapDevToolPlugin({test:[/.js/,/.mjs/],filename:`[file].map[query]`})}createCssExtractPlugin(){if(!this.options.isDev)return new T.CssExtractRspackPlugin({filename:this.joinAssetsDir(`assets/css/[contenthash].css`),ignoreOrder:!0})}createDoctorPlugin(){let{isDev:e,userConfig:t}=this.options;if(!(e||!t?.build?.outReport))return new se}createGzipPlugin(){let{isDev:e,userConfig:t}=this.options;if(!(e||!t?.build?.gzip))return new ce}createCdnPlugin(){let{cdnOptions:e}=this.options.userConfig??{};if(!(!e||g(e.modules)))return new Ae(e)}createModuleFederationPlugin(){let e=this.options.userConfig?.moduleFederation;if(e)return h(e)?e.map(e=>new le(e)):new le(e)}createDependencyCyclePlugin(){let{isDev:e,userConfig:t}=this.options;if(!(e||!t?.build?.dependencyCycleCheck))return new T.CircularDependencyRspackPlugin({exclude:/node_modules/,failOnError:!1})}joinAssetsDir(...e){return[this.options.assetsDir,...e].join(`/`).replace(/\/+/g,`/`)}};const Me=e=>{let{isVue:t,isReact:n}=e;return t?{noParse:/^(vue|vue-router|vuex|vuex-router-sync)$/,env:{__VUE_OPTIONS_API__:!0,__VUE_PROD_DEVTOOLS__:!1,__VUE_PROD_HYDRATION_MISMATCH_DETAILS__:!1}}:n?{noParse:e=>/(react|react-dom|react-is)\.production\.min\.js$/.test(e),env:{REACT_APP_ENABLE_DEVTOOLS:!1}}:{env:void 0,noParse:void 0}},Ne=e=>e===I.SERVER?{minimize:!1,removeAvailableModules:!1,removeEmptyChunks:!1,splitChunks:!1}:{minimize:!0,minimizer:[new T.LightningCssMinimizerRspackPlugin,new T.SwcJsMinimizerRspackPlugin],splitChunks:{chunks:`all`,minSize:3e4,minChunks:1,maxAsyncRequests:5,maxInitialRequests:3,cacheGroups:{vendor:{test:/[\\/]node_modules[\\/]/,name:`vendors`,priority:10,chunks:`all`},common:{name:`common`,minChunks:2,priority:5,reuseExistingChunk:!0}}}},Pe=e=>{if(e.command!==I.SERVER&&e.userConfig?.build?.cache)return{cache:!0,experiments:{cache:{type:`persistent`}}}},Fe=e=>{let{userConfig:t,isElectron:n,resolveContext:r}=e,i=t?.build?.outDirName;if(n){let e=t?.electron,n=r(`dist/electron/renderer`);return e?.build?.outDir?o(r(e.build.outDir),`renderer`):n}return m(i)?r(i):r(`dist`)},Ie=(e,t)=>[e,t].filter(Boolean).join(`/`).replace(/\/+/g,`/`),Le=e=>{let{command:t,mode:n,env:r,context:i,contextPkg:a,userConfig:s,pages:c,browserslist:l,base:u,port:d,isElectron:f,resolveContext:p}=e,m=t===I.SERVER,h=m?`development`:`production`,g=new K({env:h,mode:n}),_=new q({env:h,mode:n}),{entry:v,plugins:y}=new Ee({pages:c,enablePages:s?.enablePages}).create(),{env:b,noParse:x}=Me({isVue:e.isVue,isReact:e.isReact}),S=g.useDefaultResourceLoader().useDefaultScriptLoader(s?.experiments).useDefaultCssLoader(s?.css).add(s?.loaders).end(),C=s?.build?.assetsDir??``,w=new je({command:t,userConfig:s,isDev:m,assetsDir:C}),ee=_.useDefaultEnvPlugin({extEnv:{...s?.define},frameworkEnv:b,env:r}).useCopyPlugin().add(y).add(new Oe).add(w.createSourceMapPlugin()).add(w.createCssExtractPlugin()).add(w.createDoctorPlugin()).add(w.createGzipPlugin()).add(w.createCdnPlugin()).add(w.createModuleFederationPlugin()).add(w.createDependencyCyclePlugin()).add(s?.plugins).end();return{mode:h,context:i,entry:v,target:f?`electron-renderer`:[`web`,`es2015`,`browserslist:${l}`],resolve:{alias:{"@":p(`src`),...s?.resolve?.alias},extensions:s?.resolve?.extensions||V,modules:[`node_modules`,p(`node_modules`),U(`node_modules`)]},output:{clean:!0,path:Fe({userConfig:s,isElectron:f,resolveContext:p}),publicPath:f?`./`:u,filename:m?`[name].[contenthash:8].js`:Ie(C,`assets/js/[contenthash:8].js`),chunkFilename:m?`[name].[contenthash:8].chunk.js`:Ie(C,`assets/js/[contenthash:8].chunk.js`),chunkLoadingGlobal:`${a?.name||`ikaros`}_chunk`,pathinfo:!1},optimization:Ne(t),stats:`none`,watchOptions:{aggregateTimeout:500,ignored:/node_modules/},module:{rules:S,noParse:x},plugins:ee,devServer:{hot:!0,port:d,server:(()=>{let e=s?.server?.https;return e?e===!0?`https`:{type:`https`,options:e}:`http`})(),allowedHosts:`all`,proxy:s?.server?.proxy,historyApiFallback:{disableDotRule:!0,rewrites:[{from:/\.(js|css|json|png|jpe?g|gif|svg|ico|woff2?|eot|ttf|otf|mp4|webm|ogg|mp3|wav|flac|aac|map)(\?.*)?$/,to:e=>e.parsedUrl.pathname},{from:RegExp(`^${u}`),to:o(u,`index.html`)}]},headers:{"Access-Control-Allow-Origin":`*`},static:{directory:p(`public`),publicPath:u},client:{logging:`none`,overlay:{errors:!0,warnings:!1,runtimeErrors:!1},webSocketURL:`auto://0.0.0.0:${d}/ws`}},experiments:{css:!0},...Pe({command:t,userConfig:s})}},Re=e=>{let t=e===`mobile`,n=[`defaults`];return t?n.push(`IOS >= 16`,`Chrome >= 80`):n.push(`>0.2%`,`Chrome >= 90`,`Safari >= 16`,`last 2 versions`,`not dead`),n.join(`,`)},ze=(e,t)=>t?{index:{html:e(`src/renderer/index.html`),entry:e(`src/renderer/index`)}}:{index:{html:e(`index.html`),entry:e(`src/index`)}},Be=async e=>{let{command:t,resolveContext:n,getUserConfig:r,isElectron:i}=e,a=await r(),o=a?.build?.base??`/`;if(t===I.SERVER&&/^https?:/.test(o)){let e=w.cyan(`build.base`);throw Error(`本地开发时 ${e} 不应该为外部 Host!`)}let s=a?.target??`pc`,c=a?.pages??ze(n,!!i),l=a?.server?.port??await ue(`8080`),u=!1,d=!1;try{let[e,t]=await Promise.all([k(`react`),k(`vue`)]);u=t,d=e}catch{}return{userConfig:a,base:o,target:s,pages:c,port:l,browserslist:Re(s),isVue:u,isReact:d}},Ve=async e=>{let{command:t,options:n,env:r,context:i,contextPkg:a,userConfig:o,isElectron:s,resolveContext:c,loadViteAdapter:l}=e,u=await Be({command:t,resolveContext:c,getUserConfig:async()=>o,isElectron:s}),d=u.userConfig?.bundler??`rspack`;return{bundler:d,config:(()=>{switch(d){case`vite`:{let e=l?.();if(!e)throw Error(`bundler='vite' 需要安装可选依赖 @ikaros-cli/ikaros-bundler-vite`);return e.createWebViteConfig({command:t,mode:n.mode,env:r,context:i,userConfig:u.userConfig,pages:u.pages,base:u.base,port:u.port,isElectron:s,resolveContext:c})}case`rspack`:default:return Le({command:t,mode:n.mode,env:r,context:i,contextPkg:a,userConfig:u.userConfig,pages:u.pages,browserslist:u.browserslist,base:u.base,port:u.port,isElectron:s,isVue:u.isVue,isReact:u.isReact,resolveContext:c})}})(),pre:u}},He=()=>{let e=`@ikaros-cli/ikaros-bundler-vite`,t=[`你启用了 bundler='vite',但未安装可选依赖 ${e}。`,``,`请安装后重试:`,` pnpm add -D ${e}`];return Error(t.join(`
8
- `))},Ue=()=>{let e=[`你启用了 bundler='vite',但当前 Node.js 版本过低。`,`当前版本:v${process.versions.node}`,`Vite 7 运行时通常需要 Node.js >= 22。`];return Error(e.join(`
9
- `))},Q=e=>{let{loadContextModule:t}=e,n=Number(process.versions.node.split(`.`)[0]);if(Number.isFinite(n)&&n<22)throw Ue();try{let e=t(`@ikaros-cli/ikaros-bundler-vite`),n=e.default??e;if(typeof n?.createWebViteConfig!=`function`||typeof n?.runViteBuild!=`function`||typeof n?.startViteDevServer!=`function`)throw He();return n}catch(e){throw e instanceof Error,He()}},{error:We}=M();var Ge=class extends L{constructor(e){super(e),this.onBuildStatus=e.onBuildStatus}async dev(){let e=await this.prepare();if(e.bundler===`vite`){await e.vite.startViteDevServer(e.config,{port:this.port,onBuildStatus:this.onBuildStatus});return}await xe(e.config,{port:this.port,onBuildStatus:this.onBuildStatus})}async build(){let e=await this.prepare();if(e.bundler===`vite`){await e.vite.runViteBuild(e.config,{onBuildStatus:this.onBuildStatus});return}await z(e.config,{onBuildStatus:this.onBuildStatus})}async prepare(){try{let e=await Ve({command:this.command,options:this.options,env:this.env,context:this.context,contextPkg:this.contextPkg,userConfig:this.userConfig,isElectron:this.isElectron,resolveContext:this.resolveContext,loadViteAdapter:()=>this.viteAdapter??=Q({loadContextModule:this.loadContextModule.bind(this)})});return this.userConfig=e.pre.userConfig,this.port=e.pre.port,e.bundler===`vite`?{bundler:`vite`,config:e.config,vite:this.viteAdapter??=Q({loadContextModule:this.loadContextModule.bind(this)})}:{bundler:`rspack`,config:e.config}}catch(e){We({text:e instanceof Error?e.message:String(e)}),process.exit(0)}}getDevPort(){return this.port}};const Ke=()=>{let e=`@ikaros-cli/ikaros-platform-desktop-client`,t=[`你启用了 platform='desktopClient',但未安装可选依赖 ${e}。`,``,`请安装后重试:`,` pnpm add -D ${e}`];return Error(t.join(`
10
- `))},qe=async()=>{try{let t=await import(l(e(o(process.cwd(),`./`)).resolve(`@ikaros-cli/ikaros-platform-desktop-client`)).href),n=t.default??t;if(typeof n?.startDesktopClientCompile!=`function`)throw Ke();return n}catch{throw Ke()}},$={WEB:`web`,DESKTOPCLIENT:`desktopClient`,ELECTRON:`desktopClient`},Je=[new t(`-m, --mode <name>`,`Environment variable`),new t(`-p, --platform <type>`,`build platform type`).default($.WEB).choices(Object.values($))],Ye=async e=>{try{switch(e.options.platform){case $.WEB:await Ge.create(e);return;case $.DESKTOPCLIENT:await(await qe()).startDesktopClientCompile(e);return;default:{let e=Object.values($).join(`,`);throw Error(`No corresponding compilation service was found, platform: ${e}`)}}}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`${t}\n`),process.exit(1)}},Xe=e=>{let t=e.command(I.SERVER,{isDefault:!0}).description(`Start local develop serve`).action(async e=>{await Ye({command:I.SERVER,options:e})}),n=e.command(I.BUILD).description(`Start build`).action(async e=>{await Ye({command:I.BUILD,options:e})});for(let e of Je)t.addOption(e),n.addOption(e)},Ze=e=>e;if(Number(process.versions.node.split(`.`)[0])<22){let e=w.bgRed.white(` ERROR `);process.stderr.write(`${e} Node.js version must be greater than or equal to v22!\n\n`),process.exit(1)}n.version(D,`-v, --version`),Xe(n),n.parse();export{L as BaseCompileService,I as Command,K as CreateLoader,q as CreatePlugins,M as LoggerSystem,Ge as WebCompileService,Ze as defineConfig,V as extensions,Q as loadOptionalViteAdapter,Ve as prepareWebCompile,U as resolveCLI,z as runRspackBuild,Se as watchRspackBuild};
5
+ `)}getEndTips(e,t){let{gray:n,cyan:r,red:i,green:a,yellow:o}=v,{errorsCount:s=-1,warningsCount:c=-1}=e,l=(t/1e3).toFixed(2);return n(s>0?`${r(U.name)} compiled with${i(` ${s} error`)}`:c>0?`compile ${a(`success`)} and with ${o(`${c} warning`)}, time: ${l}s`:`compile ${a(`success`)}, time: ${l}s.`)}getTableInfo(e){let{assets:t}=e;if(!t||t.length===0)return;let n=new S,r=this.userConfig?.build?.gzip??!1,i=0,a=0,o=!1;for(let e=0;e<t.length;e++){let{name:s,size:c,related:l,info:u}=t[e];if(u.development)continue;let d=r&&h(l)?l.find(e=>e.type===`gzipped`).size:0;if(i+=c,a+=d,t.length>20&&e>=4&&e<t.length-1-4){o||(o=!0,n.cell(`name`,`....`),n.cell(`size`,`....`),r&&n.cell(`gzip`,`....`),n.newRow());continue}n.cell(`name`,s),n.cell(`size`,x(c)),r&&n.cell(`gzip`,x(d)),n.newRow()}return n.pushDelimeter(),n.cell(`name`,`There are ${t.length} files`),n.cell(`size`,x(i)),r&&n.cell(`gzip`,x(a)),n.newRow(),v.cyan.dim(n.toString().trim())}getHostList(){let{userConfig:e,compiler:t}=this,{devServer:n}=t.options,r=n?.server===`https`||typeof n?.server==`object`,i=Number(n?.port),a=[],s=``,c=Object.values(b.networkInterfaces());if(e){s=e.build?.base??``,(!s||s===`auto`)&&(s=`/`);let t=Object.keys(e?.pages||{})[0];t&&t!==`index`?s=o.join(s,`${t}.html`):s.endsWith(`/`)||(s+=`/`)}for(let e of c){let{address:t}=e?.find(e=>e.family===`IPv4`)||{};t&&a.push(t)}a.sort((e,t)=>{let n=e.split(`.`),r=t.split(`.`);for(let[t]of n.entries())if(e[t]!==r[t])return Number(r[t])-Number(e[t]);return 0});let l=a.indexOf(`127.0.0.1`);return l!==-1&&(a.splice(l,1),a.unshift(`localhost`)),a=a.map(e=>(r?(e=`https://${e}`,i!==443&&(e=e+`:`+i)):(e=`http://`+e,i!==80&&(e=e+`:`+i)),new URL(s,e).href)),a}initDevHook(){let{compiler:e}=this,t=this.getHostList(),{blue:n,cyan:r,gray:i}=v;e.hooks.environment.intercept({name:W}),e.hooks.watchRun.intercept({name:W,call:()=>{this.updateStartCompileTime()}}),e.hooks.done.intercept({name:W,call:e=>{console.clear();let a=e.toJson({preset:`errors-warnings`,colors:!0}),{eventArray:o}=L(),{errorsCount:s=0,warningsCount:c=0}=a;if(s>0)console.log(this.getError(a)),console.log();else{c>0&&(console.log(this.getWarn(a)),console.log()),o.length>0&&(console.log(o.map(e=>e).join(`
6
+ `)),console.log());let{name:e,version:s}=U,l=`${r(`${e} v${s}`)} entry address:\n\n`;for(let e of t)l+=n(` ${e}\n`);console.log(i(l))}console.log(this.getEndTips(a,this.getCurrentEndCompileTime())),console.log()}})}initProdHook(){let{compiler:e}=this,t;e.hooks.environment.intercept({name:W,call:()=>{console.log(v.gray(`start build...`)),this.updateStartCompileTime()}}),e.hooks.done.intercept({name:W,call:e=>{t=e.toJson({preset:`normal`,colors:!0,assetsSort:`size`})}}),e.cache.hooks.shutdown.intercept({name:W,done:()=>{let{errorsCount:e=0,warningsCount:n=0}=t;console.log(),e>0?(console.log(this.getError(t)),console.log()):(n>0&&(console.log(this.getWarn(t)),console.log()),console.log(this.getTableInfo(t)),console.log()),console.log(this.getEndTips(t,this.getCurrentEndCompileTime()))}})}};const K=`@rspack/ikaros-cdn-plugin`,_e=/:([a-z]+)/gi;function ve(e){return e.filter(e=>!e.cssOnly).reduce((e,t)=>(e[t.name]=t.var||t.name,e),{})}var ye=class{constructor(e){this.isDev=!1,this.versionCache=new Map,this.options={prodUrl:`https://unpkg.com/:name@:version/:path`,devUrl:`:name/:path`,crossOrigin:!1,...e}}apply(e){this.isDev=e.options.mode===`development`,e.hooks.compilation.tap(K,e=>{r.HtmlRspackPlugin.getCompilationHooks(e).alterAssetTags.tapAsync(K,(e,t)=>{try{this.injectResources(e),t(null,e)}catch(e){t(e)}})})}injectResources(e){let t=this.options.modules,n=[];t.forEach(e=>{this.getStyles(e).forEach(e=>{n.push({tagName:`link`,voidTag:!0,attributes:{rel:`stylesheet`,href:e,...this.options.crossOrigin&&{crossorigin:this.options.crossOrigin}}})})}),t.filter(e=>!e.cssOnly).forEach(e=>{this.getScripts(e).forEach(e=>{n.push({tagName:`script`,voidTag:!0,attributes:{src:e,...this.options.crossOrigin&&{crossorigin:this.options.crossOrigin}}})})}),e.assetTags&&(e.assetTags.styles.unshift(...n.filter(e=>e.tagName===`link`)),e.assetTags.scripts.unshift(...n.filter(e=>e.tagName===`script`)))}getStyles(e){let t=[...e.styles||[]];return e.style&&t.unshift(e.style),t.map(t=>this.generateUrl(e,t))}getScripts(e){let t=[...e.paths||[]];return e.path&&t.unshift(e.path),t.map(t=>this.generateUrl(e,t))}joinUrl(e,t){return e=e.replace(/\/+$/,``),t=t.replace(/^\/+/,``),`${e}/${t}`}generateUrl(e,t){let n=this.isDev?e.devUrl||this.options.devUrl:e.prodUrl||this.options.prodUrl;return n.match(_e)?n.replace(_e,(n,r)=>{switch(r){case`name`:return e.name;case`version`:return e.version||this.getModuleVersion(e.name);case`path`:return t;default:return n}}):this.joinUrl(n,t)}getModuleVersion(t){let n=this.versionCache.get(t);if(n)return n;try{let n=e(d.join(process.cwd(),`node_modules`))(d.join(t,`package.json`)).version;return this.versionCache.set(t,n),n}catch{return console.warn(v.yellow(`[${K}] 无法获取模块 "${t}" 的版本信息`)),`latest`}}},be=class{constructor(e){this.options=e}createSourceMapPlugin(){let{isDev:e,userConfig:t}=this.options;if(e)return new r.EvalSourceMapDevToolPlugin({columns:!1,module:!0});if(t?.build?.sourceMap??!1)return new r.SourceMapDevToolPlugin({test:[/.js/,/.mjs/],filename:`[file].map[query]`})}createCssExtractPlugin(){if(!this.options.isDev)return new r.CssExtractRspackPlugin({filename:this.joinAssetsDir(`assets/css/[contenthash].css`),ignoreOrder:!0})}createDoctorPlugin(){let{isDev:e,userConfig:t}=this.options;if(!(e||!t?.build?.outReport))return new T}createGzipPlugin(){let{isDev:e,userConfig:t}=this.options;if(!(e||!t?.build?.gzip))return new ee}createCdnPlugin(){let{cdnOptions:e}=this.options.userConfig??{};if(!(!e||g(e.modules)))return new ye(e)}createModuleFederationPlugin(){let e=this.options.userConfig?.moduleFederation;if(e)return h(e)?e.map(e=>new E(e)):new E(e)}createDependencyCyclePlugin(){let{isDev:e,userConfig:t}=this.options;if(!(e||!t?.build?.dependencyCycleCheck))return new r.CircularDependencyRspackPlugin({exclude:/node_modules/,failOnError:!1})}joinAssetsDir(...e){return[this.options.assetsDir,...e].join(`/`).replace(/\/+/g,`/`)}};const q={target:O.enum([`pc`,`mobile`]).optional().default(`pc`),pages:O.custom().optional(),enablePages:O.union([O.array(O.string()),O.literal(!1)]).optional(),define:O.custom().optional(),build:O.object({base:O.string().optional().default(`/`),assetsDir:O.string().optional(),sourceMap:O.boolean().optional().default(!1),outDirName:O.string().optional().default(`dist`)}).optional(),resolve:O.object({alias:O.record(O.string(),O.string()).optional(),extensions:O.array(O.string()).optional()}).optional(),server:O.object({port:O.number().int().min(1024).max(65535).optional()}).optional(),electron:O.unknown().optional()},xe=O.object({bundler:O.custom().optional().default(`rspack`).refine(e=>e===`rspack`,{message:`bundler must be 'rspack' for rspack config`}),...q,moduleFederation:O.union([O.custom(),O.array(O.custom())]).optional(),plugins:O.union([O.custom(),O.array(O.custom())]).optional(),loaders:O.array(O.custom()).optional(),experiments:O.custom().optional(),cdnOptions:O.custom().optional(),server:O.object({port:O.number().int().min(1024).max(65535).optional(),proxy:O.custom().optional(),https:O.union([O.boolean(),O.record(O.string(),O.unknown())]).optional().default(!1)}).optional(),css:O.object({lightningcssOptions:O.record(O.string(),O.unknown()).optional(),sourceMap:O.boolean().optional(),lessOptions:O.record(O.string(),O.unknown()).optional(),sassOptions:O.record(O.string(),O.unknown()).optional(),stylusOptions:O.record(O.string(),O.unknown()).optional()}).optional(),build:O.object({base:O.string().optional().default(`/`),assetsDir:O.string().optional(),gzip:O.boolean().optional().default(!1),sourceMap:O.boolean().optional().default(!1),outDirName:O.string().optional().default(`dist`),outReport:O.boolean().optional().default(!1),cache:O.boolean().optional().default(!1),dependencyCycleCheck:O.boolean().optional().default(!1)}).optional()}),Se=O.object({bundler:O.literal(`vite`),...q,server:O.object({port:O.number().int().min(1024).max(65535).optional(),proxy:O.record(O.string(),O.unknown()).optional(),https:O.union([O.boolean(),O.record(O.string(),O.unknown())]).optional()}).optional(),vite:O.object({plugins:O.unknown().optional()}).strict().optional()}).passthrough().superRefine((e,t)=>{for(let n of[`plugins`,`loaders`,`experiments`,`cdnOptions`,`moduleFederation`,`css`]){let r=e;n in r&&r[n]!==void 0&&t.addIssue({code:O.ZodIssueCode.custom,path:[n],message:`bundler='vite' 时不支持 ${String(n)},请使用 vite.plugins 或 Vite 原生配置能力`})}}),J=O.union([Se,xe]),Y=(e,t)=>t?f(e,`env`,`.env.${t}`):f(e,`env`,`.env`),Ce=async(e,t)=>{let{warning:n,emitEvent:r}=L();if(!await k.pathExists(f(e,`env`)))return r(n({text:`env folder not found`,onlyText:!0})),!1;if(t){if(!await k.pathExists(Y(e,t)))return r(n({text:`.env.${t} file not found`,onlyText:!0})),!1}else return await k.pathExists(Y(e))?!0:(r(n({text:`.env file not found`,onlyText:!0})),!1);return!0},we=async(e,t)=>await Ce(e,t)?t?re({path:Y(e,t),quiet:!0}).parsed??{}:re({path:Y(e),quiet:!0}).parsed??{}:{};async function Te(e,t){let{code:n,errors:r}=await ae(e,await ne(e,`utf-8`),{lang:t?`ts`:`js`});if(r.length>0)throw Error(`Transformation failed: `+r.map(e=>e.message).join(`, `));return{code:n}}async function Ee(e,t){let n=`${e}.timestamp-${Date.now()}-${Math.random().toString(16).slice(2)}`,r=`${n}.mjs`,i=`${m(n)}.mjs`;await D.writeFile(r,t);try{return(await import(i)).default}finally{await D.unlink(r)}}async function De(e,t=!1){let{code:n}=await Te(e,t);return Ee(e,n)}const X=new Map;X.set(`.mjs`,async e=>(await import(m(e).href)).default),X.set(`.ts`,async e=>await De(e,!0)),X.set(`.json`,async e=>await k.readJson(e)),X.set(`.yaml`,async e=>ie(await D.readFile(e,`utf8`)));async function Oe({configFile:e,context:t}){let n,r=t??process.cwd(),i=`ikaros.config`,a=[`ts`,`mjs`,`json`,`yaml`].map(e=>`${l(r,i)}.${e}`),o=(await Promise.all(a.map(e=>k.pathExists(e)))).findIndex(Boolean);if(!(o<0)){if(n=c(a[o]),r=u(r,`${i}${n}`),e&&(r=s(e),n=c(e)),!X.has(n))throw Error(`No configuration file ! `);return X.get(n)(r)}}let Z=function(e){return e.SERVER=`server`,e.BUILD=`build`,e}({});async function ke(t){let{command:n,options:r,configFile:i,onBuildStatus:a}=t,o=t.context??process.cwd(),s=e(l(o,`./`)),c=(...e)=>l(o,...e),u=e=>s(e),d=e=>{try{return s.resolve(e)}catch{return}},f=await Ae(c),p=await je(r,o);return{context:o,command:n,options:r,env:p,userConfig:await Me({configFile:i,context:o,options:r,env:p,command:n}),contextPkg:f,resolveContext:c,loadContextModule:u,resolveContextModule:d,contextRequire:s,isElectron:r.platform===`desktopClient`,configFile:i,onBuildStatus:a}}async function Ae(e){let t=e(`package.json`);try{await D.access(t,te.constants.F_OK)}catch{return}return JSON.parse(await D.readFile(t,{encoding:`utf8`}))}async function je(e,t){let{platform:n,mode:r}=e,i={PLATFORM:n,MODE:r},a=await we(t,r);return{...i,...a}}async function Me(e){let{configFile:t,context:n,options:r,env:a,command:o}=e,s=await Oe({configFile:t,context:n});if(s){if(i(s)){let e={mode:r.mode??``,env:{...a,PLATFORM:r.platform,MODE:r.mode??a?.MODE},command:o};return J.parse(await s(e))}if(_(s))return J.parse(s)}}const Ne=e=>{let{isVue:t,isReact:n}=e;return t?{noParse:/^(vue|vue-router|vuex|vuex-router-sync)$/}:n?{noParse:e=>/(react|react-dom|react-is)\.production\.min\.js$/.test(e),env:{REACT_APP_ENABLE_DEVTOOLS:!1}}:{env:void 0,noParse:void 0}},Pe=e=>e===Z.SERVER?{minimize:!1,removeAvailableModules:!1,removeEmptyChunks:!1,splitChunks:!1}:{minimize:!0,minimizer:[new r.LightningCssMinimizerRspackPlugin,new r.SwcJsMinimizerRspackPlugin],splitChunks:{chunks:`all`,minSize:3e4,minChunks:1,maxAsyncRequests:5,maxInitialRequests:3,cacheGroups:{vendor:{test:/[\\/]node_modules[\\/]/,name:`vendors`,priority:10,chunks:`all`},common:{name:`common`,minChunks:2,priority:5,reuseExistingChunk:!0}}}},Fe=e=>{if(e.command!==Z.SERVER&&e.userConfig?.build?.cache)return{cache:!0,experiments:{cache:{type:`persistent`}}}},Ie=e=>{let{userConfig:t,isElectron:n,resolveContext:r}=e,i=t?.build?.outDirName;if(n){let e=t?.electron,n=r(`dist/electron/renderer`);return e?.build?.outDir?l(r(e.build.outDir),`renderer`):n}return a(i)?r(i):r(`dist`)},Q=(e,t)=>[e,t].filter(Boolean).join(`/`).replace(/\/+/g,`/`),Le=e=>{let{command:t,mode:n,env:r,context:i,contextPkg:a,userConfig:o,pages:s,browserslist:c,base:u,port:d,isElectron:f,resolveContext:p}=e,m=t===Z.SERVER,h=m?`development`:`production`,g=new V({env:h,mode:n}),_=new H({env:h,mode:n}),{entry:v,plugins:y}=new me({pages:s,enablePages:o?.enablePages}).create(),{env:b,noParse:x}=Ne({isVue:e.isVue,isReact:e.isReact}),S=g.useDefaultResourceLoader().useDefaultScriptLoader(o?.experiments).useDefaultCssLoader(o?.css).add(o?.loaders).end(),C=o?.build?.assetsDir??``,w=new be({command:t,userConfig:o,isDev:m,assetsDir:C}),T=_.useDefaultEnvPlugin({extEnv:{...o?.define},frameworkEnv:b,env:r}).useCopyPlugin().add(y).add(new ge).add(w.createSourceMapPlugin()).add(w.createCssExtractPlugin()).add(w.createDoctorPlugin()).add(w.createGzipPlugin()).add(w.createCdnPlugin()).add(w.createModuleFederationPlugin()).add(w.createDependencyCyclePlugin()).add(o?.plugins).end();return{mode:h,context:i,entry:v,target:f?`electron-renderer`:[`web`,`es2015`,`browserslist:${c}`],externals:o?.cdnOptions?.modules?ve(o.cdnOptions.modules):void 0,resolve:{alias:{"@":p(`src`),...o?.resolve?.alias},extensions:o?.resolve?.extensions||M,modules:[`node_modules`,p(`node_modules`),P(`node_modules`)]},output:{clean:!m,path:Ie({userConfig:o,isElectron:f,resolveContext:p}),publicPath:f&&!m?`./`:u,filename:m?`[name].js`:Q(C,`assets/js/[contenthash:8].js`),chunkFilename:m?`[name].chunk.js`:Q(C,`assets/js/[contenthash:8].chunk.js`),cssFilename:m?`[name].css`:Q(C,`assets/css/[contenthash:8].css`),cssChunkFilename:m?`[name].chunk.css`:Q(C,`assets/css/[contenthash:8].chunk.css`),chunkLoadingGlobal:`${a?.name||`ikaros`}_chunk`,pathinfo:!1},optimization:Pe(t),stats:`none`,watchOptions:{aggregateTimeout:500,ignored:/node_modules/},module:{rules:S,noParse:x},plugins:T,devServer:{hot:!0,port:d,server:(()=>{let e=o?.server?.https;return e?e===!0?`https`:{type:`https`,options:e}:`http`})(),allowedHosts:`all`,proxy:o?.server?.proxy,historyApiFallback:{rewrites:[{from:/\.(js|css|json|png|jpe?g|gif|svg|ico|woff2?|eot|ttf|otf|mp4|webm|ogg|mp3|wav|flac|aac|map)(\?.*)?$/,to:e=>e.parsedUrl.pathname},{from:RegExp(`^${u}`),to:l(u,`index.html`)}]},headers:{"Access-Control-Allow-Origin":`*`},static:{directory:p(`public`),publicPath:u},client:{logging:`none`,overlay:{errors:!0,warnings:!1,runtimeErrors:!1},webSocketURL:`auto://0.0.0.0:${d}/ws`}},experiments:{css:!0},...Fe({command:t,userConfig:o})}},Re=e=>{let t=`Build failed with errors.
7
+ `;return e.toString({chunks:!1,colors:!0}).split(/\r?\n/).forEach(e=>{t+=` ${e}\n`}),t},ze=(e,t)=>{let{onBuildStatus:n}=t??{};return new Promise((t,i)=>{let a=r(e);a.run((e,r)=>{a.close(a=>{let o=e||a;if(o)return n?.({success:!1,message:o.message||`build error`}),i(o);if(r?.hasErrors()){let e=Re(r);return n?.({success:!1,message:e}),i(Error(e))}let s=r?.toString({chunks:!1,colors:!0});return n?.({success:!0,message:s}),t(s)})})})},Be=async(e,t)=>{let{port:n,onBuildStatus:i}=t??{},a=r(e),o=new oe(e.devServer,a);await new Promise((e,t)=>{o.startCallback(r=>r?(i?.({success:!1,port:n,message:r.message}),t(r)):(i?.({success:!0,port:n}),e()))})},Ve=(e,t)=>{let{onBuildStatus:n,...i}=t??{};return new Promise((t,a)=>{r(e).watch({ignored:/node_modules/,aggregateTimeout:300,poll:!1,...i},(e,r)=>{if(e)return n?.({success:!1,message:e.message||`watch build error`}),a(e);if(r?.hasErrors()){let e=Re(r);return n?.({success:!1,message:e}),a(Error(e))}let i=r?.toString({chunks:!1,colors:!0});return n?.({success:!0,message:i}),t(i)})})};var He=class{constructor(){this.name=`rspack`}createConfig(e){return Le({command:e.command===`server`?Z.SERVER:Z.BUILD,mode:e.mode,env:e.env,context:e.context,contextPkg:e.contextPkg,userConfig:e.userConfig,pages:e.pages,browserslist:e.browserslist,base:e.base,port:e.port,isElectron:e.isElectron,isVue:e.isVue,isReact:e.isReact,resolveContext:e.resolveContext})}async runDev(e,t){await Be(e,{port:t.port,onBuildStatus:t.onBuildStatus})}async runBuild(e,t){return ze(e,{onBuildStatus:t.onBuildStatus})}};function Ue(e){let t=Number(process.versions.node.split(`.`)[0]);if(Number.isFinite(t)&&t<e){let t=v.bgRed.white(` ERROR `);process.stderr.write(`${t} Node.js version must be greater than or equal to v${e}! (current: v${process.versions.node})\n\n`),process.exit(1)}}function We(e){let t=Number(process.versions.node.split(`.`)[0]);if(Number.isFinite(t)&&t<e)throw Error(`Node.js >= ${e} is required (current: v${process.versions.node})`)}const Ge=()=>{let e=`@ikaros-cli/ikaros-bundler-vite`,t=[`你启用了 bundler='vite',但未安装可选依赖 ${e}。`,``,`请安装后重试:`,` pnpm add -D ${e}`];return Error(t.join(`
8
+ `))};var Ke=class{constructor(e){this.name=`vite`,this.loadContextModule=e.loadContextModule}ensureAdapter(){if(this.adapter)return this.adapter;We(22);try{let e=this.loadContextModule(`@ikaros-cli/ikaros-bundler-vite`),t=(e.default??e).ViteBundlerAdapter;if(typeof t!=`function`)throw Ge();return this.adapter=new t,this.adapter}catch(e){throw e instanceof Error&&e.message.includes(`bundler='vite'`)?e:Ge()}}createConfig(e){return this.ensureAdapter().createConfig(e)}async runDev(e,t){return this.ensureAdapter().runDev(e,t)}async runBuild(e,t){return this.ensureAdapter().runBuild(e,t)}};function qe(e){let{bundler:t,loadContextModule:n}=e;switch(t){case`vite`:return new Ke({loadContextModule:n});default:return new He}}const Je=e=>{let t=e===`mobile`,n=[`defaults`];return t?n.push(`IOS >= 16`,`Chrome >= 80`):n.push(`>0.2%`,`Chrome >= 90`,`Safari >= 16`,`last 2 versions`,`not dead`),n.join(`,`)},Ye=(e,t)=>t?{index:{html:e(`src/renderer/index.html`),entry:e(`src/renderer/index`)}}:{index:{html:e(`index.html`),entry:e(`src/index`)}},Xe=async e=>{let{command:t,context:n,resolveContext:r,getUserConfig:i,isElectron:a}=e,o=await i(),s=o?.build?.base??`/`;if(t===Z.SERVER&&/^https?:/.test(s)){let e=v.cyan(`build.base`);throw Error(`本地开发时 ${e} 不应该为外部 Host!`)}let c=o?.target??`pc`,l=o?.pages??Ye(r,!!a),u=o?.server?.port??await se(`8080`),d=!1,f=!1;try{let[e,t]=await Promise.all([z(`react`,n),z(`vue`,n)]);d=t,f=e}catch{}return{userConfig:o,base:s,target:c,pages:l,port:u,browserslist:Je(c),isVue:d,isReact:f}};var Ze=class{constructor(){this.name=`web`}async resolvePreConfig(e){return Xe({command:e.command,context:e.context,resolveContext:e.resolveContext,getUserConfig:async()=>e.userConfig,isElectron:e.isElectron})}async compile(e,t){let{command:n,preConfig:r,compileContext:i}=t,a=await e.createConfig({command:n,mode:i.options.mode,env:i.env,context:i.context,contextPkg:i.contextPkg,userConfig:r.userConfig,pages:r.pages,base:r.base,port:r.port,browserslist:r.browserslist,isElectron:i.isElectron,isVue:r.isVue,isReact:r.isReact,resolveContext:i.resolveContext});n===`server`?await e.runDev(a,{port:r.port,onBuildStatus:i.onBuildStatus}):await e.runBuild(a,{onBuildStatus:i.onBuildStatus})}};function Qe(e){switch(e){case`desktopClient`:return $e();default:return new Ze}}function $e(){let e,t=async()=>e||(e=await et(),e);return{name:`desktopClient`,async resolvePreConfig(e){return(await t()).resolvePreConfig(e)},async compile(e,n){return(await t()).compile(e,n)}}}async function et(){let t=`@ikaros-cli/ikaros-platform-desktop-client`,n=e=>{let n=[`你启用了 platform='desktopClient',但未安装可选依赖 ${t}。`,``,`请安装后重试:`,` pnpm add -D ${t}`];if(e){let t=e instanceof Error?e.message:String(e);n.push(``,`原始错误: ${t}`)}return Error(n.join(`
9
+ `))},r;try{r=await import(m(e(l(process.cwd(),`./`)).resolve(t)).href)}catch(e){throw n(e)}let i=(r.default??r).ElectronDesktopPlatformInstance;if(!i||typeof i.resolvePreConfig!=`function`)throw Error([`${t} 已安装但加载失败:未找到 ElectronDesktopPlatformInstance 导出。`,`请确认安装的版本与 @ikaros-cli/ikaros 兼容(需 >=3.0)。`].join(`
10
+ `));return i}async function tt(e){let t=await ke(e),n=Qe(t.options.platform),r=await n.resolvePreConfig(t),i={...t,userConfig:r.userConfig},a=qe({bundler:i.userConfig?.bundler??`rspack`,loadContextModule:i.loadContextModule});await n.compile(a,{command:i.command,preConfig:r,compileContext:i})}const nt={WEB:`web`,DESKTOPCLIENT:`desktopClient`,ELECTRON:`desktopClient`},rt=[new t(`-m, --mode <name>`,`Environment variable`),new t(`-p, --platform <type>`,`build platform type`).default(nt.WEB).choices(Object.values(nt))],$=async e=>{try{await tt(e)}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`${t}\n`),process.exit(1)}},it=e=>{let t=e.command(Z.SERVER,{isDefault:!0}).description(`Start local develop serve`).action(async e=>{await $({command:Z.SERVER,options:e})}),n=e.command(Z.BUILD).description(`Start build`).action(async e=>{await $({command:Z.BUILD,options:e})});for(let e of rt)t.addOption(e),n.addOption(e)},at=e=>e;Ue(22),n.version(A,`-v, --version`),it(n),n.parse();export{Z as Command,V as CreateLoader,H as CreatePlugins,L as LoggerSystem,He as RspackAdapter,Ke as ViteAdapterLoader,Ze as WebPlatformAdapter,Ue as assertNodeVersion,We as checkNodeVersion,qe as createBundlerAdapter,ke as createCompileContext,Qe as createPlatformAdapter,at as defineConfig,M as extensions,P as resolveCLI,Xe as resolveWebPreConfig,tt as runCompile,ze as runRspackBuild,Ve as watchRspackBuild};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikaros-cli/ikaros",
3
- "version": "2.1.3",
3
+ "version": "2.2.1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -18,7 +18,8 @@
18
18
  "scripts": {
19
19
  "dev": "tsdown --watch",
20
20
  "dts": "tsdown --dts",
21
- "build": "tsdown"
21
+ "build": "tsdown",
22
+ "test": "vitest run"
22
23
  },
23
24
  "keywords": [
24
25
  "vue",
@@ -42,35 +43,35 @@
42
43
  "npm": ">=9.5.0"
43
44
  },
44
45
  "dependencies": {
45
- "@module-federation/enhanced": "^0.22.1",
46
- "@rsdoctor/rspack-plugin": "^1.4.0",
47
- "@rspack/core": "^1.7.2",
48
- "@rspack/dev-server": "^1.1.5",
46
+ "@module-federation/enhanced": "^2.0.1",
47
+ "@rsdoctor/rspack-plugin": "^1.5.3",
48
+ "@rspack/core": "^1.7.7",
49
+ "@rspack/dev-server": "^1.2.1",
49
50
  "chalk": "^5.6.2",
50
51
  "cli-cursor": "^5.0.0",
51
- "commander": "^14.0.2",
52
- "compression-webpack-plugin": "^11.1.0",
53
- "css-loader": "^7.1.2",
52
+ "commander": "^14.0.3",
53
+ "compression-webpack-plugin": "^12.0.0",
54
+ "css-loader": "^7.1.4",
54
55
  "detect-port": "^2.1.0",
55
- "dotenv": "^17.2.3",
56
+ "dotenv": "^17.3.1",
56
57
  "easy-table": "^1.2.0",
57
- "es-toolkit": "^1.43.0",
58
- "fs-extra": "^11.3.3",
59
- "glob": "^13.0.0",
60
- "less-loader": "^12.3.0",
61
- "listr2": "^9.0.5",
62
- "ora": "^9.0.0",
63
- "oxc-transform": "^0.108.0",
58
+ "es-toolkit": "^1.45.1",
59
+ "fs-extra": "^11.3.4",
60
+ "glob": "^13.0.6",
61
+ "less-loader": "^12.3.1",
62
+ "listr2": "^10.2.1",
63
+ "ora": "^9.3.0",
64
+ "oxc-transform": "^0.116.0",
64
65
  "picocolors": "^1.1.1",
65
66
  "pretty-bytes": "^7.1.0",
66
- "sass-loader": "^16.0.6",
67
- "stylus-loader": "^8.1.2",
67
+ "sass-loader": "^16.0.7",
68
+ "stylus-loader": "^8.1.3",
68
69
  "vue-style-loader": "^4.1.3",
69
70
  "yaml": "^2.8.2",
70
- "zod": "^4.3.5"
71
+ "zod": "^4.3.6"
71
72
  },
72
73
  "devDependencies": {
73
74
  "@types/fs-extra": "^11.0.4",
74
- "vitest": "^4.0.17"
75
+ "vitest": "^4.0.18"
75
76
  }
76
77
  }