@nasti-toolchain/nasti 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { InputOptions, OutputOptions, RenderedChunk } from 'rolldown';
2
+ import { IncomingMessage, ServerResponse } from 'node:http';
2
3
 
3
4
  type LogType = 'error' | 'warn' | 'info';
4
5
  type LogLevel = LogType | 'silent';
@@ -95,10 +96,25 @@ interface EnvironmentOptions {
95
96
  */
96
97
  consumer?: 'client' | 'server';
97
98
  /**
98
- * 该环境的构建入口(相对 root)。client 环境忽略此项(入口从 index.html
99
- * 提取);非 client 环境**只有声明了 entry 才会被 `nasti build` 构建**。
99
+ * 该环境的构建入口(相对 root)。client 默认从 HTML 提取;显式配置后可覆盖。
100
+ * client 环境只有声明 entry 或 driver 才会被 `nasti build` 构建。
100
101
  */
101
102
  entry?: string | string[];
103
+ /**
104
+ * HTML 入口(相对 root),仅 client consumer 使用。默认 `index.html`。
105
+ * Electron renderer 会把 `electron.renderer` 映射到这里。
106
+ */
107
+ html?: string;
108
+ /**
109
+ * 是否参与生产构建。默认 true;设为 false 可跳过默认 client,构建纯多环境应用。
110
+ * 仅影响 `nasti build`,不影响 dev server 中环境实例的可见性。
111
+ */
112
+ buildEnabled?: boolean;
113
+ /**
114
+ * 外部环境编译驱动标识。声明后由插件的 `createEnvironmentDriver` 提供实际实现,
115
+ * 可用于接入 Rspeedy 等不基于 Rolldown 的构建系统。
116
+ */
117
+ driver?: string;
102
118
  /** per-env 路径解析(client 默认含 'browser' condition;server 走 node conditions) */
103
119
  resolve?: ResolveConfig;
104
120
  /** per-env 构建覆盖(未设置的字段回退 top-level build) */
@@ -107,8 +123,14 @@ interface EnvironmentOptions {
107
123
  /** 解析后的环境配置 */
108
124
  interface ResolvedEnvironmentOptions {
109
125
  consumer: 'client' | 'server';
110
- /** client 环境的构建入口(绝对路径);client 恒为 [] */
126
+ /** 是否参与生产构建 */
127
+ buildEnabled: boolean;
128
+ /** 环境构建入口(绝对路径);client 未显式配置时为空并从 HTML 提取 */
111
129
  entry: string[];
130
+ /** HTML 入口绝对路径(仅 client consumer 有值) */
131
+ html?: string;
132
+ /** 外部环境编译驱动标识 */
133
+ driver?: string;
112
134
  resolve: Required<ResolveConfig>;
113
135
  build: Required<BuildConfig>;
114
136
  }
@@ -217,10 +239,16 @@ interface CssConfig {
217
239
  interface NastiPlugin {
218
240
  name: string;
219
241
  enforce?: 'pre' | 'post';
242
+ /** 必须在当前插件 setup 前完成 setup 的插件名 */
243
+ pre?: string[];
244
+ /** 必须在当前插件 setup 后完成 setup 的插件名 */
245
+ post?: string[];
220
246
  apply?: 'build' | 'serve' | ((config: ResolvedConfig, env: {
221
247
  mode: string;
222
248
  command: string;
223
249
  }) => boolean);
250
+ /** 插件初始化与跨插件 API 注册;每次 resolveConfig 只执行一次 */
251
+ setup?: (api: PluginApi) => void | Promise<void>;
224
252
  buildStart?: (this: PluginContext) => void | Promise<void>;
225
253
  buildEnd?: (this: PluginContext, error?: Error) => void | Promise<void>;
226
254
  /**
@@ -272,6 +300,16 @@ interface NastiPlugin {
272
300
  * 插件管线。未声明时插件应用于所有环境(与 Vite 默认一致)。
273
301
  */
274
302
  applyToEnvironment?: (environment: EnvironmentInstance) => boolean;
303
+ /**
304
+ * 为声明了 `environment.options.driver` 的环境提供外部编译驱动。
305
+ * 一个环境只能被一个插件接管;返回多个驱动会报错。
306
+ */
307
+ createEnvironmentDriver?: (environment: EnvironmentInstance, api: PluginApi) => EnvironmentDriver | null | undefined | Promise<EnvironmentDriver | null | undefined>;
308
+ /**
309
+ * 所有环境构建完成后的 app 级收尾钩子,用于跨环境聚合产物。
310
+ * Vue Lynx 原生后端可在这里组合 background/main-thread bundle。
311
+ */
312
+ afterBuildApp?: (results: Record<string, EnvironmentBuildResult>, api: PluginApi, context: BuildAppContext) => void | Promise<void>;
275
313
  configureServer?: (server: DevServer) => void | (() => void) | Promise<void | (() => void)>;
276
314
  transformIndexHtml?: (html: string) => string | HtmlTagDescriptor[] | {
277
315
  html: string;
@@ -292,6 +330,73 @@ interface PluginContext {
292
330
  */
293
331
  environment?: EnvironmentInstance;
294
332
  }
333
+ type PluginApiKey = string | symbol;
334
+ /** 插件 setup 与环境驱动共享的跨插件 API。 */
335
+ interface PluginApi {
336
+ readonly config: ResolvedConfig;
337
+ readonly logger: Logger;
338
+ expose: <T>(key: PluginApiKey, value: T) => void;
339
+ useExposed: <T>(key: PluginApiKey) => T | undefined;
340
+ }
341
+ interface EnvironmentBuildOutput {
342
+ fileName: string;
343
+ type: string;
344
+ code?: string;
345
+ source?: Uint8Array | string;
346
+ }
347
+ /** 单个环境附加到标准构建结果上的结构化元数据。 */
348
+ interface EnvironmentBuildMetadata {
349
+ entries?: Record<string, string>;
350
+ publicPath?: string;
351
+ manifest?: unknown;
352
+ stats?: unknown;
353
+ }
354
+ /** 外部环境驱动或原生 Rolldown 环境返回的标准构建结果。 */
355
+ interface EnvironmentBuildResult extends EnvironmentBuildMetadata {
356
+ output: EnvironmentBuildOutput[];
357
+ }
358
+ /** app 级 finalizer 写出的聚合产物。 */
359
+ interface AppBuildOutput extends EnvironmentBuildOutput {
360
+ type: 'asset';
361
+ source: Uint8Array | string;
362
+ }
363
+ /**
364
+ * 所有环境完成后提供给 `afterBuildApp` 的只读查询与产物写出接口。
365
+ * Lynx 等多运行时工具链可用它聚合 background/main-thread 结果,而无需读取磁盘目录。
366
+ */
367
+ interface BuildAppContext {
368
+ readonly config: ResolvedConfig;
369
+ readonly results: Readonly<Record<string, EnvironmentBuildResult>>;
370
+ readonly output: readonly AppBuildOutput[];
371
+ getResult: (environmentName: string) => EnvironmentBuildResult | undefined;
372
+ getArtifact: (environmentName: string, fileName: string) => EnvironmentBuildOutput | undefined;
373
+ getEntry: (environmentName: string, entryName: string) => EnvironmentBuildOutput | undefined;
374
+ getManifest: <T = unknown>(environmentName: string) => T | undefined;
375
+ /** 将聚合产物安全地写入 top-level `build.outDir`,并纳入 BuildResult.appOutput。 */
376
+ emitFile: (file: AppBuildOutput) => string;
377
+ }
378
+ /** 外部环境驱动返回的开发服务信息。 */
379
+ interface EnvironmentServeResult {
380
+ localUrls?: string[];
381
+ networkUrls?: string[];
382
+ middleware?: (request: IncomingMessage, response: ServerResponse, next: (error?: unknown) => void) => void;
383
+ }
384
+ interface EnvironmentDriverContext {
385
+ environment: EnvironmentInstance;
386
+ config: ResolvedConfig;
387
+ api: PluginApi;
388
+ logger: Logger;
389
+ }
390
+ interface EnvironmentDriverServeContext extends EnvironmentDriverContext {
391
+ server: DevServer;
392
+ }
393
+ interface EnvironmentDriver {
394
+ name: string;
395
+ build?: (context: EnvironmentDriverContext) => EnvironmentBuildResult | Promise<EnvironmentBuildResult>;
396
+ serve?: (context: EnvironmentDriverServeContext) => EnvironmentServeResult | void | Promise<EnvironmentServeResult | void>;
397
+ watchChange?: (file: string, event: 'add' | 'change' | 'unlink', context: EnvironmentDriverContext) => void | Promise<void>;
398
+ close?: (context: EnvironmentDriverContext) => void | Promise<void>;
399
+ }
295
400
  /**
296
401
  * 环境实例的公共面(核心实现见 core/environment.ts 的 NastiEnvironment)。
297
402
  * 插件经 `this.environment` / `applyToEnvironment(env)` 感知环境。
@@ -303,6 +408,10 @@ interface EnvironmentInstance {
303
408
  config: ResolvedConfig;
304
409
  options: ResolvedEnvironmentOptions;
305
410
  hot: HotChannel;
411
+ /** 声明 driver 后,由插件提供的外部环境编译驱动 */
412
+ driver?: EnvironmentDriver;
413
+ /** 由生产插件登记 entries / manifest / stats,构建完成后合并进环境结果。 */
414
+ setBuildMetadata: (metadata: EnvironmentBuildMetadata) => void;
306
415
  }
307
416
  /**
308
417
  * renderChunk / augmentChunkHash 的 `this`:Rolldown 真实插件上下文的最小可用面。
@@ -312,6 +421,8 @@ interface EnvironmentInstance {
312
421
  interface RenderChunkContext {
313
422
  emitFile: (file: EmittedFile) => string;
314
423
  getFileName: (referenceId: string) => string;
424
+ /** 当前生产钩子所属环境;BG/MT 同为 client consumer 时也可准确区分。 */
425
+ environment: EnvironmentInstance;
315
426
  }
316
427
  interface ResolveIdOptions {
317
428
  isEntry?: boolean;
@@ -359,6 +470,8 @@ interface ModuleNode {
359
470
  acceptedHmrDeps: Set<ModuleNode>;
360
471
  transformResult: TransformResult | null;
361
472
  lastHMRTimestamp: number;
473
+ /** 每次失效递增,防止较慢的旧转换覆盖较新的缓存。 */
474
+ invalidationVersion: number;
362
475
  isSelfAccepting: boolean;
363
476
  /** Environment API:节点所属环境名(per-env 模块图,默认 'client') */
364
477
  environment?: string;
@@ -368,7 +481,8 @@ interface ResolvedConfig {
368
481
  base: string;
369
482
  mode: 'development' | 'production';
370
483
  target: 'web' | 'electron';
371
- framework: 'react' | 'vue' | 'auto';
484
+ /** `auto` 在配置解析阶段已收敛为具体框架 */
485
+ framework: 'react' | 'vue';
372
486
  command: 'build' | 'serve';
373
487
  resolve: Required<ResolveConfig>;
374
488
  plugins: NastiPlugin[];
@@ -400,6 +514,8 @@ interface DevServer {
400
514
  ws: WebSocketServer;
401
515
  /** Environment API:per-env 环境实例(Phase 1 仅 client 有完整运行时) */
402
516
  environments: Record<string, EnvironmentInstance>;
517
+ /** 外部环境驱动启动后返回的服务 URL / middleware 信息 */
518
+ environmentServices: Record<string, EnvironmentServeResult>;
403
519
  listen: (port?: number) => Promise<DevServer>;
404
520
  close: () => Promise<void>;
405
521
  transformRequest: (url: string) => Promise<TransformResult>;
@@ -416,7 +532,12 @@ interface ModuleGraph$1 {
416
532
  getModuleById: (id: string) => ModuleNode | undefined;
417
533
  getModulesByFile: (file: string) => Set<ModuleNode> | undefined;
418
534
  ensureEntryFromUrl: (url: string) => Promise<ModuleNode>;
419
- invalidateModule: (mod: ModuleNode) => void;
535
+ invalidateModule: (mod: ModuleNode, timestamp?: number) => void;
536
+ invalidateModuleAndImporters: (mod: ModuleNode, timestamp?: number) => void;
537
+ getHmrBoundaries: (mod: ModuleNode) => Array<{
538
+ boundary: ModuleNode;
539
+ acceptedVia: ModuleNode;
540
+ }>;
420
541
  invalidateAll: () => void;
421
542
  }
422
543
  interface WebSocketServer {
@@ -482,6 +603,13 @@ interface HmrUpdate {
482
603
  }
483
604
 
484
605
  declare function defineConfig(config: NastiConfig): NastiConfig;
606
+ /**
607
+ * 将 framework:auto 收敛为具体框架。
608
+ *
609
+ * 优先使用源码中的 .vue 文件消除同时安装 React/Vue 时的歧义,其次读取
610
+ * package.json dependencies,最后回退 React 以保持 1.x 默认行为。
611
+ */
612
+ declare function detectFramework(root: string): 'react' | 'vue';
485
613
  /**
486
614
  * Resolve the final configuration by loading file-based config, merging with inline config, and applying plugin hooks.
487
615
  *
@@ -543,8 +671,18 @@ declare class ModuleGraph {
543
671
  setModuleId(mod: ModuleNode, id: string): void;
544
672
  /** 更新模块依赖关系 */
545
673
  updateModuleImports(mod: ModuleNode, importedIds: Set<string>): void;
674
+ /**
675
+ * 用一次转换得到的信息原子更新 import 与 HMR accept 关系。
676
+ * 依赖节点会在真正被浏览器请求前预先创建,这样入口模块先转换时也能建立完整图。
677
+ */
678
+ updateModuleInfo(mod: ModuleNode, importedUrls: Set<string>, acceptedUrls: Set<string>, isSelfAccepting: boolean, expectedInvalidationVersion?: number): Promise<Set<ModuleNode> | null>;
546
679
  /** 使模块的转换缓存失效 */
547
- invalidateModule(mod: ModuleNode): void;
680
+ invalidateModule(mod: ModuleNode, timestamp?: number): void;
681
+ /**
682
+ * 仅失效到 HMR 边界:显式接受依赖的模块本身不会重执行;自接受模块需要失效,
683
+ * 但不再继续影响其 importer。这样既能传播依赖时间戳,也不会隐式重复副作用。
684
+ */
685
+ invalidateModuleAndImporters(mod: ModuleNode, timestamp?: number, seen?: Set<ModuleNode>): void;
548
686
  /** 使所有模块缓存失效 */
549
687
  invalidateAll(): void;
550
688
  /** 获取 HMR 传播边界 - 从变更模块向上遍历找到接受更新的边界 */
@@ -559,6 +697,8 @@ interface NastiEnvironmentInit {
559
697
  mode?: 'dev' | 'build';
560
698
  /** 环境的候选插件(init 时经 applyToEnvironment 过滤) */
561
699
  plugins?: NastiPlugin[];
700
+ /** 配置解析阶段创建的共享插件 API;通常自动从 ResolvedConfig 获取 */
701
+ pluginApi?: PluginApi;
562
702
  }
563
703
  declare class NastiEnvironment implements EnvironmentInstance {
564
704
  readonly name: string;
@@ -567,6 +707,7 @@ declare class NastiEnvironment implements EnvironmentInstance {
567
707
  readonly config: ResolvedConfig;
568
708
  readonly options: ResolvedEnvironmentOptions;
569
709
  readonly hot: HotChannel;
710
+ driver?: EnvironmentDriver;
570
711
  /** applyToEnvironment 过滤后的插件(init() 后可用) */
571
712
  plugins: NastiPlugin[];
572
713
  /** per-env 插件容器(init() 后可用;dev 管线使用) */
@@ -574,10 +715,15 @@ declare class NastiEnvironment implements EnvironmentInstance {
574
715
  /** per-env 模块图(dev 管线使用) */
575
716
  moduleGraph: ModuleGraph;
576
717
  private candidatePlugins;
718
+ private pluginApi;
719
+ private buildMetadata;
577
720
  private initialized;
578
721
  constructor(name: string, config: ResolvedConfig, init?: NastiEnvironmentInit);
579
722
  /** 过滤插件并建 per-env PluginContainer */
580
723
  init(): Promise<void>;
724
+ getDriverContext(): EnvironmentDriverContext;
725
+ setBuildMetadata(metadata: EnvironmentBuildMetadata): void;
726
+ getBuildMetadata(): EnvironmentBuildMetadata;
581
727
  close(): Promise<void>;
582
728
  }
583
729
  /** 按 applyToEnvironment 过滤环境插件(未声明 = 应用于所有环境) */
@@ -585,14 +731,13 @@ declare function resolveEnvironmentPlugins(environment: EnvironmentInstance, plu
585
731
 
586
732
  interface BuildResult {
587
733
  /** client 环境的产物(back-compat:1.x 的 BuildResult 形态) */
588
- output: Array<{
589
- fileName: string;
590
- type: string;
591
- code?: string;
592
- source?: Uint8Array | string;
593
- }>;
734
+ output: EnvironmentBuildOutput[];
594
735
  /** 全部已构建环境的产物(2.0 多环境 builder) */
595
736
  environments?: Record<string, BuildResult['output']>;
737
+ /** 全部环境的完整结果(entries / manifest / stats 等) */
738
+ environmentResults?: Record<string, EnvironmentBuildResult>;
739
+ /** app 级 finalizer 聚合写出的产物(如 `.lynx.bundle`) */
740
+ appOutput?: AppBuildOutput[];
596
741
  }
597
742
  declare function build(inlineConfig?: NastiConfig): Promise<BuildResult>;
598
743
 
@@ -611,6 +756,13 @@ interface ElectronBuildResult {
611
756
  * @throws Error if the configured Electron main entry file does not exist
612
757
  */
613
758
  declare function buildElectron(inlineConfig?: NastiConfig): Promise<ElectronBuildResult>;
759
+ /**
760
+ * 从 Electron 配置派生 renderer 的普通 Web 构建配置。
761
+ *
762
+ * renderer 使用指定 HTML 入口;本地文件加载场景默认把 `/` base 收敛为
763
+ * `./`,避免产物中的 `/assets/*` 被解析到文件系统根目录。
764
+ */
765
+ declare function createElectronRendererConfig(config: ResolvedConfig, inlineConfig?: NastiConfig, overrides?: Pick<NastiConfig, 'build'>): NastiConfig;
614
766
 
615
767
  declare function createServer(inlineConfig?: NastiConfig): Promise<DevServer>;
616
768
 
@@ -624,6 +776,8 @@ interface ElectronDevOptions extends NastiConfig {
624
776
  * @param inlineConfig - Development options; when `inlineConfig.noSpawn` is `true`, only compiles main/preload into `.nasti/` and does not start the Electron process.
625
777
  */
626
778
  declare function startElectronDev(inlineConfig?: ElectronDevOptions): Promise<void>;
779
+ /** 将 renderer HTML 路径转换为 Electron 开发服务器 URL path。 */
780
+ declare function electronRendererDevPath(renderer: string): string;
627
781
 
628
782
  /**
629
783
  * Create a Vite/Rollup plugin that externalizes Electron and Node built-in imports according to the resolved config.
@@ -690,4 +844,4 @@ declare function buildEnvDefine(env: EnvRecord, mode: string, overrides?: Record
690
844
  /** 按环境 consumer 派生 import.meta.env.SSR 的 define 覆盖 */
691
845
  declare function ssrDefineOverrides(consumer: 'client' | 'server'): Record<string, string>;
692
846
 
693
- export { type BuildConfig, type DevServer, type ElectronConfig, type EnvironmentInstance, type EnvironmentOptions, type HmrPayload, type HotChannel, type HotChannelClient, type HotChannelInvokeHandlers, type LogLevel, LogLevels, type LogOptions, type Logger, type ModuleNode, type MonacoCustomWorker, type MonacoEditorLanguageWorker, type MonacoEditorPluginOptions, type NastiConfig, NastiEnvironment, type NastiPlugin, type NastiRolldownOptions, type PluginContext, type RenderChunkContext, type ResolvedConfig, type ResolvedEnvironmentOptions, type TransformResult, build, buildElectron, buildEnvDefine, createDebugger, createLogger, createNoopHotChannel, createServer, createWsHotChannel, defineConfig, electronPlugin, loadEnv, monacoEditorPlugin, printServerUrls, resolveConfig, resolveEnvironmentPlugins, ssrDefineOverrides, startElectronDev };
847
+ export { type AppBuildOutput, type BuildAppContext, type BuildConfig, type BuildResult, type DevServer, type ElectronConfig, type EnvironmentBuildMetadata, type EnvironmentBuildOutput, type EnvironmentBuildResult, type EnvironmentDriver, type EnvironmentDriverContext, type EnvironmentDriverServeContext, type EnvironmentInstance, type EnvironmentOptions, type EnvironmentServeResult, type HmrPayload, type HotChannel, type HotChannelClient, type HotChannelInvokeHandlers, type LogLevel, LogLevels, type LogOptions, type Logger, type ModuleNode, type MonacoCustomWorker, type MonacoEditorLanguageWorker, type MonacoEditorPluginOptions, type NastiConfig, NastiEnvironment, type NastiPlugin, type NastiRolldownOptions, type PluginApi, type PluginApiKey, type PluginContext, type RenderChunkContext, type ResolvedConfig, type ResolvedEnvironmentOptions, type TransformResult, build, buildElectron, buildEnvDefine, createDebugger, createElectronRendererConfig, createLogger, createNoopHotChannel, createServer, createWsHotChannel, defineConfig, detectFramework, electronPlugin, electronRendererDevPath, loadEnv, monacoEditorPlugin, printServerUrls, resolveConfig, resolveEnvironmentPlugins, ssrDefineOverrides, startElectronDev };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { InputOptions, OutputOptions, RenderedChunk } from 'rolldown';
2
+ import { IncomingMessage, ServerResponse } from 'node:http';
2
3
 
3
4
  type LogType = 'error' | 'warn' | 'info';
4
5
  type LogLevel = LogType | 'silent';
@@ -95,10 +96,25 @@ interface EnvironmentOptions {
95
96
  */
96
97
  consumer?: 'client' | 'server';
97
98
  /**
98
- * 该环境的构建入口(相对 root)。client 环境忽略此项(入口从 index.html
99
- * 提取);非 client 环境**只有声明了 entry 才会被 `nasti build` 构建**。
99
+ * 该环境的构建入口(相对 root)。client 默认从 HTML 提取;显式配置后可覆盖。
100
+ * client 环境只有声明 entry 或 driver 才会被 `nasti build` 构建。
100
101
  */
101
102
  entry?: string | string[];
103
+ /**
104
+ * HTML 入口(相对 root),仅 client consumer 使用。默认 `index.html`。
105
+ * Electron renderer 会把 `electron.renderer` 映射到这里。
106
+ */
107
+ html?: string;
108
+ /**
109
+ * 是否参与生产构建。默认 true;设为 false 可跳过默认 client,构建纯多环境应用。
110
+ * 仅影响 `nasti build`,不影响 dev server 中环境实例的可见性。
111
+ */
112
+ buildEnabled?: boolean;
113
+ /**
114
+ * 外部环境编译驱动标识。声明后由插件的 `createEnvironmentDriver` 提供实际实现,
115
+ * 可用于接入 Rspeedy 等不基于 Rolldown 的构建系统。
116
+ */
117
+ driver?: string;
102
118
  /** per-env 路径解析(client 默认含 'browser' condition;server 走 node conditions) */
103
119
  resolve?: ResolveConfig;
104
120
  /** per-env 构建覆盖(未设置的字段回退 top-level build) */
@@ -107,8 +123,14 @@ interface EnvironmentOptions {
107
123
  /** 解析后的环境配置 */
108
124
  interface ResolvedEnvironmentOptions {
109
125
  consumer: 'client' | 'server';
110
- /** client 环境的构建入口(绝对路径);client 恒为 [] */
126
+ /** 是否参与生产构建 */
127
+ buildEnabled: boolean;
128
+ /** 环境构建入口(绝对路径);client 未显式配置时为空并从 HTML 提取 */
111
129
  entry: string[];
130
+ /** HTML 入口绝对路径(仅 client consumer 有值) */
131
+ html?: string;
132
+ /** 外部环境编译驱动标识 */
133
+ driver?: string;
112
134
  resolve: Required<ResolveConfig>;
113
135
  build: Required<BuildConfig>;
114
136
  }
@@ -217,10 +239,16 @@ interface CssConfig {
217
239
  interface NastiPlugin {
218
240
  name: string;
219
241
  enforce?: 'pre' | 'post';
242
+ /** 必须在当前插件 setup 前完成 setup 的插件名 */
243
+ pre?: string[];
244
+ /** 必须在当前插件 setup 后完成 setup 的插件名 */
245
+ post?: string[];
220
246
  apply?: 'build' | 'serve' | ((config: ResolvedConfig, env: {
221
247
  mode: string;
222
248
  command: string;
223
249
  }) => boolean);
250
+ /** 插件初始化与跨插件 API 注册;每次 resolveConfig 只执行一次 */
251
+ setup?: (api: PluginApi) => void | Promise<void>;
224
252
  buildStart?: (this: PluginContext) => void | Promise<void>;
225
253
  buildEnd?: (this: PluginContext, error?: Error) => void | Promise<void>;
226
254
  /**
@@ -272,6 +300,16 @@ interface NastiPlugin {
272
300
  * 插件管线。未声明时插件应用于所有环境(与 Vite 默认一致)。
273
301
  */
274
302
  applyToEnvironment?: (environment: EnvironmentInstance) => boolean;
303
+ /**
304
+ * 为声明了 `environment.options.driver` 的环境提供外部编译驱动。
305
+ * 一个环境只能被一个插件接管;返回多个驱动会报错。
306
+ */
307
+ createEnvironmentDriver?: (environment: EnvironmentInstance, api: PluginApi) => EnvironmentDriver | null | undefined | Promise<EnvironmentDriver | null | undefined>;
308
+ /**
309
+ * 所有环境构建完成后的 app 级收尾钩子,用于跨环境聚合产物。
310
+ * Vue Lynx 原生后端可在这里组合 background/main-thread bundle。
311
+ */
312
+ afterBuildApp?: (results: Record<string, EnvironmentBuildResult>, api: PluginApi, context: BuildAppContext) => void | Promise<void>;
275
313
  configureServer?: (server: DevServer) => void | (() => void) | Promise<void | (() => void)>;
276
314
  transformIndexHtml?: (html: string) => string | HtmlTagDescriptor[] | {
277
315
  html: string;
@@ -292,6 +330,73 @@ interface PluginContext {
292
330
  */
293
331
  environment?: EnvironmentInstance;
294
332
  }
333
+ type PluginApiKey = string | symbol;
334
+ /** 插件 setup 与环境驱动共享的跨插件 API。 */
335
+ interface PluginApi {
336
+ readonly config: ResolvedConfig;
337
+ readonly logger: Logger;
338
+ expose: <T>(key: PluginApiKey, value: T) => void;
339
+ useExposed: <T>(key: PluginApiKey) => T | undefined;
340
+ }
341
+ interface EnvironmentBuildOutput {
342
+ fileName: string;
343
+ type: string;
344
+ code?: string;
345
+ source?: Uint8Array | string;
346
+ }
347
+ /** 单个环境附加到标准构建结果上的结构化元数据。 */
348
+ interface EnvironmentBuildMetadata {
349
+ entries?: Record<string, string>;
350
+ publicPath?: string;
351
+ manifest?: unknown;
352
+ stats?: unknown;
353
+ }
354
+ /** 外部环境驱动或原生 Rolldown 环境返回的标准构建结果。 */
355
+ interface EnvironmentBuildResult extends EnvironmentBuildMetadata {
356
+ output: EnvironmentBuildOutput[];
357
+ }
358
+ /** app 级 finalizer 写出的聚合产物。 */
359
+ interface AppBuildOutput extends EnvironmentBuildOutput {
360
+ type: 'asset';
361
+ source: Uint8Array | string;
362
+ }
363
+ /**
364
+ * 所有环境完成后提供给 `afterBuildApp` 的只读查询与产物写出接口。
365
+ * Lynx 等多运行时工具链可用它聚合 background/main-thread 结果,而无需读取磁盘目录。
366
+ */
367
+ interface BuildAppContext {
368
+ readonly config: ResolvedConfig;
369
+ readonly results: Readonly<Record<string, EnvironmentBuildResult>>;
370
+ readonly output: readonly AppBuildOutput[];
371
+ getResult: (environmentName: string) => EnvironmentBuildResult | undefined;
372
+ getArtifact: (environmentName: string, fileName: string) => EnvironmentBuildOutput | undefined;
373
+ getEntry: (environmentName: string, entryName: string) => EnvironmentBuildOutput | undefined;
374
+ getManifest: <T = unknown>(environmentName: string) => T | undefined;
375
+ /** 将聚合产物安全地写入 top-level `build.outDir`,并纳入 BuildResult.appOutput。 */
376
+ emitFile: (file: AppBuildOutput) => string;
377
+ }
378
+ /** 外部环境驱动返回的开发服务信息。 */
379
+ interface EnvironmentServeResult {
380
+ localUrls?: string[];
381
+ networkUrls?: string[];
382
+ middleware?: (request: IncomingMessage, response: ServerResponse, next: (error?: unknown) => void) => void;
383
+ }
384
+ interface EnvironmentDriverContext {
385
+ environment: EnvironmentInstance;
386
+ config: ResolvedConfig;
387
+ api: PluginApi;
388
+ logger: Logger;
389
+ }
390
+ interface EnvironmentDriverServeContext extends EnvironmentDriverContext {
391
+ server: DevServer;
392
+ }
393
+ interface EnvironmentDriver {
394
+ name: string;
395
+ build?: (context: EnvironmentDriverContext) => EnvironmentBuildResult | Promise<EnvironmentBuildResult>;
396
+ serve?: (context: EnvironmentDriverServeContext) => EnvironmentServeResult | void | Promise<EnvironmentServeResult | void>;
397
+ watchChange?: (file: string, event: 'add' | 'change' | 'unlink', context: EnvironmentDriverContext) => void | Promise<void>;
398
+ close?: (context: EnvironmentDriverContext) => void | Promise<void>;
399
+ }
295
400
  /**
296
401
  * 环境实例的公共面(核心实现见 core/environment.ts 的 NastiEnvironment)。
297
402
  * 插件经 `this.environment` / `applyToEnvironment(env)` 感知环境。
@@ -303,6 +408,10 @@ interface EnvironmentInstance {
303
408
  config: ResolvedConfig;
304
409
  options: ResolvedEnvironmentOptions;
305
410
  hot: HotChannel;
411
+ /** 声明 driver 后,由插件提供的外部环境编译驱动 */
412
+ driver?: EnvironmentDriver;
413
+ /** 由生产插件登记 entries / manifest / stats,构建完成后合并进环境结果。 */
414
+ setBuildMetadata: (metadata: EnvironmentBuildMetadata) => void;
306
415
  }
307
416
  /**
308
417
  * renderChunk / augmentChunkHash 的 `this`:Rolldown 真实插件上下文的最小可用面。
@@ -312,6 +421,8 @@ interface EnvironmentInstance {
312
421
  interface RenderChunkContext {
313
422
  emitFile: (file: EmittedFile) => string;
314
423
  getFileName: (referenceId: string) => string;
424
+ /** 当前生产钩子所属环境;BG/MT 同为 client consumer 时也可准确区分。 */
425
+ environment: EnvironmentInstance;
315
426
  }
316
427
  interface ResolveIdOptions {
317
428
  isEntry?: boolean;
@@ -359,6 +470,8 @@ interface ModuleNode {
359
470
  acceptedHmrDeps: Set<ModuleNode>;
360
471
  transformResult: TransformResult | null;
361
472
  lastHMRTimestamp: number;
473
+ /** 每次失效递增,防止较慢的旧转换覆盖较新的缓存。 */
474
+ invalidationVersion: number;
362
475
  isSelfAccepting: boolean;
363
476
  /** Environment API:节点所属环境名(per-env 模块图,默认 'client') */
364
477
  environment?: string;
@@ -368,7 +481,8 @@ interface ResolvedConfig {
368
481
  base: string;
369
482
  mode: 'development' | 'production';
370
483
  target: 'web' | 'electron';
371
- framework: 'react' | 'vue' | 'auto';
484
+ /** `auto` 在配置解析阶段已收敛为具体框架 */
485
+ framework: 'react' | 'vue';
372
486
  command: 'build' | 'serve';
373
487
  resolve: Required<ResolveConfig>;
374
488
  plugins: NastiPlugin[];
@@ -400,6 +514,8 @@ interface DevServer {
400
514
  ws: WebSocketServer;
401
515
  /** Environment API:per-env 环境实例(Phase 1 仅 client 有完整运行时) */
402
516
  environments: Record<string, EnvironmentInstance>;
517
+ /** 外部环境驱动启动后返回的服务 URL / middleware 信息 */
518
+ environmentServices: Record<string, EnvironmentServeResult>;
403
519
  listen: (port?: number) => Promise<DevServer>;
404
520
  close: () => Promise<void>;
405
521
  transformRequest: (url: string) => Promise<TransformResult>;
@@ -416,7 +532,12 @@ interface ModuleGraph$1 {
416
532
  getModuleById: (id: string) => ModuleNode | undefined;
417
533
  getModulesByFile: (file: string) => Set<ModuleNode> | undefined;
418
534
  ensureEntryFromUrl: (url: string) => Promise<ModuleNode>;
419
- invalidateModule: (mod: ModuleNode) => void;
535
+ invalidateModule: (mod: ModuleNode, timestamp?: number) => void;
536
+ invalidateModuleAndImporters: (mod: ModuleNode, timestamp?: number) => void;
537
+ getHmrBoundaries: (mod: ModuleNode) => Array<{
538
+ boundary: ModuleNode;
539
+ acceptedVia: ModuleNode;
540
+ }>;
420
541
  invalidateAll: () => void;
421
542
  }
422
543
  interface WebSocketServer {
@@ -482,6 +603,13 @@ interface HmrUpdate {
482
603
  }
483
604
 
484
605
  declare function defineConfig(config: NastiConfig): NastiConfig;
606
+ /**
607
+ * 将 framework:auto 收敛为具体框架。
608
+ *
609
+ * 优先使用源码中的 .vue 文件消除同时安装 React/Vue 时的歧义,其次读取
610
+ * package.json dependencies,最后回退 React 以保持 1.x 默认行为。
611
+ */
612
+ declare function detectFramework(root: string): 'react' | 'vue';
485
613
  /**
486
614
  * Resolve the final configuration by loading file-based config, merging with inline config, and applying plugin hooks.
487
615
  *
@@ -543,8 +671,18 @@ declare class ModuleGraph {
543
671
  setModuleId(mod: ModuleNode, id: string): void;
544
672
  /** 更新模块依赖关系 */
545
673
  updateModuleImports(mod: ModuleNode, importedIds: Set<string>): void;
674
+ /**
675
+ * 用一次转换得到的信息原子更新 import 与 HMR accept 关系。
676
+ * 依赖节点会在真正被浏览器请求前预先创建,这样入口模块先转换时也能建立完整图。
677
+ */
678
+ updateModuleInfo(mod: ModuleNode, importedUrls: Set<string>, acceptedUrls: Set<string>, isSelfAccepting: boolean, expectedInvalidationVersion?: number): Promise<Set<ModuleNode> | null>;
546
679
  /** 使模块的转换缓存失效 */
547
- invalidateModule(mod: ModuleNode): void;
680
+ invalidateModule(mod: ModuleNode, timestamp?: number): void;
681
+ /**
682
+ * 仅失效到 HMR 边界:显式接受依赖的模块本身不会重执行;自接受模块需要失效,
683
+ * 但不再继续影响其 importer。这样既能传播依赖时间戳,也不会隐式重复副作用。
684
+ */
685
+ invalidateModuleAndImporters(mod: ModuleNode, timestamp?: number, seen?: Set<ModuleNode>): void;
548
686
  /** 使所有模块缓存失效 */
549
687
  invalidateAll(): void;
550
688
  /** 获取 HMR 传播边界 - 从变更模块向上遍历找到接受更新的边界 */
@@ -559,6 +697,8 @@ interface NastiEnvironmentInit {
559
697
  mode?: 'dev' | 'build';
560
698
  /** 环境的候选插件(init 时经 applyToEnvironment 过滤) */
561
699
  plugins?: NastiPlugin[];
700
+ /** 配置解析阶段创建的共享插件 API;通常自动从 ResolvedConfig 获取 */
701
+ pluginApi?: PluginApi;
562
702
  }
563
703
  declare class NastiEnvironment implements EnvironmentInstance {
564
704
  readonly name: string;
@@ -567,6 +707,7 @@ declare class NastiEnvironment implements EnvironmentInstance {
567
707
  readonly config: ResolvedConfig;
568
708
  readonly options: ResolvedEnvironmentOptions;
569
709
  readonly hot: HotChannel;
710
+ driver?: EnvironmentDriver;
570
711
  /** applyToEnvironment 过滤后的插件(init() 后可用) */
571
712
  plugins: NastiPlugin[];
572
713
  /** per-env 插件容器(init() 后可用;dev 管线使用) */
@@ -574,10 +715,15 @@ declare class NastiEnvironment implements EnvironmentInstance {
574
715
  /** per-env 模块图(dev 管线使用) */
575
716
  moduleGraph: ModuleGraph;
576
717
  private candidatePlugins;
718
+ private pluginApi;
719
+ private buildMetadata;
577
720
  private initialized;
578
721
  constructor(name: string, config: ResolvedConfig, init?: NastiEnvironmentInit);
579
722
  /** 过滤插件并建 per-env PluginContainer */
580
723
  init(): Promise<void>;
724
+ getDriverContext(): EnvironmentDriverContext;
725
+ setBuildMetadata(metadata: EnvironmentBuildMetadata): void;
726
+ getBuildMetadata(): EnvironmentBuildMetadata;
581
727
  close(): Promise<void>;
582
728
  }
583
729
  /** 按 applyToEnvironment 过滤环境插件(未声明 = 应用于所有环境) */
@@ -585,14 +731,13 @@ declare function resolveEnvironmentPlugins(environment: EnvironmentInstance, plu
585
731
 
586
732
  interface BuildResult {
587
733
  /** client 环境的产物(back-compat:1.x 的 BuildResult 形态) */
588
- output: Array<{
589
- fileName: string;
590
- type: string;
591
- code?: string;
592
- source?: Uint8Array | string;
593
- }>;
734
+ output: EnvironmentBuildOutput[];
594
735
  /** 全部已构建环境的产物(2.0 多环境 builder) */
595
736
  environments?: Record<string, BuildResult['output']>;
737
+ /** 全部环境的完整结果(entries / manifest / stats 等) */
738
+ environmentResults?: Record<string, EnvironmentBuildResult>;
739
+ /** app 级 finalizer 聚合写出的产物(如 `.lynx.bundle`) */
740
+ appOutput?: AppBuildOutput[];
596
741
  }
597
742
  declare function build(inlineConfig?: NastiConfig): Promise<BuildResult>;
598
743
 
@@ -611,6 +756,13 @@ interface ElectronBuildResult {
611
756
  * @throws Error if the configured Electron main entry file does not exist
612
757
  */
613
758
  declare function buildElectron(inlineConfig?: NastiConfig): Promise<ElectronBuildResult>;
759
+ /**
760
+ * 从 Electron 配置派生 renderer 的普通 Web 构建配置。
761
+ *
762
+ * renderer 使用指定 HTML 入口;本地文件加载场景默认把 `/` base 收敛为
763
+ * `./`,避免产物中的 `/assets/*` 被解析到文件系统根目录。
764
+ */
765
+ declare function createElectronRendererConfig(config: ResolvedConfig, inlineConfig?: NastiConfig, overrides?: Pick<NastiConfig, 'build'>): NastiConfig;
614
766
 
615
767
  declare function createServer(inlineConfig?: NastiConfig): Promise<DevServer>;
616
768
 
@@ -624,6 +776,8 @@ interface ElectronDevOptions extends NastiConfig {
624
776
  * @param inlineConfig - Development options; when `inlineConfig.noSpawn` is `true`, only compiles main/preload into `.nasti/` and does not start the Electron process.
625
777
  */
626
778
  declare function startElectronDev(inlineConfig?: ElectronDevOptions): Promise<void>;
779
+ /** 将 renderer HTML 路径转换为 Electron 开发服务器 URL path。 */
780
+ declare function electronRendererDevPath(renderer: string): string;
627
781
 
628
782
  /**
629
783
  * Create a Vite/Rollup plugin that externalizes Electron and Node built-in imports according to the resolved config.
@@ -690,4 +844,4 @@ declare function buildEnvDefine(env: EnvRecord, mode: string, overrides?: Record
690
844
  /** 按环境 consumer 派生 import.meta.env.SSR 的 define 覆盖 */
691
845
  declare function ssrDefineOverrides(consumer: 'client' | 'server'): Record<string, string>;
692
846
 
693
- export { type BuildConfig, type DevServer, type ElectronConfig, type EnvironmentInstance, type EnvironmentOptions, type HmrPayload, type HotChannel, type HotChannelClient, type HotChannelInvokeHandlers, type LogLevel, LogLevels, type LogOptions, type Logger, type ModuleNode, type MonacoCustomWorker, type MonacoEditorLanguageWorker, type MonacoEditorPluginOptions, type NastiConfig, NastiEnvironment, type NastiPlugin, type NastiRolldownOptions, type PluginContext, type RenderChunkContext, type ResolvedConfig, type ResolvedEnvironmentOptions, type TransformResult, build, buildElectron, buildEnvDefine, createDebugger, createLogger, createNoopHotChannel, createServer, createWsHotChannel, defineConfig, electronPlugin, loadEnv, monacoEditorPlugin, printServerUrls, resolveConfig, resolveEnvironmentPlugins, ssrDefineOverrides, startElectronDev };
847
+ export { type AppBuildOutput, type BuildAppContext, type BuildConfig, type BuildResult, type DevServer, type ElectronConfig, type EnvironmentBuildMetadata, type EnvironmentBuildOutput, type EnvironmentBuildResult, type EnvironmentDriver, type EnvironmentDriverContext, type EnvironmentDriverServeContext, type EnvironmentInstance, type EnvironmentOptions, type EnvironmentServeResult, type HmrPayload, type HotChannel, type HotChannelClient, type HotChannelInvokeHandlers, type LogLevel, LogLevels, type LogOptions, type Logger, type ModuleNode, type MonacoCustomWorker, type MonacoEditorLanguageWorker, type MonacoEditorPluginOptions, type NastiConfig, NastiEnvironment, type NastiPlugin, type NastiRolldownOptions, type PluginApi, type PluginApiKey, type PluginContext, type RenderChunkContext, type ResolvedConfig, type ResolvedEnvironmentOptions, type TransformResult, build, buildElectron, buildEnvDefine, createDebugger, createElectronRendererConfig, createLogger, createNoopHotChannel, createServer, createWsHotChannel, defineConfig, detectFramework, electronPlugin, electronRendererDevPath, loadEnv, monacoEditorPlugin, printServerUrls, resolveConfig, resolveEnvironmentPlugins, ssrDefineOverrides, startElectronDev };