@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/README.md +4 -4
- package/README.zh-CN.md +4 -4
- package/dist/app.d.ts +27 -27
- package/dist/core.d.ts +274 -272
- package/dist/core.mjs +235 -232
- package/dist/pack-config.d.ts +92 -92
- package/dist/render-context.d.ts +465 -465
- package/dist/render-context.mjs +338 -338
- package/dist/utils/cache.d.ts +15 -15
- package/dist/utils/import-map.d.ts +31 -1
- package/dist/utils/import-map.mjs +18 -0
- package/dist/utils/import-map.test.mjs +577 -1
- package/dist/utils/middleware.d.ts +19 -19
- package/dist/utils/static-import-lexer.d.ts +12 -12
- package/dist/utils/static-import-lexer.mjs +1 -1
- package/package.json +3 -3
- package/src/app.ts +34 -34
- package/src/core.ts +320 -317
- package/src/pack-config.ts +92 -92
- package/src/render-context.ts +465 -465
- package/src/utils/cache.ts +15 -15
- package/src/utils/import-map.test.ts +713 -1
- package/src/utils/import-map.ts +53 -1
- package/src/utils/middleware.ts +19 -19
- package/src/utils/static-import-lexer.ts +18 -18
package/dist/core.mjs
CHANGED
|
@@ -25,7 +25,7 @@ export var COMMAND = /* @__PURE__ */ ((COMMAND2) => {
|
|
|
25
25
|
return COMMAND2;
|
|
26
26
|
})(COMMAND || {});
|
|
27
27
|
export class Esmx {
|
|
28
|
-
//
|
|
28
|
+
// Basic properties and constructor
|
|
29
29
|
_options;
|
|
30
30
|
_readied = null;
|
|
31
31
|
_importmapHash = null;
|
|
@@ -36,25 +36,25 @@ export class Esmx {
|
|
|
36
36
|
throw new NotReadyError();
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
* @returns {string}
|
|
41
|
-
* @throws {NotReadyError}
|
|
39
|
+
* Get module name
|
|
40
|
+
* @returns {string} The name of the current module, sourced from module configuration
|
|
41
|
+
* @throws {NotReadyError} Throws error when framework instance is not initialized
|
|
42
42
|
*/
|
|
43
43
|
get name() {
|
|
44
44
|
return this.moduleConfig.name;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
48
|
-
* @returns {string}
|
|
49
|
-
* @throws {NotReadyError}
|
|
47
|
+
* Get module variable name
|
|
48
|
+
* @returns {string} A valid JavaScript variable name generated based on the module name
|
|
49
|
+
* @throws {NotReadyError} Throws error when framework instance is not initialized
|
|
50
50
|
*/
|
|
51
51
|
get varName() {
|
|
52
52
|
return "__" + this.name.replace(/[^a-zA-Z]/g, "_") + "__";
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
56
|
-
* @returns {string}
|
|
57
|
-
*
|
|
55
|
+
* Get the absolute path of the project root directory
|
|
56
|
+
* @returns {string} The absolute path of the project root directory
|
|
57
|
+
* If the configured root is a relative path, it is resolved to an absolute path based on the current working directory
|
|
58
58
|
*/
|
|
59
59
|
get root() {
|
|
60
60
|
const { root = cwd() } = this._options;
|
|
@@ -64,76 +64,77 @@ export class Esmx {
|
|
|
64
64
|
return path.resolve(cwd(), root);
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
68
|
-
* @returns {boolean}
|
|
69
|
-
*
|
|
67
|
+
* Determine if currently in production environment
|
|
68
|
+
* @returns {boolean} Environment flag
|
|
69
|
+
* Prioritizes the isProd in configuration, if not configured, judges based on process.env.NODE_ENV
|
|
70
70
|
*/
|
|
71
71
|
get isProd() {
|
|
72
72
|
return this._options?.isProd ?? process.env.NODE_ENV === "production";
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
76
|
-
* @returns {string}
|
|
77
|
-
*
|
|
75
|
+
* Get the base path of the module
|
|
76
|
+
* @returns {string} The base path of the module starting and ending with a slash
|
|
77
|
+
* Used to construct the access path for module assets
|
|
78
78
|
*/
|
|
79
79
|
get basePath() {
|
|
80
80
|
return `/${this.name}/`;
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
84
|
-
* @returns {string}
|
|
85
|
-
*
|
|
83
|
+
* Get the base path placeholder
|
|
84
|
+
* @returns {string} Base path placeholder or empty string
|
|
85
|
+
* Used for dynamically replacing the base path of the module at runtime, can be disabled through configuration
|
|
86
86
|
*/
|
|
87
87
|
get basePathPlaceholder() {
|
|
88
88
|
const varName = this._options.basePathPlaceholder;
|
|
89
89
|
if (varName === false) {
|
|
90
90
|
return "";
|
|
91
91
|
}
|
|
92
|
-
return varName ?? "[[[
|
|
92
|
+
return varName ?? "[[[___ESMX_DYNAMIC_BASE___]]]";
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
|
-
*
|
|
96
|
-
* @returns {COMMAND}
|
|
97
|
-
* @throws {NotReadyError}
|
|
95
|
+
* Get the currently executing command
|
|
96
|
+
* @returns {COMMAND} The command enumeration value currently being executed
|
|
97
|
+
* @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
|
|
98
98
|
*/
|
|
99
99
|
get command() {
|
|
100
100
|
return this.readied.command;
|
|
101
101
|
}
|
|
102
102
|
/**
|
|
103
|
-
*
|
|
104
|
-
* @returns {typeof COMMAND}
|
|
103
|
+
* Get the command enumeration type
|
|
104
|
+
* @returns {typeof COMMAND} Command enumeration type definition
|
|
105
105
|
*/
|
|
106
106
|
get COMMAND() {
|
|
107
107
|
return COMMAND;
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
|
-
*
|
|
111
|
-
* @returns {ParsedModuleConfig}
|
|
110
|
+
* Get module configuration information
|
|
111
|
+
* @returns {ParsedModuleConfig} Complete configuration information of the current module
|
|
112
112
|
*/
|
|
113
113
|
get moduleConfig() {
|
|
114
114
|
return this.readied.moduleConfig;
|
|
115
115
|
}
|
|
116
116
|
/**
|
|
117
|
-
*
|
|
118
|
-
* @returns {ParsedPackConfig}
|
|
117
|
+
* Get package configuration information
|
|
118
|
+
* @returns {ParsedPackConfig} Package-related configuration of the current module
|
|
119
119
|
*/
|
|
120
120
|
get packConfig() {
|
|
121
121
|
return this.readied.packConfig;
|
|
122
122
|
}
|
|
123
123
|
/**
|
|
124
|
-
*
|
|
124
|
+
* Get the static asset processing middleware for the application.
|
|
125
125
|
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* -
|
|
126
|
+
* This middleware is responsible for handling static asset requests for the application,
|
|
127
|
+
* providing different implementations based on the runtime environment:
|
|
128
|
+
* - Development environment: Supports real-time compilation and hot reloading of source code, uses no-cache strategy
|
|
129
|
+
* - Production environment: Handles built static assets, supports long-term caching for immutable files
|
|
129
130
|
*
|
|
130
|
-
* @returns {Middleware}
|
|
131
|
-
* @throws {NotReadyError}
|
|
131
|
+
* @returns {Middleware} Returns the static asset processing middleware function
|
|
132
|
+
* @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
|
|
132
133
|
*
|
|
133
134
|
* @example
|
|
134
135
|
* ```ts
|
|
135
136
|
* const server = http.createServer((req, res) => {
|
|
136
|
-
* //
|
|
137
|
+
* // Use middleware to handle static asset requests
|
|
137
138
|
* esmx.middleware(req, res, async () => {
|
|
138
139
|
* const rc = await esmx.render({ url: req.url });
|
|
139
140
|
* res.end(rc.html);
|
|
@@ -145,28 +146,29 @@ export class Esmx {
|
|
|
145
146
|
return this.readied.app.middleware;
|
|
146
147
|
}
|
|
147
148
|
/**
|
|
148
|
-
*
|
|
149
|
+
* Get the server-side rendering function for the application.
|
|
149
150
|
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* -
|
|
151
|
+
* This function is responsible for executing server-side rendering,
|
|
152
|
+
* providing different implementations based on the runtime environment:
|
|
153
|
+
* - Development environment: Loads server entry file from source code, supports hot reloading and real-time preview
|
|
154
|
+
* - Production environment: Loads built server entry file, provides optimized rendering performance
|
|
153
155
|
*
|
|
154
|
-
* @returns {(options?: RenderContextOptions) => Promise<RenderContext>}
|
|
155
|
-
* @throws {NotReadyError}
|
|
156
|
+
* @returns {(options?: RenderContextOptions) => Promise<RenderContext>} Returns the server-side rendering function
|
|
157
|
+
* @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
|
|
156
158
|
*
|
|
157
159
|
* @example
|
|
158
160
|
* ```ts
|
|
159
|
-
* //
|
|
161
|
+
* // Basic usage
|
|
160
162
|
* const rc = await esmx.render({
|
|
161
163
|
* params: { url: req.url }
|
|
162
164
|
* });
|
|
163
165
|
* res.end(rc.html);
|
|
164
166
|
*
|
|
165
|
-
* //
|
|
167
|
+
* // Advanced configuration
|
|
166
168
|
* const rc = await esmx.render({
|
|
167
|
-
* base: '', //
|
|
168
|
-
* importmapMode: 'inline', //
|
|
169
|
-
* entryName: 'default', //
|
|
169
|
+
* base: '', // Set base path
|
|
170
|
+
* importmapMode: 'inline', // Set import map mode
|
|
171
|
+
* entryName: 'default', // Specify render entry
|
|
170
172
|
* params: {
|
|
171
173
|
* url: req.url,
|
|
172
174
|
* state: { user: 'admin' }
|
|
@@ -181,21 +183,21 @@ export class Esmx {
|
|
|
181
183
|
this._options = options;
|
|
182
184
|
}
|
|
183
185
|
/**
|
|
184
|
-
*
|
|
186
|
+
* Initialize the Esmx framework instance.
|
|
185
187
|
*
|
|
186
|
-
*
|
|
187
|
-
* 1.
|
|
188
|
-
* 2.
|
|
189
|
-
* 3.
|
|
188
|
+
* This method executes the following core initialization process:
|
|
189
|
+
* 1. Parse project configuration (package.json, module configuration, package configuration, etc.)
|
|
190
|
+
* 2. Create application instance (development or production environment)
|
|
191
|
+
* 3. Execute corresponding lifecycle methods based on the command
|
|
190
192
|
*
|
|
191
|
-
* @param command -
|
|
192
|
-
* - dev:
|
|
193
|
-
* - build:
|
|
194
|
-
* - preview:
|
|
195
|
-
* - start:
|
|
193
|
+
* @param command - Framework running command
|
|
194
|
+
* - dev: Start development server with hot reload support
|
|
195
|
+
* - build: Build production artifacts
|
|
196
|
+
* - preview: Preview build artifacts
|
|
197
|
+
* - start: Start production environment server
|
|
196
198
|
*
|
|
197
|
-
* @returns
|
|
198
|
-
* @throws {Error}
|
|
199
|
+
* @returns Returns true for successful initialization
|
|
200
|
+
* @throws {Error} Throws error when initializing repeatedly
|
|
199
201
|
*
|
|
200
202
|
* @example
|
|
201
203
|
* ```ts
|
|
@@ -203,32 +205,32 @@ export class Esmx {
|
|
|
203
205
|
* import type { EsmxOptions } from '@esmx/core';
|
|
204
206
|
*
|
|
205
207
|
* export default {
|
|
206
|
-
* //
|
|
208
|
+
* // Development environment configuration
|
|
207
209
|
* async devApp(esmx) {
|
|
208
210
|
* return import('@esmx/rspack').then((m) =>
|
|
209
211
|
* m.createRspackHtmlApp(esmx, {
|
|
210
212
|
* config(context) {
|
|
211
|
-
* //
|
|
213
|
+
* // Custom Rspack configuration
|
|
212
214
|
* }
|
|
213
215
|
* })
|
|
214
216
|
* );
|
|
215
217
|
* },
|
|
216
218
|
*
|
|
217
|
-
* // HTTP
|
|
219
|
+
* // HTTP server configuration
|
|
218
220
|
* async server(esmx) {
|
|
219
221
|
* const server = http.createServer((req, res) => {
|
|
220
|
-
* //
|
|
222
|
+
* // Static file handling
|
|
221
223
|
* esmx.middleware(req, res, async () => {
|
|
222
|
-
* //
|
|
224
|
+
* // Pass rendering parameters
|
|
223
225
|
* const render = await esmx.render({
|
|
224
226
|
* params: { url: req.url }
|
|
225
227
|
* });
|
|
226
|
-
* //
|
|
228
|
+
* // Respond with HTML content
|
|
227
229
|
* res.end(render.html);
|
|
228
230
|
* });
|
|
229
231
|
* });
|
|
230
232
|
*
|
|
231
|
-
* //
|
|
233
|
+
* // Listen to port
|
|
232
234
|
* server.listen(3000, () => {
|
|
233
235
|
* console.log('http://localhost:3000');
|
|
234
236
|
* });
|
|
@@ -279,25 +281,25 @@ export class Esmx {
|
|
|
279
281
|
return true;
|
|
280
282
|
}
|
|
281
283
|
/**
|
|
282
|
-
*
|
|
284
|
+
* Destroy the Esmx framework instance, performing resource cleanup and connection closing operations.
|
|
283
285
|
*
|
|
284
|
-
*
|
|
285
|
-
* -
|
|
286
|
-
* -
|
|
287
|
-
* -
|
|
286
|
+
* This method is mainly used for resource cleanup in development environment, including:
|
|
287
|
+
* - Closing development servers (such as Rspack Dev Server)
|
|
288
|
+
* - Cleaning up temporary files and cache
|
|
289
|
+
* - Releasing system resources
|
|
288
290
|
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
+
* Note: In general, the framework automatically handles resource release, users do not need to manually call this method.
|
|
292
|
+
* Only use it when custom resource cleanup logic is needed.
|
|
291
293
|
*
|
|
292
|
-
* @returns
|
|
293
|
-
* - true:
|
|
294
|
-
* - false:
|
|
294
|
+
* @returns Returns a Promise that resolves to a boolean value
|
|
295
|
+
* - true: Cleanup successful or no cleanup needed
|
|
296
|
+
* - false: Cleanup failed
|
|
295
297
|
*
|
|
296
298
|
* @example
|
|
297
299
|
* ```ts
|
|
298
|
-
* //
|
|
300
|
+
* // Use when custom cleanup logic is needed
|
|
299
301
|
* process.once('SIGTERM', async () => {
|
|
300
|
-
* await esmx.destroy(); //
|
|
302
|
+
* await esmx.destroy(); // Clean up resources
|
|
301
303
|
* process.exit(0);
|
|
302
304
|
* });
|
|
303
305
|
* ```
|
|
@@ -310,21 +312,21 @@ export class Esmx {
|
|
|
310
312
|
return true;
|
|
311
313
|
}
|
|
312
314
|
/**
|
|
313
|
-
*
|
|
315
|
+
* Execute the application's build process.
|
|
314
316
|
*
|
|
315
|
-
*
|
|
316
|
-
* -
|
|
317
|
-
* -
|
|
318
|
-
* -
|
|
319
|
-
* -
|
|
317
|
+
* This method is responsible for executing the entire application build process, including:
|
|
318
|
+
* - Compiling source code
|
|
319
|
+
* - Generating production build artifacts
|
|
320
|
+
* - Optimizing and compressing code
|
|
321
|
+
* - Generating asset manifests
|
|
320
322
|
*
|
|
321
|
-
*
|
|
323
|
+
* The build process prints start and end times, as well as total duration and other information.
|
|
322
324
|
*
|
|
323
|
-
* @returns
|
|
324
|
-
* - true:
|
|
325
|
-
* - false:
|
|
325
|
+
* @returns Returns a Promise that resolves to a boolean value
|
|
326
|
+
* - true: Build successful or build method not implemented
|
|
327
|
+
* - false: Build failed
|
|
326
328
|
*
|
|
327
|
-
* @throws {NotReadyError}
|
|
329
|
+
* @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
|
|
328
330
|
*
|
|
329
331
|
* @example
|
|
330
332
|
* ```ts
|
|
@@ -332,20 +334,20 @@ export class Esmx {
|
|
|
332
334
|
* import type { EsmxOptions } from '@esmx/core';
|
|
333
335
|
*
|
|
334
336
|
* export default {
|
|
335
|
-
* //
|
|
337
|
+
* // Development environment configuration
|
|
336
338
|
* async devApp(esmx) {
|
|
337
339
|
* return import('@esmx/rspack').then((m) =>
|
|
338
340
|
* m.createRspackHtmlApp(esmx, {
|
|
339
341
|
* config(context) {
|
|
340
|
-
* //
|
|
342
|
+
* // Custom Rspack configuration
|
|
341
343
|
* }
|
|
342
344
|
* })
|
|
343
345
|
* );
|
|
344
346
|
* },
|
|
345
347
|
*
|
|
346
|
-
* //
|
|
348
|
+
* // Post-build processing
|
|
347
349
|
* async postBuild(esmx) {
|
|
348
|
-
* //
|
|
350
|
+
* // Generate static HTML after build completion
|
|
349
351
|
* const render = await esmx.render({
|
|
350
352
|
* params: { url: '/' }
|
|
351
353
|
* });
|
|
@@ -369,21 +371,21 @@ export class Esmx {
|
|
|
369
371
|
return successful ?? true;
|
|
370
372
|
}
|
|
371
373
|
/**
|
|
372
|
-
*
|
|
374
|
+
* Start HTTP server and configure server instance.
|
|
373
375
|
*
|
|
374
|
-
*
|
|
375
|
-
* -
|
|
376
|
-
* -
|
|
376
|
+
* This method is called in the following lifecycle of the framework:
|
|
377
|
+
* - Development environment (dev): Start development server, providing features like hot reload
|
|
378
|
+
* - Production environment (start): Start production server, providing production-grade performance
|
|
377
379
|
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
* -
|
|
381
|
-
* -
|
|
382
|
-
* -
|
|
383
|
-
* -
|
|
380
|
+
* The specific implementation of the server is provided by the user through the server configuration function in EsmxOptions.
|
|
381
|
+
* This function is responsible for:
|
|
382
|
+
* - Creating HTTP server instance
|
|
383
|
+
* - Configuring middleware and routes
|
|
384
|
+
* - Handling requests and responses
|
|
385
|
+
* - Starting server listening
|
|
384
386
|
*
|
|
385
|
-
* @returns
|
|
386
|
-
* @throws {NotReadyError}
|
|
387
|
+
* @returns Returns a Promise that resolves when the server startup is complete
|
|
388
|
+
* @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
|
|
387
389
|
*
|
|
388
390
|
* @example
|
|
389
391
|
* ```ts
|
|
@@ -392,12 +394,12 @@ export class Esmx {
|
|
|
392
394
|
* import type { EsmxOptions } from '@esmx/core';
|
|
393
395
|
*
|
|
394
396
|
* export default {
|
|
395
|
-
* //
|
|
397
|
+
* // Server configuration
|
|
396
398
|
* async server(esmx) {
|
|
397
399
|
* const server = http.createServer((req, res) => {
|
|
398
|
-
* //
|
|
400
|
+
* // Handle static assets
|
|
399
401
|
* esmx.middleware(req, res, async () => {
|
|
400
|
-
* //
|
|
402
|
+
* // Server-side rendering
|
|
401
403
|
* const render = await esmx.render({
|
|
402
404
|
* params: { url: req.url }
|
|
403
405
|
* });
|
|
@@ -405,7 +407,7 @@ export class Esmx {
|
|
|
405
407
|
* });
|
|
406
408
|
* });
|
|
407
409
|
*
|
|
408
|
-
* //
|
|
410
|
+
* // Start server
|
|
409
411
|
* server.listen(3000, () => {
|
|
410
412
|
* console.log('Server running at http://localhost:3000');
|
|
411
413
|
* });
|
|
@@ -417,19 +419,19 @@ export class Esmx {
|
|
|
417
419
|
await this._options?.server?.(this);
|
|
418
420
|
}
|
|
419
421
|
/**
|
|
420
|
-
*
|
|
422
|
+
* Execute post-build processing logic.
|
|
421
423
|
*
|
|
422
|
-
*
|
|
423
|
-
* -
|
|
424
|
-
* -
|
|
425
|
-
* -
|
|
426
|
-
* -
|
|
424
|
+
* This method is called after the application build is completed, used to perform additional resource processing, such as:
|
|
425
|
+
* - Generating static HTML files
|
|
426
|
+
* - Processing build artifacts
|
|
427
|
+
* - Executing deployment tasks
|
|
428
|
+
* - Sending build notifications
|
|
427
429
|
*
|
|
428
|
-
*
|
|
430
|
+
* The method automatically captures and handles exceptions during execution, ensuring it does not affect the main build process.
|
|
429
431
|
*
|
|
430
|
-
* @returns
|
|
431
|
-
* - true:
|
|
432
|
-
* - false:
|
|
432
|
+
* @returns Returns a Promise that resolves to a boolean value
|
|
433
|
+
* - true: Post-processing successful or no processing needed
|
|
434
|
+
* - false: Post-processing failed
|
|
433
435
|
*
|
|
434
436
|
* @example
|
|
435
437
|
* ```ts
|
|
@@ -437,9 +439,9 @@ export class Esmx {
|
|
|
437
439
|
* import type { EsmxOptions } from '@esmx/core';
|
|
438
440
|
*
|
|
439
441
|
* export default {
|
|
440
|
-
* //
|
|
442
|
+
* // Post-build processing
|
|
441
443
|
* async postBuild(esmx) {
|
|
442
|
-
* //
|
|
444
|
+
* // Generate static HTML for multiple pages
|
|
443
445
|
* const pages = ['/', '/about', '/404'];
|
|
444
446
|
*
|
|
445
447
|
* for (const url of pages) {
|
|
@@ -447,7 +449,7 @@ export class Esmx {
|
|
|
447
449
|
* params: { url }
|
|
448
450
|
* });
|
|
449
451
|
*
|
|
450
|
-
* //
|
|
452
|
+
* // Write static HTML file
|
|
451
453
|
* esmx.writeSync(
|
|
452
454
|
* esmx.resolvePath('dist/client', url.substring(1), 'index.html'),
|
|
453
455
|
* render.html
|
|
@@ -467,18 +469,18 @@ export class Esmx {
|
|
|
467
469
|
}
|
|
468
470
|
}
|
|
469
471
|
/**
|
|
470
|
-
*
|
|
472
|
+
* Resolve project relative path to absolute path
|
|
471
473
|
*
|
|
472
|
-
* @param projectPath -
|
|
473
|
-
* @param args -
|
|
474
|
-
* @returns
|
|
474
|
+
* @param projectPath - Project path type, such as 'dist/client', 'dist/server', etc.
|
|
475
|
+
* @param args - Path segments to be concatenated
|
|
476
|
+
* @returns Resolved absolute path
|
|
475
477
|
*
|
|
476
478
|
* @example
|
|
477
479
|
* ```ts
|
|
478
|
-
* //
|
|
480
|
+
* // Used in entry.node.ts
|
|
479
481
|
* async postBuild(esmx) {
|
|
480
482
|
* const outputPath = esmx.resolvePath('dist/client', 'index.html');
|
|
481
|
-
* //
|
|
483
|
+
* // Output: /project/root/dist/client/index.html
|
|
482
484
|
* }
|
|
483
485
|
* ```
|
|
484
486
|
*/
|
|
@@ -486,15 +488,15 @@ export class Esmx {
|
|
|
486
488
|
return resolvePath(this.root, projectPath, ...args);
|
|
487
489
|
}
|
|
488
490
|
/**
|
|
489
|
-
*
|
|
491
|
+
* Write file content synchronously
|
|
490
492
|
*
|
|
491
|
-
* @param filepath -
|
|
492
|
-
* @param data -
|
|
493
|
-
* @returns
|
|
493
|
+
* @param filepath - Absolute path of the file
|
|
494
|
+
* @param data - Data to be written, can be string, Buffer or object
|
|
495
|
+
* @returns Whether the write was successful
|
|
494
496
|
*
|
|
495
497
|
* @example
|
|
496
498
|
* ```ts
|
|
497
|
-
* //
|
|
499
|
+
* // Used in entry.node.ts
|
|
498
500
|
* async postBuild(esmx) {
|
|
499
501
|
* const htmlPath = esmx.resolvePath('dist/client', 'index.html');
|
|
500
502
|
* const success = esmx.writeSync(htmlPath, '<html>...</html>');
|
|
@@ -511,15 +513,15 @@ export class Esmx {
|
|
|
511
513
|
}
|
|
512
514
|
}
|
|
513
515
|
/**
|
|
514
|
-
*
|
|
516
|
+
* Write file content asynchronously
|
|
515
517
|
*
|
|
516
|
-
* @param filepath -
|
|
517
|
-
* @param data -
|
|
518
|
-
* @returns Promise<boolean>
|
|
518
|
+
* @param filepath - Absolute path of the file
|
|
519
|
+
* @param data - Data to be written, can be string, Buffer or object
|
|
520
|
+
* @returns Promise<boolean> Whether the write was successful
|
|
519
521
|
*
|
|
520
522
|
* @example
|
|
521
523
|
* ```ts
|
|
522
|
-
* //
|
|
524
|
+
* // Used in entry.node.ts
|
|
523
525
|
* async postBuild(esmx) {
|
|
524
526
|
* const htmlPath = esmx.resolvePath('dist/client', 'index.html');
|
|
525
527
|
* const success = await esmx.write(htmlPath, '<html>...</html>');
|
|
@@ -536,19 +538,19 @@ export class Esmx {
|
|
|
536
538
|
}
|
|
537
539
|
}
|
|
538
540
|
/**
|
|
539
|
-
*
|
|
541
|
+
* Read and parse JSON file synchronously
|
|
540
542
|
*
|
|
541
|
-
* @template T -
|
|
542
|
-
* @param filename - JSON
|
|
543
|
-
* @returns {T}
|
|
544
|
-
* @throws
|
|
543
|
+
* @template T - Expected JSON object type to return
|
|
544
|
+
* @param filename - Absolute path of the JSON file
|
|
545
|
+
* @returns {T} Parsed JSON object
|
|
546
|
+
* @throws Throws exception when file does not exist or JSON format is incorrect
|
|
545
547
|
*
|
|
546
548
|
* @example
|
|
547
549
|
* ```ts
|
|
548
|
-
* //
|
|
550
|
+
* // Used in entry.node.ts
|
|
549
551
|
* async server(esmx) {
|
|
550
552
|
* const manifest = esmx.readJsonSync<Manifest>(esmx.resolvePath('dist/client', 'manifest.json'));
|
|
551
|
-
* //
|
|
553
|
+
* // Use manifest object
|
|
552
554
|
* }
|
|
553
555
|
* ```
|
|
554
556
|
*/
|
|
@@ -556,19 +558,19 @@ export class Esmx {
|
|
|
556
558
|
return JSON.parse(fs.readFileSync(filename, "utf-8"));
|
|
557
559
|
}
|
|
558
560
|
/**
|
|
559
|
-
*
|
|
561
|
+
* Read and parse JSON file asynchronously
|
|
560
562
|
*
|
|
561
|
-
* @template T -
|
|
562
|
-
* @param filename - JSON
|
|
563
|
-
* @returns {Promise<T>}
|
|
564
|
-
* @throws
|
|
563
|
+
* @template T - Expected JSON object type to return
|
|
564
|
+
* @param filename - Absolute path of the JSON file
|
|
565
|
+
* @returns {Promise<T>} Parsed JSON object
|
|
566
|
+
* @throws Throws exception when file does not exist or JSON format is incorrect
|
|
565
567
|
*
|
|
566
568
|
* @example
|
|
567
569
|
* ```ts
|
|
568
|
-
* //
|
|
570
|
+
* // Used in entry.node.ts
|
|
569
571
|
* async server(esmx) {
|
|
570
572
|
* const manifest = await esmx.readJson<Manifest>(esmx.resolvePath('dist/client', 'manifest.json'));
|
|
571
|
-
* //
|
|
573
|
+
* // Use manifest object
|
|
572
574
|
* }
|
|
573
575
|
* ```
|
|
574
576
|
*/
|
|
@@ -576,36 +578,36 @@ export class Esmx {
|
|
|
576
578
|
return JSON.parse(await fsp.readFile(filename, "utf-8"));
|
|
577
579
|
}
|
|
578
580
|
/**
|
|
579
|
-
*
|
|
581
|
+
* Get build manifest list
|
|
580
582
|
*
|
|
581
583
|
* @description
|
|
582
|
-
*
|
|
583
|
-
* 1.
|
|
584
|
-
* -
|
|
585
|
-
* -
|
|
584
|
+
* This method is used to get the build manifest list for the specified target environment, including the following features:
|
|
585
|
+
* 1. **Cache Management**
|
|
586
|
+
* - Uses internal caching mechanism to avoid repeated loading
|
|
587
|
+
* - Returns immutable manifest list
|
|
586
588
|
*
|
|
587
|
-
* 2.
|
|
588
|
-
* -
|
|
589
|
-
* -
|
|
589
|
+
* 2. **Environment Adaptation**
|
|
590
|
+
* - Supports both client and server environments
|
|
591
|
+
* - Returns corresponding manifest information based on the target environment
|
|
590
592
|
*
|
|
591
|
-
* 3.
|
|
592
|
-
* -
|
|
593
|
-
* -
|
|
593
|
+
* 3. **Module Mapping**
|
|
594
|
+
* - Contains module export information
|
|
595
|
+
* - Records resource dependency relationships
|
|
594
596
|
*
|
|
595
|
-
* @param env -
|
|
596
|
-
* - 'client':
|
|
597
|
-
* - 'server':
|
|
598
|
-
* @returns
|
|
599
|
-
* @throws {NotReadyError}
|
|
597
|
+
* @param env - Target environment type
|
|
598
|
+
* - 'client': Client environment
|
|
599
|
+
* - 'server': Server environment
|
|
600
|
+
* @returns Returns read-only build manifest list
|
|
601
|
+
* @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
|
|
600
602
|
*
|
|
601
603
|
* @example
|
|
602
604
|
* ```ts
|
|
603
|
-
* //
|
|
605
|
+
* // Used in entry.node.ts
|
|
604
606
|
* async server(esmx) {
|
|
605
|
-
* //
|
|
607
|
+
* // Get client build manifest
|
|
606
608
|
* const manifests = await esmx.getManifestList('client');
|
|
607
609
|
*
|
|
608
|
-
* //
|
|
610
|
+
* // Find build information for a specific module
|
|
609
611
|
* const appModule = manifests.find(m => m.name === 'my-app');
|
|
610
612
|
* if (appModule) {
|
|
611
613
|
* console.log('App exports:', appModule.exports);
|
|
@@ -621,37 +623,37 @@ export class Esmx {
|
|
|
621
623
|
);
|
|
622
624
|
}
|
|
623
625
|
/**
|
|
624
|
-
*
|
|
626
|
+
* Get import map object
|
|
625
627
|
*
|
|
626
628
|
* @description
|
|
627
|
-
*
|
|
628
|
-
* 1.
|
|
629
|
-
* -
|
|
630
|
-
* -
|
|
631
|
-
* -
|
|
632
|
-
*
|
|
633
|
-
* 2.
|
|
634
|
-
* -
|
|
635
|
-
* -
|
|
636
|
-
*
|
|
637
|
-
* 3.
|
|
638
|
-
* -
|
|
639
|
-
* -
|
|
640
|
-
*
|
|
641
|
-
* @param env -
|
|
642
|
-
* - 'client':
|
|
643
|
-
* - 'server':
|
|
644
|
-
* @returns
|
|
645
|
-
* @throws {NotReadyError}
|
|
629
|
+
* This method is used to generate ES module import maps with the following features:
|
|
630
|
+
* 1. **Module Resolution**
|
|
631
|
+
* - Generate module mappings based on build manifests
|
|
632
|
+
* - Support both client and server environments
|
|
633
|
+
* - Automatically handle module path resolution
|
|
634
|
+
*
|
|
635
|
+
* 2. **Cache Optimization**
|
|
636
|
+
* - Use internal caching mechanism
|
|
637
|
+
* - Return immutable mapping objects
|
|
638
|
+
*
|
|
639
|
+
* 3. **Path Handling**
|
|
640
|
+
* - Automatically handle module paths
|
|
641
|
+
* - Support dynamic base paths
|
|
642
|
+
*
|
|
643
|
+
* @param env - Target environment type
|
|
644
|
+
* - 'client': Generate import map for browser environment
|
|
645
|
+
* - 'server': Generate import map for server environment
|
|
646
|
+
* @returns Returns read-only import map object
|
|
647
|
+
* @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
|
|
646
648
|
*
|
|
647
649
|
* @example
|
|
648
650
|
* ```ts
|
|
649
|
-
* //
|
|
651
|
+
* // Used in entry.node.ts
|
|
650
652
|
* async server(esmx) {
|
|
651
|
-
* //
|
|
653
|
+
* // Get client import map
|
|
652
654
|
* const importmap = await esmx.getImportMap('client');
|
|
653
655
|
*
|
|
654
|
-
* //
|
|
656
|
+
* // Custom HTML template
|
|
655
657
|
* const html = `
|
|
656
658
|
* <!DOCTYPE html>
|
|
657
659
|
* <html>
|
|
@@ -661,7 +663,7 @@ export class Esmx {
|
|
|
661
663
|
* <\/script>
|
|
662
664
|
* </head>
|
|
663
665
|
* <body>
|
|
664
|
-
* <!--
|
|
666
|
+
* <!-- Page content -->
|
|
665
667
|
* </body>
|
|
666
668
|
* </html>
|
|
667
669
|
* `;
|
|
@@ -674,7 +676,7 @@ export class Esmx {
|
|
|
674
676
|
const manifests = await this.getManifestList(env);
|
|
675
677
|
let json = {};
|
|
676
678
|
switch (env) {
|
|
677
|
-
case "client":
|
|
679
|
+
case "client": {
|
|
678
680
|
json = getImportMap({
|
|
679
681
|
manifests,
|
|
680
682
|
getScope(name, scope) {
|
|
@@ -685,6 +687,7 @@ export class Esmx {
|
|
|
685
687
|
}
|
|
686
688
|
});
|
|
687
689
|
break;
|
|
690
|
+
}
|
|
688
691
|
case "server":
|
|
689
692
|
json = getImportMap({
|
|
690
693
|
manifests,
|
|
@@ -705,44 +708,44 @@ export class Esmx {
|
|
|
705
708
|
});
|
|
706
709
|
}
|
|
707
710
|
/**
|
|
708
|
-
*
|
|
711
|
+
* Get client import map information
|
|
709
712
|
*
|
|
710
713
|
* @description
|
|
711
|
-
*
|
|
712
|
-
* 1.
|
|
713
|
-
* -
|
|
714
|
-
* -
|
|
715
|
-
* -
|
|
716
|
-
*
|
|
717
|
-
* 2. **JS
|
|
718
|
-
* -
|
|
719
|
-
* -
|
|
720
|
-
* -
|
|
721
|
-
*
|
|
722
|
-
*
|
|
723
|
-
* -
|
|
724
|
-
* -
|
|
725
|
-
* -
|
|
726
|
-
* -
|
|
727
|
-
*
|
|
728
|
-
* @param mode -
|
|
729
|
-
* - 'inline':
|
|
730
|
-
* - 'js': JS
|
|
731
|
-
* @returns
|
|
732
|
-
* - src: JS
|
|
733
|
-
* - filepath: JS
|
|
734
|
-
* - code: HTML script
|
|
735
|
-
* @throws {NotReadyError}
|
|
714
|
+
* This method is used to generate import map code for client environment, supporting two modes:
|
|
715
|
+
* 1. **Inline Mode (inline)**
|
|
716
|
+
* - Inline import map directly into HTML
|
|
717
|
+
* - Reduce additional network requests
|
|
718
|
+
* - Suitable for scenarios with smaller import maps
|
|
719
|
+
*
|
|
720
|
+
* 2. **JS File Mode (js)**
|
|
721
|
+
* - Generate standalone JS file
|
|
722
|
+
* - Support browser caching
|
|
723
|
+
* - Suitable for scenarios with larger import maps
|
|
724
|
+
*
|
|
725
|
+
* Core Features:
|
|
726
|
+
* - Automatically handle dynamic base paths
|
|
727
|
+
* - Support module path runtime replacement
|
|
728
|
+
* - Optimize caching strategy
|
|
729
|
+
* - Ensure module loading order
|
|
730
|
+
*
|
|
731
|
+
* @param mode - Import map mode
|
|
732
|
+
* - 'inline': Inline mode, returns HTML script tag
|
|
733
|
+
* - 'js': JS file mode, returns information with file path
|
|
734
|
+
* @returns Returns import map related information
|
|
735
|
+
* - src: URL of the JS file (only in js mode)
|
|
736
|
+
* - filepath: Local path of the JS file (only in js mode)
|
|
737
|
+
* - code: HTML script tag content
|
|
738
|
+
* @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
|
|
736
739
|
*
|
|
737
740
|
* @example
|
|
738
741
|
* ```ts
|
|
739
|
-
* //
|
|
742
|
+
* // Used in entry.node.ts
|
|
740
743
|
* async server(esmx) {
|
|
741
744
|
* const server = express();
|
|
742
745
|
* server.use(esmx.middleware);
|
|
743
746
|
*
|
|
744
747
|
* server.get('*', async (req, res) => {
|
|
745
|
-
* //
|
|
748
|
+
* // Use JS file mode
|
|
746
749
|
* const result = await esmx.render({
|
|
747
750
|
* importmapMode: 'js',
|
|
748
751
|
* params: { url: req.url }
|
|
@@ -750,7 +753,7 @@ export class Esmx {
|
|
|
750
753
|
* res.send(result.html);
|
|
751
754
|
* });
|
|
752
755
|
*
|
|
753
|
-
* //
|
|
756
|
+
* // Or use inline mode
|
|
754
757
|
* server.get('/inline', async (req, res) => {
|
|
755
758
|
* const result = await esmx.render({
|
|
756
759
|
* importmapMode: 'inline',
|
|
@@ -831,22 +834,22 @@ document.head.appendChild(script);
|
|
|
831
834
|
return {
|
|
832
835
|
src: null,
|
|
833
836
|
filepath: null,
|
|
834
|
-
code: `<script type="importmap">${serialize(importmap, { isJSON: true })}<\/script>`
|
|
837
|
+
code: `<script type="importmap">${serialize(importmap, { isJSON: true, unsafe: true })}<\/script>`
|
|
835
838
|
};
|
|
836
839
|
}
|
|
837
840
|
);
|
|
838
841
|
}
|
|
839
842
|
/**
|
|
840
|
-
*
|
|
843
|
+
* Get the list of static import paths for a module.
|
|
841
844
|
*
|
|
842
|
-
* @param env -
|
|
843
|
-
* @param specifier -
|
|
844
|
-
* @returns
|
|
845
|
-
* @throws {NotReadyError}
|
|
845
|
+
* @param env - Build target ('client' | 'server')
|
|
846
|
+
* @param specifier - Module specifier
|
|
847
|
+
* @returns Returns the list of static import paths, returns null if not found
|
|
848
|
+
* @throws {NotReadyError} Throws error when calling this method if the framework instance is not initialized
|
|
846
849
|
*
|
|
847
850
|
* @example
|
|
848
851
|
* ```ts
|
|
849
|
-
* //
|
|
852
|
+
* // Get static import paths for client entry module
|
|
850
853
|
* const paths = await esmx.getStaticImportPaths(
|
|
851
854
|
* 'client',
|
|
852
855
|
* `your-app-name/src/entry.client`
|