@esmx/core 3.0.0-rc.60 → 3.0.0-rc.63

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/src/core.ts CHANGED
@@ -28,105 +28,105 @@ import { type ProjectPath, resolvePath } from './utils/resolve-path';
28
28
  import { getImportPreloadInfo as getStaticImportPaths } from './utils/static-import-lexer';
29
29
 
30
30
  /**
31
- * Esmx 框架的核心配置选项接口
31
+ * Core configuration options interface for the Esmx framework
32
32
  */
33
33
  export interface EsmxOptions {
34
34
  /**
35
- * 项目根目录路径
36
- * - 可以是绝对路径或相对路径
37
- * - 默认为当前工作目录 (process.cwd())
35
+ * Project root directory path
36
+ * - Can be absolute or relative path
37
+ * - Defaults to current working directory (process.cwd())
38
38
  */
39
39
  root?: string;
40
40
 
41
41
  /**
42
- * 是否为生产环境
43
- * - true: 生产环境
44
- * - false: 开发环境
45
- * - 默认根据 process.env.NODE_ENV === 'production' 判断
42
+ * Whether it is production environment
43
+ * - true: Production environment
44
+ * - false: Development environment
45
+ * - Defaults to process.env.NODE_ENV === 'production'
46
46
  */
47
47
  isProd?: boolean;
48
48
 
49
49
  /**
50
- * 基础路径占位符配置
51
- * - string: 自定义占位符
52
- * - false: 禁用占位符
53
- * - 默认值为 '[[[___GEZ_DYNAMIC_BASE___]]]'
54
- * - 用于运行时动态替换资源的基础路径
50
+ * Base path placeholder configuration
51
+ * - string: Custom placeholder
52
+ * - false: Disable placeholder
53
+ * - Default value is '[[[___ESMX_DYNAMIC_BASE___]]]'
54
+ * - Used for dynamically replacing the base path of assets at runtime
55
55
  */
56
56
  basePathPlaceholder?: string | false;
57
57
 
58
58
  /**
59
- * 模块配置选项
60
- * - 用于配置项目的模块解析规则
61
- * - 包括模块别名、外部依赖等配置
59
+ * Module configuration options
60
+ * - Used to configure module resolution rules for the project
61
+ * - Includes module aliases, external dependencies, etc.
62
62
  */
63
63
  modules?: ModuleConfig;
64
64
 
65
65
  /**
66
- * 打包配置选项
67
- * - 用于将构建产物打包成标准的 npm .tgz 格式软件包
68
- * - 包括输出路径、package.json 处理、打包钩子等配置
66
+ * Package configuration options
67
+ * - Used to package build artifacts into standard npm .tgz format packages
68
+ * - Includes output path, package.json handling, packaging hooks, etc.
69
69
  */
70
70
  packs?: PackConfig;
71
71
 
72
72
  /**
73
- * 开发环境应用创建函数
74
- * - 仅在开发环境中使用
75
- * - 用于创建开发服务器的应用实例
76
- * @param esmx Esmx实例
73
+ * Development environment application creation function
74
+ * - Only used in development environment
75
+ * - Used to create application instance for development server
76
+ * @param esmx Esmx instance
77
77
  */
78
78
  devApp?: (esmx: Esmx) => Promise<App>;
79
79
 
80
80
  /**
81
- * 服务器启动配置函数
82
- * - 用于配置和启动 HTTP 服务器
83
- * - 在开发环境和生产环境中都可使用
84
- * @param esmx Esmx实例
81
+ * Server startup configuration function
82
+ * - Used to configure and start HTTP server
83
+ * - Can be used in both development and production environments
84
+ * @param esmx Esmx instance
85
85
  */
86
86
  server?: (esmx: Esmx) => Promise<void>;
87
87
 
88
88
  /**
89
- * 构建后置处理函数
90
- * - 在项目构建完成后执行
91
- * - 可用于执行额外的资源处理、部署等操作
92
- * @param esmx Esmx实例
89
+ * Post-build processing function
90
+ * - Executed after project build is completed
91
+ * - Can be used to perform additional resource processing, deployment, etc.
92
+ * @param esmx Esmx instance
93
93
  */
94
94
  postBuild?: (esmx: Esmx) => Promise<void>;
95
95
  }
96
96
 
97
97
  /**
98
- * 应用程序构建目标类型。
99
- * - client: 客户端构建目标,用于生成浏览器端运行的代码
100
- * - server: 服务端构建目标,用于生成 Node.js 环境运行的代码
98
+ * Application build target types.
99
+ * - client: Client build target, used to generate code that runs in the browser
100
+ * - server: Server build target, used to generate code that runs in Node.js environment
101
101
  */
102
102
  export type BuildEnvironment = 'client' | 'server';
103
103
 
104
104
  /**
105
- * Esmx 框架的命令枚举。
106
- * 用于控制框架的运行模式和生命周期。
105
+ * Command enumeration for the Esmx framework.
106
+ * Used to control the runtime mode and lifecycle of the framework.
107
107
  */
108
108
  export enum COMMAND {
109
109
  /**
110
- * 开发模式
111
- * 启动开发服务器并支持热更新
110
+ * Development mode
111
+ * Starts development server with hot reload support
112
112
  */
113
113
  dev = 'dev',
114
114
 
115
115
  /**
116
- * 构建模式
117
- * 生成生产环境构建产物
116
+ * Build mode
117
+ * Generates production build artifacts
118
118
  */
119
119
  build = 'build',
120
120
 
121
121
  /**
122
- * 预览模式
123
- * 预览构建产物
122
+ * Preview mode
123
+ * Preview build artifacts
124
124
  */
125
125
  preview = 'preview',
126
126
 
127
127
  /**
128
- * 启动模式
129
- * 启动生产环境服务器
128
+ * Start mode
129
+ * Starts production environment server
130
130
  */
131
131
  start = 'start'
132
132
  }
@@ -134,32 +134,32 @@ export enum COMMAND {
134
134
  export type { ImportMap, SpecifierMap, ScopesMap };
135
135
 
136
136
  /**
137
- * Esmx 框架实例的初始化状态接口
138
- * @internal 仅供框架内部使用
137
+ * Initialization status interface for Esmx framework instance
138
+ * @internal For framework internal use only
139
139
  *
140
140
  * @description
141
- * 该接口定义了框架实例初始化后的状态数据,包含:
142
- * - 应用实例:处理请求和渲染
143
- * - 当前命令:控制运行模式
144
- * - 模块配置:解析后的模块设置
145
- * - 打包配置:解析后的构建设置
146
- * - 缓存处理:框架内部缓存机制
141
+ * This interface defines the status data after framework instance initialization, including:
142
+ * - Application instance: Handles requests and rendering
143
+ * - Current command: Controls runtime mode
144
+ * - Module configuration: Parsed module settings
145
+ * - Package configuration: Parsed build settings
146
+ * - Cache handling: Framework internal caching mechanism
147
147
  */
148
148
  interface Readied {
149
- /** 应用程序实例,提供中间件和渲染功能 */
149
+ /** Application instance, providing middleware and rendering functionality */
150
150
  app: App;
151
- /** 当前执行的框架命令 */
151
+ /** Currently executing framework command */
152
152
  command: COMMAND;
153
- /** 解析后的模块配置信息 */
153
+ /** Parsed module configuration information */
154
154
  moduleConfig: ParsedModuleConfig;
155
- /** 解析后的打包配置信息 */
155
+ /** Parsed package configuration information */
156
156
  packConfig: ParsedPackConfig;
157
- /** 缓存处理器 */
157
+ /** Cache handler */
158
158
  cache: CacheHandle;
159
159
  }
160
160
 
161
161
  export class Esmx {
162
- // 基础属性和构造函数
162
+ // Basic properties and constructor
163
163
  private readonly _options: EsmxOptions;
164
164
  private _readied: Readied | null = null;
165
165
  private _importmapHash: string | null = null;
@@ -172,27 +172,27 @@ export class Esmx {
172
172
  }
173
173
 
174
174
  /**
175
- * 获取模块名称
176
- * @returns {string} 当前模块的名称,来源于模块配置
177
- * @throws {NotReadyError} 在框架实例未初始化时抛出错误
175
+ * Get module name
176
+ * @returns {string} The name of the current module, sourced from module configuration
177
+ * @throws {NotReadyError} Throws error when framework instance is not initialized
178
178
  */
179
179
  public get name(): string {
180
180
  return this.moduleConfig.name;
181
181
  }
182
182
 
183
183
  /**
184
- * 获取模块变量名
185
- * @returns {string} 基于模块名称生成的合法 JavaScript 变量名
186
- * @throws {NotReadyError} 在框架实例未初始化时抛出错误
184
+ * Get module variable name
185
+ * @returns {string} A valid JavaScript variable name generated based on the module name
186
+ * @throws {NotReadyError} Throws error when framework instance is not initialized
187
187
  */
188
188
  public get varName(): string {
189
189
  return '__' + this.name.replace(/[^a-zA-Z]/g, '_') + '__';
190
190
  }
191
191
 
192
192
  /**
193
- * 获取项目根目录的绝对路径
194
- * @returns {string} 项目根目录的绝对路径
195
- * 如果配置的 root 为相对路径,则基于当前工作目录解析为绝对路径
193
+ * Get the absolute path of the project root directory
194
+ * @returns {string} The absolute path of the project root directory
195
+ * If the configured root is a relative path, it is resolved to an absolute path based on the current working directory
196
196
  */
197
197
  public get root(): string {
198
198
  const { root = cwd() } = this._options;
@@ -203,83 +203,84 @@ export class Esmx {
203
203
  }
204
204
 
205
205
  /**
206
- * 判断当前是否为生产环境
207
- * @returns {boolean} 环境标识
208
- * 优先使用配置项中的 isProd,若未配置则根据 process.env.NODE_ENV 判断
206
+ * Determine if currently in production environment
207
+ * @returns {boolean} Environment flag
208
+ * Prioritizes the isProd in configuration, if not configured, judges based on process.env.NODE_ENV
209
209
  */
210
210
  public get isProd(): boolean {
211
211
  return this._options?.isProd ?? process.env.NODE_ENV === 'production';
212
212
  }
213
213
 
214
214
  /**
215
- * 获取模块的基础路径
216
- * @returns {string} 以斜杠开头和结尾的模块基础路径
217
- * 用于构建模块资源的访问路径
215
+ * Get the base path of the module
216
+ * @returns {string} The base path of the module starting and ending with a slash
217
+ * Used to construct the access path for module assets
218
218
  */
219
219
  public get basePath(): string {
220
220
  return `/${this.name}/`;
221
221
  }
222
222
 
223
223
  /**
224
- * 获取基础路径占位符
225
- * @returns {string} 基础路径占位符或空字符串
226
- * 用于运行时动态替换模块的基础路径,可通过配置禁用
224
+ * Get the base path placeholder
225
+ * @returns {string} Base path placeholder or empty string
226
+ * Used for dynamically replacing the base path of the module at runtime, can be disabled through configuration
227
227
  */
228
228
  public get basePathPlaceholder(): string {
229
229
  const varName = this._options.basePathPlaceholder;
230
230
  if (varName === false) {
231
231
  return '';
232
232
  }
233
- return varName ?? '[[[___GEZ_DYNAMIC_BASE___]]]';
233
+ return varName ?? '[[[___ESMX_DYNAMIC_BASE___]]]';
234
234
  }
235
235
 
236
236
  /**
237
- * 获取当前执行的命令
238
- * @returns {COMMAND} 当前正在执行的命令枚举值
239
- * @throws {NotReadyError} 在框架实例未初始化时调用此方法会抛出错误
237
+ * Get the currently executing command
238
+ * @returns {COMMAND} The command enumeration value currently being executed
239
+ * @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
240
240
  */
241
241
  public get command(): COMMAND {
242
242
  return this.readied.command;
243
243
  }
244
244
 
245
245
  /**
246
- * 获取命令枚举类型
247
- * @returns {typeof COMMAND} 命令枚举类型定义
246
+ * Get the command enumeration type
247
+ * @returns {typeof COMMAND} Command enumeration type definition
248
248
  */
249
249
  public get COMMAND(): typeof COMMAND {
250
250
  return COMMAND;
251
251
  }
252
252
 
253
253
  /**
254
- * 获取模块配置信息
255
- * @returns {ParsedModuleConfig} 当前模块的完整配置信息
254
+ * Get module configuration information
255
+ * @returns {ParsedModuleConfig} Complete configuration information of the current module
256
256
  */
257
257
  public get moduleConfig(): ParsedModuleConfig {
258
258
  return this.readied.moduleConfig;
259
259
  }
260
260
 
261
261
  /**
262
- * 获取打包配置信息
263
- * @returns {ParsedPackConfig} 当前模块的打包相关配置
262
+ * Get package configuration information
263
+ * @returns {ParsedPackConfig} Package-related configuration of the current module
264
264
  */
265
265
  public get packConfig(): ParsedPackConfig {
266
266
  return this.readied.packConfig;
267
267
  }
268
268
 
269
269
  /**
270
- * 获取应用程序的静态资源处理中间件。
270
+ * Get the static asset processing middleware for the application.
271
271
  *
272
- * 该中间件负责处理应用程序的静态资源请求,根据运行环境提供不同的实现:
273
- * - 开发环境:支持源码的实时编译、热更新,使用 no-cache 缓存策略
274
- * - 生产环境:处理构建后的静态资源,支持不可变文件的长期缓存
272
+ * This middleware is responsible for handling static asset requests for the application,
273
+ * providing different implementations based on the runtime environment:
274
+ * - Development environment: Supports real-time compilation and hot reloading of source code, uses no-cache strategy
275
+ * - Production environment: Handles built static assets, supports long-term caching for immutable files
275
276
  *
276
- * @returns {Middleware} 返回静态资源处理中间件函数
277
- * @throws {NotReadyError} 在框架实例未初始化时调用此方法会抛出错误
277
+ * @returns {Middleware} Returns the static asset processing middleware function
278
+ * @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
278
279
  *
279
280
  * @example
280
281
  * ```ts
281
282
  * const server = http.createServer((req, res) => {
282
- * // 使用中间件处理静态资源请求
283
+ * // Use middleware to handle static asset requests
283
284
  * esmx.middleware(req, res, async () => {
284
285
  * const rc = await esmx.render({ url: req.url });
285
286
  * res.end(rc.html);
@@ -292,28 +293,29 @@ export class Esmx {
292
293
  }
293
294
 
294
295
  /**
295
- * 获取应用程序的服务端渲染函数。
296
+ * Get the server-side rendering function for the application.
296
297
  *
297
- * 该函数负责执行服务端渲染,根据运行环境提供不同的实现:
298
- * - 开发环境:加载源码中的服务端入口文件,支持热更新和实时预览
299
- * - 生产环境:加载构建后的服务端入口文件,提供优化的渲染性能
298
+ * This function is responsible for executing server-side rendering,
299
+ * providing different implementations based on the runtime environment:
300
+ * - Development environment: Loads server entry file from source code, supports hot reloading and real-time preview
301
+ * - Production environment: Loads built server entry file, provides optimized rendering performance
300
302
  *
301
- * @returns {(options?: RenderContextOptions) => Promise<RenderContext>} 返回服务端渲染函数
302
- * @throws {NotReadyError} 在框架实例未初始化时调用此方法会抛出错误
303
+ * @returns {(options?: RenderContextOptions) => Promise<RenderContext>} Returns the server-side rendering function
304
+ * @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
303
305
  *
304
306
  * @example
305
307
  * ```ts
306
- * // 基本用法
308
+ * // Basic usage
307
309
  * const rc = await esmx.render({
308
310
  * params: { url: req.url }
309
311
  * });
310
312
  * res.end(rc.html);
311
313
  *
312
- * // 高级配置
314
+ * // Advanced configuration
313
315
  * const rc = await esmx.render({
314
- * base: '', // 设置基础路径
315
- * importmapMode: 'inline', // 设置导入映射模式
316
- * entryName: 'default', // 指定渲染入口
316
+ * base: '', // Set base path
317
+ * importmapMode: 'inline', // Set import map mode
318
+ * entryName: 'default', // Specify render entry
317
319
  * params: {
318
320
  * url: req.url,
319
321
  * state: { user: 'admin' }
@@ -330,21 +332,21 @@ export class Esmx {
330
332
  this._options = options;
331
333
  }
332
334
  /**
333
- * 初始化 Esmx 框架实例。
335
+ * Initialize the Esmx framework instance.
334
336
  *
335
- * 该方法执行以下核心初始化流程:
336
- * 1. 解析项目配置(package.json、模块配置、打包配置等)
337
- * 2. 创建应用实例(开发环境或生产环境)
338
- * 3. 根据命令执行相应的生命周期方法
337
+ * This method executes the following core initialization process:
338
+ * 1. Parse project configuration (package.json, module configuration, package configuration, etc.)
339
+ * 2. Create application instance (development or production environment)
340
+ * 3. Execute corresponding lifecycle methods based on the command
339
341
  *
340
- * @param command - 框架运行命令
341
- * - dev: 启动开发服务器,支持热更新
342
- * - build: 构建生产环境产物
343
- * - preview: 预览构建产物
344
- * - start: 启动生产环境服务器
342
+ * @param command - Framework running command
343
+ * - dev: Start development server with hot reload support
344
+ * - build: Build production artifacts
345
+ * - preview: Preview build artifacts
346
+ * - start: Start production environment server
345
347
  *
346
- * @returns 初始化成功返回 true
347
- * @throws {Error} 重复初始化时抛出错误
348
+ * @returns Returns true for successful initialization
349
+ * @throws {Error} Throws error when initializing repeatedly
348
350
  *
349
351
  * @example
350
352
  * ```ts
@@ -352,32 +354,32 @@ export class Esmx {
352
354
  * import type { EsmxOptions } from '@esmx/core';
353
355
  *
354
356
  * export default {
355
- * // 开发环境配置
357
+ * // Development environment configuration
356
358
  * async devApp(esmx) {
357
359
  * return import('@esmx/rspack').then((m) =>
358
360
  * m.createRspackHtmlApp(esmx, {
359
361
  * config(context) {
360
- * // 自定义 Rspack 配置
362
+ * // Custom Rspack configuration
361
363
  * }
362
364
  * })
363
365
  * );
364
366
  * },
365
367
  *
366
- * // HTTP 服务器配置
368
+ * // HTTP server configuration
367
369
  * async server(esmx) {
368
370
  * const server = http.createServer((req, res) => {
369
- * // 静态文件处理
371
+ * // Static file handling
370
372
  * esmx.middleware(req, res, async () => {
371
- * // 传入渲染的参数
373
+ * // Pass rendering parameters
372
374
  * const render = await esmx.render({
373
375
  * params: { url: req.url }
374
376
  * });
375
- * // 响应 HTML 内容
377
+ * // Respond with HTML content
376
378
  * res.end(render.html);
377
379
  * });
378
380
  * });
379
381
  *
380
- * // 监听端口
382
+ * // Listen to port
381
383
  * server.listen(3000, () => {
382
384
  * console.log('http://localhost:3000');
383
385
  * });
@@ -435,25 +437,25 @@ export class Esmx {
435
437
  }
436
438
 
437
439
  /**
438
- * 销毁 Esmx 框架实例,执行资源清理和连接关闭等操作。
440
+ * Destroy the Esmx framework instance, performing resource cleanup and connection closing operations.
439
441
  *
440
- * 该方法主要用于开发环境下的资源清理,包括:
441
- * - 关闭开发服务器(如 Rspack Dev Server
442
- * - 清理临时文件和缓存
443
- * - 释放系统资源
442
+ * This method is mainly used for resource cleanup in development environment, including:
443
+ * - Closing development servers (such as Rspack Dev Server)
444
+ * - Cleaning up temporary files and cache
445
+ * - Releasing system resources
444
446
  *
445
- * 注意:一般情况下,框架会自动处理资源的释放,用户无需手动调用此方法。
446
- * 仅在需要自定义资源清理逻辑时才需要使用。
447
+ * Note: In general, the framework automatically handles resource release, users do not need to manually call this method.
448
+ * Only use it when custom resource cleanup logic is needed.
447
449
  *
448
- * @returns 返回一个 Promise,resolve boolean
449
- * - true: 清理成功或无需清理
450
- * - false: 清理失败
450
+ * @returns Returns a Promise that resolves to a boolean value
451
+ * - true: Cleanup successful or no cleanup needed
452
+ * - false: Cleanup failed
451
453
  *
452
454
  * @example
453
455
  * ```ts
454
- * // 在需要自定义清理逻辑时使用
456
+ * // Use when custom cleanup logic is needed
455
457
  * process.once('SIGTERM', async () => {
456
- * await esmx.destroy(); // 清理资源
458
+ * await esmx.destroy(); // Clean up resources
457
459
  * process.exit(0);
458
460
  * });
459
461
  * ```
@@ -467,21 +469,21 @@ export class Esmx {
467
469
  }
468
470
 
469
471
  /**
470
- * 执行应用程序的构建流程。
472
+ * Execute the application's build process.
471
473
  *
472
- * 该方法负责执行整个应用的构建过程,包括:
473
- * - 编译源代码
474
- * - 生成生产环境的构建产物
475
- * - 优化和压缩代码
476
- * - 生成资源清单
474
+ * This method is responsible for executing the entire application build process, including:
475
+ * - Compiling source code
476
+ * - Generating production build artifacts
477
+ * - Optimizing and compressing code
478
+ * - Generating asset manifests
477
479
  *
478
- * 构建过程会打印开始和结束时间,以及总耗时等信息。
480
+ * The build process prints start and end times, as well as total duration and other information.
479
481
  *
480
- * @returns 返回一个 Promise,resolve boolean
481
- * - true: 构建成功或构建方法未实现
482
- * - false: 构建失败
482
+ * @returns Returns a Promise that resolves to a boolean value
483
+ * - true: Build successful or build method not implemented
484
+ * - false: Build failed
483
485
  *
484
- * @throws {NotReadyError} 在框架实例未初始化时调用此方法会抛出错误
486
+ * @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
485
487
  *
486
488
  * @example
487
489
  * ```ts
@@ -489,20 +491,20 @@ export class Esmx {
489
491
  * import type { EsmxOptions } from '@esmx/core';
490
492
  *
491
493
  * export default {
492
- * // 开发环境配置
494
+ * // Development environment configuration
493
495
  * async devApp(esmx) {
494
496
  * return import('@esmx/rspack').then((m) =>
495
497
  * m.createRspackHtmlApp(esmx, {
496
498
  * config(context) {
497
- * // 自定义 Rspack 配置
499
+ * // Custom Rspack configuration
498
500
  * }
499
501
  * })
500
502
  * );
501
503
  * },
502
504
  *
503
- * // 构建后处理
505
+ * // Post-build processing
504
506
  * async postBuild(esmx) {
505
- * // 构建完成后生成静态 HTML
507
+ * // Generate static HTML after build completion
506
508
  * const render = await esmx.render({
507
509
  * params: { url: '/' }
508
510
  * });
@@ -532,21 +534,21 @@ export class Esmx {
532
534
  }
533
535
 
534
536
  /**
535
- * 启动 HTTP 服务器并配置服务器实例。
537
+ * Start HTTP server and configure server instance.
536
538
  *
537
- * 该方法在框架的以下生命周期中被调用:
538
- * - 开发环境(dev):启动开发服务器,提供热更新等功能
539
- * - 生产环境(start):启动生产服务器,提供生产级性能
539
+ * This method is called in the following lifecycle of the framework:
540
+ * - Development environment (dev): Start development server, providing features like hot reload
541
+ * - Production environment (start): Start production server, providing production-grade performance
540
542
  *
541
- * 服务器的具体实现由用户通过 EsmxOptions server 配置函数提供。
542
- * 该函数负责:
543
- * - 创建 HTTP 服务器实例
544
- * - 配置中间件和路由
545
- * - 处理请求和响应
546
- * - 启动服务器监听
543
+ * The specific implementation of the server is provided by the user through the server configuration function in EsmxOptions.
544
+ * This function is responsible for:
545
+ * - Creating HTTP server instance
546
+ * - Configuring middleware and routes
547
+ * - Handling requests and responses
548
+ * - Starting server listening
547
549
  *
548
- * @returns 返回一个 Promise,在服务器启动完成后 resolve
549
- * @throws {NotReadyError} 在框架实例未初始化时调用此方法会抛出错误
550
+ * @returns Returns a Promise that resolves when the server startup is complete
551
+ * @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
550
552
  *
551
553
  * @example
552
554
  * ```ts
@@ -555,12 +557,12 @@ export class Esmx {
555
557
  * import type { EsmxOptions } from '@esmx/core';
556
558
  *
557
559
  * export default {
558
- * // 服务器配置
560
+ * // Server configuration
559
561
  * async server(esmx) {
560
562
  * const server = http.createServer((req, res) => {
561
- * // 处理静态资源
563
+ * // Handle static assets
562
564
  * esmx.middleware(req, res, async () => {
563
- * // 服务端渲染
565
+ * // Server-side rendering
564
566
  * const render = await esmx.render({
565
567
  * params: { url: req.url }
566
568
  * });
@@ -568,7 +570,7 @@ export class Esmx {
568
570
  * });
569
571
  * });
570
572
  *
571
- * // 启动服务器
573
+ * // Start server
572
574
  * server.listen(3000, () => {
573
575
  * console.log('Server running at http://localhost:3000');
574
576
  * });
@@ -581,19 +583,19 @@ export class Esmx {
581
583
  }
582
584
 
583
585
  /**
584
- * 执行构建后的处理逻辑。
586
+ * Execute post-build processing logic.
585
587
  *
586
- * 该方法在应用构建完成后被调用,用于执行额外的资源处理,如:
587
- * - 生成静态 HTML 文件
588
- * - 处理构建产物
589
- * - 执行部署任务
590
- * - 发送构建通知
588
+ * This method is called after the application build is completed, used to perform additional resource processing, such as:
589
+ * - Generating static HTML files
590
+ * - Processing build artifacts
591
+ * - Executing deployment tasks
592
+ * - Sending build notifications
591
593
  *
592
- * 方法会自动捕获并处理执行过程中的异常,确保不会影响主构建流程。
594
+ * The method automatically captures and handles exceptions during execution, ensuring it does not affect the main build process.
593
595
  *
594
- * @returns 返回一个 Promise,resolve boolean
595
- * - true: 后处理成功或无需处理
596
- * - false: 后处理失败
596
+ * @returns Returns a Promise that resolves to a boolean value
597
+ * - true: Post-processing successful or no processing needed
598
+ * - false: Post-processing failed
597
599
  *
598
600
  * @example
599
601
  * ```ts
@@ -601,9 +603,9 @@ export class Esmx {
601
603
  * import type { EsmxOptions } from '@esmx/core';
602
604
  *
603
605
  * export default {
604
- * // 构建后处理
606
+ * // Post-build processing
605
607
  * async postBuild(esmx) {
606
- * // 生成多个页面的静态 HTML
608
+ * // Generate static HTML for multiple pages
607
609
  * const pages = ['/', '/about', '/404'];
608
610
  *
609
611
  * for (const url of pages) {
@@ -611,7 +613,7 @@ export class Esmx {
611
613
  * params: { url }
612
614
  * });
613
615
  *
614
- * // 写入静态 HTML 文件
616
+ * // Write static HTML file
615
617
  * esmx.writeSync(
616
618
  * esmx.resolvePath('dist/client', url.substring(1), 'index.html'),
617
619
  * render.html
@@ -631,18 +633,18 @@ export class Esmx {
631
633
  }
632
634
  }
633
635
  /**
634
- * 解析项目相对路径为绝对路径
636
+ * Resolve project relative path to absolute path
635
637
  *
636
- * @param projectPath - 项目路径类型,如 'dist/client''dist/server'
637
- * @param args - 需要拼接的路径片段
638
- * @returns 解析后的绝对路径
638
+ * @param projectPath - Project path type, such as 'dist/client', 'dist/server', etc.
639
+ * @param args - Path segments to be concatenated
640
+ * @returns Resolved absolute path
639
641
  *
640
642
  * @example
641
643
  * ```ts
642
- * // entry.node.ts 中使用
644
+ * // Used in entry.node.ts
643
645
  * async postBuild(esmx) {
644
646
  * const outputPath = esmx.resolvePath('dist/client', 'index.html');
645
- * // 输出: /project/root/dist/client/index.html
647
+ * // Output: /project/root/dist/client/index.html
646
648
  * }
647
649
  * ```
648
650
  */
@@ -651,15 +653,15 @@ export class Esmx {
651
653
  }
652
654
 
653
655
  /**
654
- * 同步写入文件内容
656
+ * Write file content synchronously
655
657
  *
656
- * @param filepath - 文件的绝对路径
657
- * @param data - 要写入的数据,可以是字符串、Buffer 或对象
658
- * @returns 写入是否成功
658
+ * @param filepath - Absolute path of the file
659
+ * @param data - Data to be written, can be string, Buffer or object
660
+ * @returns Whether the write was successful
659
661
  *
660
662
  * @example
661
663
  * ```ts
662
- * // entry.node.ts 中使用
664
+ * // Used in entry.node.ts
663
665
  * async postBuild(esmx) {
664
666
  * const htmlPath = esmx.resolvePath('dist/client', 'index.html');
665
667
  * const success = esmx.writeSync(htmlPath, '<html>...</html>');
@@ -668,9 +670,9 @@ export class Esmx {
668
670
  */
669
671
  public writeSync(filepath: string, data: any): boolean {
670
672
  try {
671
- // 确保目标目录存在
673
+ // Ensure the target directory exists
672
674
  fs.mkdirSync(path.dirname(filepath), { recursive: true });
673
- // 写入文件
675
+ // Write file
674
676
  fs.writeFileSync(filepath, data);
675
677
  return true;
676
678
  } catch {
@@ -679,15 +681,15 @@ export class Esmx {
679
681
  }
680
682
 
681
683
  /**
682
- * 异步写入文件内容
684
+ * Write file content asynchronously
683
685
  *
684
- * @param filepath - 文件的绝对路径
685
- * @param data - 要写入的数据,可以是字符串、Buffer 或对象
686
- * @returns Promise<boolean> 写入是否成功
686
+ * @param filepath - Absolute path of the file
687
+ * @param data - Data to be written, can be string, Buffer or object
688
+ * @returns Promise<boolean> Whether the write was successful
687
689
  *
688
690
  * @example
689
691
  * ```ts
690
- * // entry.node.ts 中使用
692
+ * // Used in entry.node.ts
691
693
  * async postBuild(esmx) {
692
694
  * const htmlPath = esmx.resolvePath('dist/client', 'index.html');
693
695
  * const success = await esmx.write(htmlPath, '<html>...</html>');
@@ -696,9 +698,9 @@ export class Esmx {
696
698
  */
697
699
  public async write(filepath: string, data: any): Promise<boolean> {
698
700
  try {
699
- // 确保目标目录存在
701
+ // Ensure the target directory exists
700
702
  await fsp.mkdir(path.dirname(filepath), { recursive: true });
701
- // 写入文件
703
+ // Write file
702
704
  await fsp.writeFile(filepath, data);
703
705
  return true;
704
706
  } catch {
@@ -707,19 +709,19 @@ export class Esmx {
707
709
  }
708
710
 
709
711
  /**
710
- * 同步读取并解析 JSON 文件
712
+ * Read and parse JSON file synchronously
711
713
  *
712
- * @template T - 期望返回的JSON对象类型
713
- * @param filename - JSON 文件的绝对路径
714
- * @returns {T} 解析后的 JSON 对象
715
- * @throws 当文件不存在或 JSON 格式错误时抛出异常
714
+ * @template T - Expected JSON object type to return
715
+ * @param filename - Absolute path of the JSON file
716
+ * @returns {T} Parsed JSON object
717
+ * @throws Throws exception when file does not exist or JSON format is incorrect
716
718
  *
717
719
  * @example
718
720
  * ```ts
719
- * // entry.node.ts 中使用
721
+ * // Used in entry.node.ts
720
722
  * async server(esmx) {
721
723
  * const manifest = esmx.readJsonSync<Manifest>(esmx.resolvePath('dist/client', 'manifest.json'));
722
- * // 使用 manifest 对象
724
+ * // Use manifest object
723
725
  * }
724
726
  * ```
725
727
  */
@@ -728,19 +730,19 @@ export class Esmx {
728
730
  }
729
731
 
730
732
  /**
731
- * 异步读取并解析 JSON 文件
733
+ * Read and parse JSON file asynchronously
732
734
  *
733
- * @template T - 期望返回的JSON对象类型
734
- * @param filename - JSON 文件的绝对路径
735
- * @returns {Promise<T>} 解析后的 JSON 对象
736
- * @throws 当文件不存在或 JSON 格式错误时抛出异常
735
+ * @template T - Expected JSON object type to return
736
+ * @param filename - Absolute path of the JSON file
737
+ * @returns {Promise<T>} Parsed JSON object
738
+ * @throws Throws exception when file does not exist or JSON format is incorrect
737
739
  *
738
740
  * @example
739
741
  * ```ts
740
- * // entry.node.ts 中使用
742
+ * // Used in entry.node.ts
741
743
  * async server(esmx) {
742
744
  * const manifest = await esmx.readJson<Manifest>(esmx.resolvePath('dist/client', 'manifest.json'));
743
- * // 使用 manifest 对象
745
+ * // Use manifest object
744
746
  * }
745
747
  * ```
746
748
  */
@@ -749,36 +751,36 @@ export class Esmx {
749
751
  }
750
752
 
751
753
  /**
752
- * 获取构建清单列表
754
+ * Get build manifest list
753
755
  *
754
756
  * @description
755
- * 该方法用于获取指定目标环境的构建清单列表,包含以下功能:
756
- * 1. **缓存管理**
757
- * - 使用内部缓存机制避免重复加载
758
- * - 返回不可变的清单列表
757
+ * This method is used to get the build manifest list for the specified target environment, including the following features:
758
+ * 1. **Cache Management**
759
+ * - Uses internal caching mechanism to avoid repeated loading
760
+ * - Returns immutable manifest list
759
761
  *
760
- * 2. **环境适配**
761
- * - 支持客户端和服务端两种环境
762
- * - 根据目标环境返回对应的清单信息
762
+ * 2. **Environment Adaptation**
763
+ * - Supports both client and server environments
764
+ * - Returns corresponding manifest information based on the target environment
763
765
  *
764
- * 3. **模块映射**
765
- * - 包含模块导出信息
766
- * - 记录资源依赖关系
766
+ * 3. **Module Mapping**
767
+ * - Contains module export information
768
+ * - Records resource dependency relationships
767
769
  *
768
- * @param env - 目标环境类型
769
- * - 'client': 客户端环境
770
- * - 'server': 服务端环境
771
- * @returns 返回只读的构建清单列表
772
- * @throws {NotReadyError} 在框架实例未初始化时调用此方法会抛出错误
770
+ * @param env - Target environment type
771
+ * - 'client': Client environment
772
+ * - 'server': Server environment
773
+ * @returns Returns read-only build manifest list
774
+ * @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
773
775
  *
774
776
  * @example
775
777
  * ```ts
776
- * // entry.node.ts 中使用
778
+ * // Used in entry.node.ts
777
779
  * async server(esmx) {
778
- * // 获取客户端构建清单
780
+ * // Get client build manifest
779
781
  * const manifests = await esmx.getManifestList('client');
780
782
  *
781
- * // 查找特定模块的构建信息
783
+ * // Find build information for a specific module
782
784
  * const appModule = manifests.find(m => m.name === 'my-app');
783
785
  * if (appModule) {
784
786
  * console.log('App exports:', appModule.exports);
@@ -796,37 +798,37 @@ export class Esmx {
796
798
  }
797
799
 
798
800
  /**
799
- * 获取导入映射对象
801
+ * Get import map object
800
802
  *
801
803
  * @description
802
- * 该方法用于生成 ES 模块导入映射(Import Map),具有以下特点:
803
- * 1. **模块解析**
804
- * - 基于构建清单生成模块映射
805
- * - 支持客户端和服务端两种环境
806
- * - 自动处理模块路径解析
807
- *
808
- * 2. **缓存优化**
809
- * - 使用内部缓存机制
810
- * - 返回不可变的映射对象
811
- *
812
- * 3. **路径处理**
813
- * - 自动处理模块路径
814
- * - 支持动态基础路径
815
- *
816
- * @param env - 目标环境类型
817
- * - 'client': 生成浏览器环境的导入映射
818
- * - 'server': 生成服务端环境的导入映射
819
- * @returns 返回只读的导入映射对象
820
- * @throws {NotReadyError} 在框架实例未初始化时调用此方法会抛出错误
804
+ * This method is used to generate ES module import maps with the following features:
805
+ * 1. **Module Resolution**
806
+ * - Generate module mappings based on build manifests
807
+ * - Support both client and server environments
808
+ * - Automatically handle module path resolution
809
+ *
810
+ * 2. **Cache Optimization**
811
+ * - Use internal caching mechanism
812
+ * - Return immutable mapping objects
813
+ *
814
+ * 3. **Path Handling**
815
+ * - Automatically handle module paths
816
+ * - Support dynamic base paths
817
+ *
818
+ * @param env - Target environment type
819
+ * - 'client': Generate import map for browser environment
820
+ * - 'server': Generate import map for server environment
821
+ * @returns Returns read-only import map object
822
+ * @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
821
823
  *
822
824
  * @example
823
825
  * ```ts
824
- * // entry.node.ts 中使用
826
+ * // Used in entry.node.ts
825
827
  * async server(esmx) {
826
- * // 获取客户端导入映射
828
+ * // Get client import map
827
829
  * const importmap = await esmx.getImportMap('client');
828
830
  *
829
- * // 自定义 HTML 模板
831
+ * // Custom HTML template
830
832
  * const html = `
831
833
  * <!DOCTYPE html>
832
834
  * <html>
@@ -836,7 +838,7 @@ export class Esmx {
836
838
  * </script>
837
839
  * </head>
838
840
  * <body>
839
- * <!-- 页面内容 -->
841
+ * <!-- Page content -->
840
842
  * </body>
841
843
  * </html>
842
844
  * `;
@@ -851,7 +853,7 @@ export class Esmx {
851
853
  const manifests = await this.getManifestList(env);
852
854
  let json: ImportMap = {};
853
855
  switch (env) {
854
- case 'client':
856
+ case 'client': {
855
857
  json = getImportMap({
856
858
  manifests,
857
859
  getScope(name, scope) {
@@ -862,6 +864,7 @@ export class Esmx {
862
864
  }
863
865
  });
864
866
  break;
867
+ }
865
868
  case 'server':
866
869
  json = getImportMap({
867
870
  manifests,
@@ -894,44 +897,44 @@ export class Esmx {
894
897
  }
895
898
 
896
899
  /**
897
- * 获取客户端导入映射信息
900
+ * Get client import map information
898
901
  *
899
902
  * @description
900
- * 该方法用于生成客户端环境的导入映射代码,支持两种模式:
901
- * 1. **内联模式 (inline)**
902
- * - 将导入映射直接内联到 HTML
903
- * - 减少额外的网络请求
904
- * - 适合导入映射较小的场景
905
- *
906
- * 2. **JS 文件模式 (js)**
907
- * - 生成独立的 JS 文件
908
- * - 支持浏览器缓存
909
- * - 适合导入映射较大的场景
910
- *
911
- * 核心功能:
912
- * - 自动处理动态基础路径
913
- * - 支持模块路径运行时替换
914
- * - 优化缓存策略
915
- * - 确保模块加载顺序
916
- *
917
- * @param mode - 导入映射模式
918
- * - 'inline': 内联模式,返回 HTML script 标签
919
- * - 'js': JS 文件模式,返回带有文件路径的信息
920
- * @returns 返回导入映射的相关信息
921
- * - src: JS 文件的 URL(仅在 js 模式下)
922
- * - filepath: JS 文件的本地路径(仅在 js 模式下)
923
- * - code: HTML script 标签内容
924
- * @throws {NotReadyError} 在框架实例未初始化时调用此方法会抛出错误
903
+ * This method is used to generate import map code for client environment, supporting two modes:
904
+ * 1. **Inline Mode (inline)**
905
+ * - Inline import map directly into HTML
906
+ * - Reduce additional network requests
907
+ * - Suitable for scenarios with smaller import maps
908
+ *
909
+ * 2. **JS File Mode (js)**
910
+ * - Generate standalone JS file
911
+ * - Support browser caching
912
+ * - Suitable for scenarios with larger import maps
913
+ *
914
+ * Core Features:
915
+ * - Automatically handle dynamic base paths
916
+ * - Support module path runtime replacement
917
+ * - Optimize caching strategy
918
+ * - Ensure module loading order
919
+ *
920
+ * @param mode - Import map mode
921
+ * - 'inline': Inline mode, returns HTML script tag
922
+ * - 'js': JS file mode, returns information with file path
923
+ * @returns Returns import map related information
924
+ * - src: URL of the JS file (only in js mode)
925
+ * - filepath: Local path of the JS file (only in js mode)
926
+ * - code: HTML script tag content
927
+ * @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
925
928
  *
926
929
  * @example
927
930
  * ```ts
928
- * // entry.node.ts 中使用
931
+ * // Used in entry.node.ts
929
932
  * async server(esmx) {
930
933
  * const server = express();
931
934
  * server.use(esmx.middleware);
932
935
  *
933
936
  * server.get('*', async (req, res) => {
934
- * // 使用 JS 文件模式
937
+ * // Use JS file mode
935
938
  * const result = await esmx.render({
936
939
  * importmapMode: 'js',
937
940
  * params: { url: req.url }
@@ -939,7 +942,7 @@ export class Esmx {
939
942
  * res.send(result.html);
940
943
  * });
941
944
  *
942
- * // 或者使用内联模式
945
+ * // Or use inline mode
943
946
  * server.get('/inline', async (req, res) => {
944
947
  * const result = await esmx.render({
945
948
  * importmapMode: 'inline',
@@ -1034,23 +1037,23 @@ document.head.appendChild(script);
1034
1037
  return {
1035
1038
  src: null,
1036
1039
  filepath: null,
1037
- code: `<script type="importmap">${serialize(importmap, { isJSON: true })}</script>`
1040
+ code: `<script type="importmap">${serialize(importmap, { isJSON: true, unsafe: true })}</script>`
1038
1041
  };
1039
1042
  }
1040
1043
  );
1041
1044
  }
1042
1045
 
1043
1046
  /**
1044
- * 获取模块的静态导入路径列表。
1047
+ * Get the list of static import paths for a module.
1045
1048
  *
1046
- * @param env - 构建目标('client' | 'server'
1047
- * @param specifier - 模块标识符
1048
- * @returns 返回静态导入路径列表,如果未找到则返回 null
1049
- * @throws {NotReadyError} 在框架实例未初始化时调用此方法会抛出错误
1049
+ * @param env - Build target ('client' | 'server')
1050
+ * @param specifier - Module specifier
1051
+ * @returns Returns the list of static import paths, returns null if not found
1052
+ * @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
1050
1053
  *
1051
1054
  * @example
1052
1055
  * ```ts
1053
- * // 获取客户端入口模块的静态导入路径
1056
+ * // Get static import paths for client entry module
1054
1057
  * const paths = await esmx.getStaticImportPaths(
1055
1058
  * 'client',
1056
1059
  * `your-app-name/src/entry.client`
@@ -1079,18 +1082,18 @@ document.head.appendChild(script);
1079
1082
  }
1080
1083
 
1081
1084
  /**
1082
- * 默认的开发环境应用创建函数
1085
+ * Default development environment application creation function
1083
1086
  *
1084
1087
  * @description
1085
- * 这是一个默认的占位函数,用于在未配置开发环境应用创建函数时抛出错误。
1086
- * 实际使用时应当通过 EsmxOptions.devApp 配置实际的应用创建函数。
1088
+ * This is a default placeholder function that throws an error when the development environment application creation function is not configured.
1089
+ * In actual use, the actual application creation function should be configured through EsmxOptions.devApp.
1087
1090
  *
1088
- * @throws {Error} 当未配置 devApp 时抛出错误,提示用户需要设置开发环境应用创建函数
1089
- * @returns {Promise<App>} 不会真正返回,总是抛出错误
1091
+ * @throws {Error} Throws an error when devApp is not configured, prompting the user to set up the development environment application creation function
1092
+ * @returns {Promise<App>} Will not actually return, always throws an error
1090
1093
  *
1091
1094
  * @example
1092
1095
  * ```ts
1093
- * // 正确的使用方式是在配置中提供 devApp
1096
+ * // Correct usage is to provide devApp in the configuration
1094
1097
  * const options: EsmxOptions = {
1095
1098
  * devApp: async (esmx) => {
1096
1099
  * return import('@esmx/rspack').then(m =>
@@ -1105,13 +1108,13 @@ async function defaultDevApp(): Promise<App> {
1105
1108
  }
1106
1109
 
1107
1110
  /**
1108
- * Esmx 框架未初始化错误
1111
+ * Esmx framework not initialized error
1109
1112
  *
1110
1113
  * @description
1111
- * 该错误在以下情况下抛出:
1112
- * - 在调用 init() 之前访问需要初始化的方法或属性
1113
- * - 在框架未完全初始化时尝试使用核心功能
1114
- * - 在销毁实例后继续使用框架功能
1114
+ * This error is thrown in the following situations:
1115
+ * - Accessing methods or properties that require initialization before calling init()
1116
+ * - Attempting to use core functionality when the framework is not fully initialized
1117
+ * - Continuing to use framework functionality after destroying the instance
1115
1118
  *
1116
1119
  * @extends Error
1117
1120
  *
@@ -1119,7 +1122,7 @@ async function defaultDevApp(): Promise<App> {
1119
1122
  * ```ts
1120
1123
  * const esmx = new Esmx();
1121
1124
  * try {
1122
- * // 这会抛出 NotReadyError,因为还未初始化
1125
+ * // This will throw NotReadyError because it's not initialized yet
1123
1126
  * await esmx.render();
1124
1127
  * } catch (e) {
1125
1128
  * if (e instanceof NotReadyError) {
@@ -1135,27 +1138,27 @@ class NotReadyError extends Error {
1135
1138
  }
1136
1139
 
1137
1140
  /**
1138
- * 计算内容的 SHA-256 哈希值
1141
+ * Calculate SHA-256 hash value of content
1139
1142
  *
1140
1143
  * @description
1141
- * 该函数用于:
1142
- * - 生成文件内容的唯一标识符
1143
- * - 用于缓存失效判断
1144
- * - 生成具有内容哈希的文件名
1144
+ * This function is used for:
1145
+ * - Generating unique identifiers for file content
1146
+ * - Cache invalidation judgment
1147
+ * - Generating filenames with content hash
1145
1148
  *
1146
- * 特点:
1147
- * - 使用 SHA-256 算法确保哈希值的唯一性
1148
- * - 截取前 12 位以平衡唯一性和长度
1149
- * - 适用于缓存控制和文件版本管理
1149
+ * Features:
1150
+ * - Uses SHA-256 algorithm to ensure hash uniqueness
1151
+ * - Truncates to first 12 characters to balance uniqueness and length
1152
+ * - Suitable for cache control and file version management
1150
1153
  *
1151
- * @param {string} text - 要计算哈希的文本内容
1152
- * @returns {string} 返回 12 位的十六进制哈希字符串
1154
+ * @param {string} text - Text content to calculate hash for
1155
+ * @returns {string} Returns 12-character hexadecimal hash string
1153
1156
  *
1154
1157
  * @example
1155
1158
  * ```ts
1156
1159
  * const content = 'some content';
1157
1160
  * const hash = contentHash(content);
1158
- * // 输出类似:'a1b2c3d4e5f6'
1161
+ * // Output similar to: 'a1b2c3d4e5f6'
1159
1162
  * ```
1160
1163
  */
1161
1164
  function contentHash(text: string) {