@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/render-context.d.ts
CHANGED
|
@@ -1,104 +1,104 @@
|
|
|
1
1
|
import serialize from 'serialize-javascript';
|
|
2
2
|
import type { Esmx } from './core';
|
|
3
3
|
/**
|
|
4
|
-
* RenderContext
|
|
4
|
+
* Configuration options interface for RenderContext
|
|
5
5
|
*
|
|
6
6
|
* @description
|
|
7
|
-
* RenderContextOptions
|
|
7
|
+
* RenderContextOptions is used to configure the behavior of RenderContext instances, including base path, entry name, parameters, and import map mode.
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* ```ts
|
|
11
|
-
* // 1.
|
|
12
|
-
* //
|
|
11
|
+
* // 1. Base path configuration example
|
|
12
|
+
* // Supports deploying static assets to different paths
|
|
13
13
|
* const rc = await esmx.render({
|
|
14
|
-
* //
|
|
14
|
+
* // Set base path to /esmx, all static assets will be loaded based on this path
|
|
15
15
|
* base: '/esmx',
|
|
16
|
-
* //
|
|
16
|
+
* // Other configurations...
|
|
17
17
|
* });
|
|
18
18
|
*
|
|
19
|
-
* // 2.
|
|
20
|
-
* //
|
|
19
|
+
* // 2. Multi-language site deployment example
|
|
20
|
+
* // Support multi-language sites through different base paths
|
|
21
21
|
* const rc = await esmx.render({
|
|
22
|
-
* base: '/cn', //
|
|
22
|
+
* base: '/cn', // Chinese site
|
|
23
23
|
* params: { lang: 'zh-CN' }
|
|
24
24
|
* });
|
|
25
25
|
*
|
|
26
|
-
* // 3.
|
|
26
|
+
* // 3. Import map mode configuration example
|
|
27
27
|
* const rc = await esmx.render({
|
|
28
|
-
* //
|
|
28
|
+
* // Use inline mode, suitable for small applications
|
|
29
29
|
* importmapMode: 'inline',
|
|
30
|
-
* //
|
|
30
|
+
* // Other configurations...
|
|
31
31
|
* });
|
|
32
32
|
* ```
|
|
33
33
|
*/
|
|
34
34
|
export interface RenderContextOptions {
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* Base path for static assets
|
|
37
37
|
* @description
|
|
38
|
-
* -
|
|
39
|
-
* -
|
|
40
|
-
* -
|
|
41
|
-
* -
|
|
38
|
+
* - Defaults to empty string
|
|
39
|
+
* - All static assets (JS, CSS, images, etc.) will be loaded based on this path
|
|
40
|
+
* - Supports runtime dynamic configuration without rebuilding
|
|
41
|
+
* - Commonly used for multi-language sites, micro-frontends, and other scenarios
|
|
42
42
|
*/
|
|
43
43
|
base?: string;
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
45
|
+
* Server-side rendering entry name
|
|
46
46
|
* @description
|
|
47
|
-
* -
|
|
48
|
-
* -
|
|
49
|
-
* -
|
|
47
|
+
* - Defaults to 'default'
|
|
48
|
+
* - Used to specify the entry function used during server-side rendering
|
|
49
|
+
* - Used when a module exports multiple rendering functions
|
|
50
50
|
*/
|
|
51
51
|
entryName?: string;
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
53
|
+
* Rendering parameters
|
|
54
54
|
* @description
|
|
55
|
-
* -
|
|
56
|
-
* -
|
|
57
|
-
* -
|
|
55
|
+
* - Can pass parameters of any type to the rendering function
|
|
56
|
+
* - Commonly used to pass request information (URL, query parameters, etc.)
|
|
57
|
+
* - Can be accessed through rc.params during server-side rendering
|
|
58
58
|
*/
|
|
59
59
|
params?: Record<string, any>;
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
61
|
+
* Define the generation mode for importmap
|
|
62
62
|
*
|
|
63
63
|
* @description
|
|
64
|
-
* ImportmapMode
|
|
65
|
-
* - `inline`:
|
|
66
|
-
* -
|
|
67
|
-
* -
|
|
68
|
-
* -
|
|
69
|
-
* - `js`:
|
|
70
|
-
* -
|
|
71
|
-
* -
|
|
72
|
-
* -
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* 1.
|
|
76
|
-
* -
|
|
77
|
-
* -
|
|
78
|
-
* -
|
|
79
|
-
* 2.
|
|
80
|
-
* -
|
|
81
|
-
* -
|
|
82
|
-
* -
|
|
83
|
-
* 3.
|
|
84
|
-
* -
|
|
85
|
-
* -
|
|
86
|
-
* -
|
|
64
|
+
* ImportmapMode is used to control the generation method of importmap, supporting two modes:
|
|
65
|
+
* - `inline`: Inline importmap content directly into HTML (default value), suitable for the following scenarios:
|
|
66
|
+
* - Need to reduce the number of HTTP requests
|
|
67
|
+
* - Importmap content is small
|
|
68
|
+
* - High requirements for first-screen loading performance
|
|
69
|
+
* - `js`: Generate importmap content as an independent JS file, suitable for the following scenarios:
|
|
70
|
+
* - Importmap content is large
|
|
71
|
+
* - Need to utilize browser caching mechanisms
|
|
72
|
+
* - Multiple pages share the same importmap
|
|
73
|
+
*
|
|
74
|
+
* Reasons for choosing 'inline' as the default value:
|
|
75
|
+
* 1. Simple and direct
|
|
76
|
+
* - Reduce additional HTTP requests
|
|
77
|
+
* - No additional resource management required
|
|
78
|
+
* - Suitable for most application scenarios
|
|
79
|
+
* 2. First-screen performance
|
|
80
|
+
* - Avoid additional network requests
|
|
81
|
+
* - Ensure import maps are immediately available
|
|
82
|
+
* - Reduce page loading time
|
|
83
|
+
* 3. Easy to debug
|
|
84
|
+
* - Import maps are directly visible
|
|
85
|
+
* - Facilitate problem diagnosis
|
|
86
|
+
* - Simplify development process
|
|
87
87
|
*
|
|
88
88
|
* @example
|
|
89
89
|
* ```ts
|
|
90
|
-
* //
|
|
90
|
+
* // Use inline mode (default)
|
|
91
91
|
* const rc = await esmx.render({
|
|
92
92
|
* params: { url: req.url }
|
|
93
93
|
* });
|
|
94
94
|
*
|
|
95
|
-
* //
|
|
95
|
+
* // Explicitly specify inline mode
|
|
96
96
|
* const rc = await esmx.render({
|
|
97
97
|
* importmapMode: 'inline',
|
|
98
98
|
* params: { url: req.url }
|
|
99
99
|
* });
|
|
100
100
|
*
|
|
101
|
-
* //
|
|
101
|
+
* // Use JS file mode
|
|
102
102
|
* const rc = await esmx.render({
|
|
103
103
|
* importmapMode: 'js',
|
|
104
104
|
* params: { url: req.url }
|
|
@@ -108,47 +108,47 @@ export interface RenderContextOptions {
|
|
|
108
108
|
importmapMode?: ImportmapMode;
|
|
109
109
|
}
|
|
110
110
|
/**
|
|
111
|
-
*
|
|
111
|
+
* Server-side rendering function
|
|
112
112
|
*/
|
|
113
113
|
export type ServerRenderHandle = (rc: RenderContext) => Promise<void>;
|
|
114
114
|
/**
|
|
115
|
-
*
|
|
115
|
+
* Render resource file list interface
|
|
116
116
|
* @description
|
|
117
|
-
* RenderFiles
|
|
117
|
+
* The RenderFiles interface defines various static assets collected during the server-side rendering process:
|
|
118
118
|
*
|
|
119
|
-
* 1.
|
|
120
|
-
* - css:
|
|
121
|
-
* - modulepreload:
|
|
122
|
-
* - js: JavaScript
|
|
123
|
-
* - resources:
|
|
119
|
+
* 1. **Resource Types**
|
|
120
|
+
* - css: List of stylesheet files
|
|
121
|
+
* - modulepreload: List of ESM modules that need to be preloaded
|
|
122
|
+
* - js: List of JavaScript files
|
|
123
|
+
* - resources: List of other resource files
|
|
124
124
|
*
|
|
125
|
-
* 2.
|
|
126
|
-
* -
|
|
127
|
-
* -
|
|
128
|
-
* -
|
|
125
|
+
* 2. **Use Cases**
|
|
126
|
+
* - Automatically collected in the commit() method
|
|
127
|
+
* - Injected through methods like preload(), css(), etc.
|
|
128
|
+
* - Supports base path configuration
|
|
129
129
|
*
|
|
130
130
|
* @example
|
|
131
131
|
* ```ts
|
|
132
|
-
* // 1.
|
|
132
|
+
* // 1. Resource collection
|
|
133
133
|
* await rc.commit();
|
|
134
134
|
*
|
|
135
|
-
* // 2.
|
|
135
|
+
* // 2. Resource injection
|
|
136
136
|
* rc.html = `
|
|
137
137
|
* <!DOCTYPE html>
|
|
138
138
|
* <html>
|
|
139
139
|
* <head>
|
|
140
|
-
* <!--
|
|
140
|
+
* <!-- Preload resources -->
|
|
141
141
|
* ${rc.preload()}
|
|
142
|
-
* <!--
|
|
142
|
+
* <!-- Inject stylesheets -->
|
|
143
143
|
* ${rc.css()}
|
|
144
144
|
* </head>
|
|
145
145
|
* <body>
|
|
146
146
|
* ${html}
|
|
147
|
-
* <!--
|
|
147
|
+
* <!-- Inject import map -->
|
|
148
148
|
* ${rc.importmap()}
|
|
149
|
-
* <!--
|
|
149
|
+
* <!-- Inject client entry -->
|
|
150
150
|
* ${rc.moduleEntry()}
|
|
151
|
-
* <!--
|
|
151
|
+
* <!-- Preload modules -->
|
|
152
152
|
* ${rc.modulePreload()}
|
|
153
153
|
* </body>
|
|
154
154
|
* </html>
|
|
@@ -157,64 +157,64 @@ export type ServerRenderHandle = (rc: RenderContext) => Promise<void>;
|
|
|
157
157
|
*/
|
|
158
158
|
export interface RenderFiles {
|
|
159
159
|
/**
|
|
160
|
-
* JavaScript
|
|
160
|
+
* List of JavaScript files
|
|
161
161
|
*/
|
|
162
162
|
js: string[];
|
|
163
163
|
/**
|
|
164
|
-
* CSS
|
|
164
|
+
* List of CSS files
|
|
165
165
|
*/
|
|
166
166
|
css: string[];
|
|
167
167
|
/**
|
|
168
|
-
*
|
|
168
|
+
* List of ESM modules that need to be preloaded
|
|
169
169
|
*/
|
|
170
170
|
modulepreload: string[];
|
|
171
171
|
/**
|
|
172
|
-
*
|
|
172
|
+
* List of other resource files (images, fonts, etc.)
|
|
173
173
|
*/
|
|
174
174
|
resources: string[];
|
|
175
175
|
}
|
|
176
176
|
/**
|
|
177
|
-
*
|
|
177
|
+
* Define the generation mode for importmap
|
|
178
178
|
*
|
|
179
179
|
* @description
|
|
180
|
-
* ImportmapMode
|
|
181
|
-
* - `inline`:
|
|
182
|
-
* -
|
|
183
|
-
* -
|
|
184
|
-
* -
|
|
185
|
-
* - `js`:
|
|
186
|
-
* -
|
|
187
|
-
* -
|
|
188
|
-
* -
|
|
180
|
+
* ImportmapMode is used to control the generation method of importmap, supporting two modes:
|
|
181
|
+
* - `inline`: Inline importmap content directly into HTML (default value), suitable for the following scenarios:
|
|
182
|
+
* - Need to reduce the number of HTTP requests
|
|
183
|
+
* - Importmap content is small
|
|
184
|
+
* - High requirements for first-screen loading performance
|
|
185
|
+
* - `js`: Generate importmap content as an independent JS file, suitable for the following scenarios:
|
|
186
|
+
* - Importmap content is large
|
|
187
|
+
* - Need to utilize browser caching mechanisms
|
|
188
|
+
* - Multiple pages share the same importmap
|
|
189
189
|
*
|
|
190
|
-
*
|
|
191
|
-
* 1.
|
|
192
|
-
* -
|
|
193
|
-
* -
|
|
194
|
-
* -
|
|
195
|
-
* 2.
|
|
196
|
-
* -
|
|
197
|
-
* -
|
|
198
|
-
* -
|
|
199
|
-
* 3.
|
|
200
|
-
* -
|
|
201
|
-
* -
|
|
202
|
-
* -
|
|
190
|
+
* Reasons for choosing 'inline' as the default value:
|
|
191
|
+
* 1. Simple and direct
|
|
192
|
+
* - Reduce additional HTTP requests
|
|
193
|
+
* - No additional resource management required
|
|
194
|
+
* - Suitable for most application scenarios
|
|
195
|
+
* 2. First-screen performance
|
|
196
|
+
* - Avoid additional network requests
|
|
197
|
+
* - Ensure import maps are immediately available
|
|
198
|
+
* - Reduce page loading time
|
|
199
|
+
* 3. Easy to debug
|
|
200
|
+
* - Import maps are directly visible
|
|
201
|
+
* - Facilitate problem diagnosis
|
|
202
|
+
* - Simplify development process
|
|
203
203
|
*
|
|
204
204
|
* @example
|
|
205
205
|
* ```ts
|
|
206
|
-
* //
|
|
206
|
+
* // Use inline mode (default)
|
|
207
207
|
* const rc = await esmx.render({
|
|
208
208
|
* params: { url: req.url }
|
|
209
209
|
* });
|
|
210
210
|
*
|
|
211
|
-
* //
|
|
211
|
+
* // Explicitly specify inline mode
|
|
212
212
|
* const rc = await esmx.render({
|
|
213
213
|
* importmapMode: 'inline',
|
|
214
214
|
* params: { url: req.url }
|
|
215
215
|
* });
|
|
216
216
|
*
|
|
217
|
-
* //
|
|
217
|
+
* // Use JS file mode
|
|
218
218
|
* const rc = await esmx.render({
|
|
219
219
|
* importmapMode: 'js',
|
|
220
220
|
* params: { url: req.url }
|
|
@@ -223,59 +223,59 @@ export interface RenderFiles {
|
|
|
223
223
|
*/
|
|
224
224
|
export type ImportmapMode = 'inline' | 'js';
|
|
225
225
|
/**
|
|
226
|
-
* RenderContext
|
|
226
|
+
* RenderContext is the core class in the Esmx framework, responsible for resource management and HTML generation during server-side rendering (SSR)
|
|
227
227
|
*
|
|
228
228
|
* @description
|
|
229
|
-
* RenderContext
|
|
230
|
-
* 1.
|
|
231
|
-
* -
|
|
232
|
-
* -
|
|
233
|
-
* -
|
|
229
|
+
* RenderContext has the following core features:
|
|
230
|
+
* 1. **ESM-based module system**
|
|
231
|
+
* - Adopts modern ECMAScript Modules standard
|
|
232
|
+
* - Supports native module imports and exports
|
|
233
|
+
* - Implements better code splitting and on-demand loading
|
|
234
234
|
*
|
|
235
|
-
* 2.
|
|
236
|
-
* -
|
|
237
|
-
* -
|
|
238
|
-
* -
|
|
235
|
+
* 2. **Intelligent dependency collection**
|
|
236
|
+
* - Dynamically collects dependencies based on actual rendering paths
|
|
237
|
+
* - Avoids unnecessary resource loading
|
|
238
|
+
* - Supports async components and dynamic imports
|
|
239
239
|
*
|
|
240
|
-
* 3.
|
|
241
|
-
* -
|
|
242
|
-
* -
|
|
243
|
-
* -
|
|
240
|
+
* 3. **Precise resource injection**
|
|
241
|
+
* - Strictly controls resource loading order
|
|
242
|
+
* - Optimizes first-screen loading performance
|
|
243
|
+
* - Ensures reliability of client-side hydration
|
|
244
244
|
*
|
|
245
|
-
* 4.
|
|
246
|
-
* -
|
|
247
|
-
* -
|
|
248
|
-
* -
|
|
245
|
+
* 4. **Flexible configuration mechanism**
|
|
246
|
+
* - Supports dynamic base path configuration
|
|
247
|
+
* - Provides multiple import map modes
|
|
248
|
+
* - Adapts to different deployment scenarios
|
|
249
249
|
*
|
|
250
250
|
* @example
|
|
251
251
|
* ```ts
|
|
252
252
|
* export default async (rc: RenderContext) => {
|
|
253
|
-
* // 1.
|
|
253
|
+
* // 1. Render page content and collect dependencies
|
|
254
254
|
* const app = createApp();
|
|
255
255
|
* const html = await renderToString(app, {
|
|
256
256
|
* importMetaSet: rc.importMetaSet
|
|
257
257
|
* });
|
|
258
258
|
*
|
|
259
|
-
* // 2.
|
|
259
|
+
* // 2. Commit dependency collection
|
|
260
260
|
* await rc.commit();
|
|
261
261
|
*
|
|
262
|
-
* // 3.
|
|
262
|
+
* // 3. Generate complete HTML
|
|
263
263
|
* rc.html = `
|
|
264
264
|
* <!DOCTYPE html>
|
|
265
265
|
* <html>
|
|
266
266
|
* <head>
|
|
267
|
-
* <!--
|
|
267
|
+
* <!-- Preload CSS and JS resources to start loading early for performance optimization -->
|
|
268
268
|
* ${rc.preload()}
|
|
269
|
-
* <!--
|
|
269
|
+
* <!-- Inject first-screen stylesheets to avoid page flickering -->
|
|
270
270
|
* ${rc.css()}
|
|
271
271
|
* </head>
|
|
272
272
|
* <body>
|
|
273
273
|
* ${html}
|
|
274
|
-
* <!--
|
|
274
|
+
* <!-- Inject module import map to define path resolution rules for ESM modules -->
|
|
275
275
|
* ${rc.importmap()}
|
|
276
|
-
* <!--
|
|
276
|
+
* <!-- Inject client entry module, must be executed after importmap -->
|
|
277
277
|
* ${rc.moduleEntry()}
|
|
278
|
-
* <!--
|
|
278
|
+
* <!-- Preload module dependencies, optimized loading based on dependencies collected during actual rendering -->
|
|
279
279
|
* ${rc.modulePreload()}
|
|
280
280
|
* </body>
|
|
281
281
|
* </html>
|
|
@@ -286,35 +286,35 @@ export type ImportmapMode = 'inline' | 'js';
|
|
|
286
286
|
export declare class RenderContext {
|
|
287
287
|
esmx: Esmx;
|
|
288
288
|
/**
|
|
289
|
-
*
|
|
289
|
+
* Redirect address
|
|
290
290
|
* @description
|
|
291
|
-
* -
|
|
292
|
-
* -
|
|
293
|
-
* -
|
|
291
|
+
* - Defaults to null, indicating no redirect
|
|
292
|
+
* - When set, the server can perform HTTP redirection based on this value
|
|
293
|
+
* - Commonly used for scenarios like login verification, permission control, etc.
|
|
294
294
|
*
|
|
295
295
|
* @example
|
|
296
296
|
* ```ts
|
|
297
|
-
* // 1.
|
|
297
|
+
* // 1. Login verification example
|
|
298
298
|
* export default async (rc: RenderContext) => {
|
|
299
299
|
* if (!isLoggedIn()) {
|
|
300
300
|
* rc.redirect = '/login';
|
|
301
301
|
* rc.status = 302;
|
|
302
302
|
* return;
|
|
303
303
|
* }
|
|
304
|
-
* //
|
|
304
|
+
* // Continue rendering page...
|
|
305
305
|
* };
|
|
306
306
|
*
|
|
307
|
-
* // 2.
|
|
307
|
+
* // 2. Permission control example
|
|
308
308
|
* export default async (rc: RenderContext) => {
|
|
309
309
|
* if (!hasPermission()) {
|
|
310
310
|
* rc.redirect = '/403';
|
|
311
311
|
* rc.status = 403;
|
|
312
312
|
* return;
|
|
313
313
|
* }
|
|
314
|
-
* //
|
|
314
|
+
* // Continue rendering page...
|
|
315
315
|
* };
|
|
316
316
|
*
|
|
317
|
-
* // 3.
|
|
317
|
+
* // 3. Server-side processing example
|
|
318
318
|
* app.use(async (req, res) => {
|
|
319
319
|
* const rc = await esmx.render({
|
|
320
320
|
* params: {
|
|
@@ -322,7 +322,7 @@ export declare class RenderContext {
|
|
|
322
322
|
* }
|
|
323
323
|
* });
|
|
324
324
|
*
|
|
325
|
-
* //
|
|
325
|
+
* // Handle redirect
|
|
326
326
|
* if (rc.redirect) {
|
|
327
327
|
* res.statusCode = rc.status || 302;
|
|
328
328
|
* res.setHeader('Location', rc.redirect);
|
|
@@ -330,49 +330,49 @@ export declare class RenderContext {
|
|
|
330
330
|
* return;
|
|
331
331
|
* }
|
|
332
332
|
*
|
|
333
|
-
* //
|
|
333
|
+
* // Set status code
|
|
334
334
|
* if (rc.status) {
|
|
335
335
|
* res.statusCode = rc.status;
|
|
336
336
|
* }
|
|
337
337
|
*
|
|
338
|
-
* //
|
|
338
|
+
* // Respond with HTML content
|
|
339
339
|
* res.end(rc.html);
|
|
340
340
|
* });
|
|
341
341
|
* ```
|
|
342
342
|
*/
|
|
343
343
|
redirect: string | null;
|
|
344
344
|
/**
|
|
345
|
-
* HTTP
|
|
345
|
+
* HTTP response status code
|
|
346
346
|
* @description
|
|
347
|
-
* -
|
|
348
|
-
* -
|
|
349
|
-
* -
|
|
350
|
-
* -
|
|
347
|
+
* - Defaults to null, indicating use of 200 status code
|
|
348
|
+
* - Can set any valid HTTP status code
|
|
349
|
+
* - Commonly used for scenarios like error handling, redirection, etc.
|
|
350
|
+
* - Usually used in conjunction with the redirect property
|
|
351
351
|
*
|
|
352
352
|
* @example
|
|
353
353
|
* ```ts
|
|
354
|
-
* // 1. 404
|
|
354
|
+
* // 1. 404 error handling example
|
|
355
355
|
* export default async (rc: RenderContext) => {
|
|
356
356
|
* const page = await findPage(rc.params.url);
|
|
357
357
|
* if (!page) {
|
|
358
358
|
* rc.status = 404;
|
|
359
|
-
* //
|
|
359
|
+
* // Render 404 page...
|
|
360
360
|
* return;
|
|
361
361
|
* }
|
|
362
|
-
* //
|
|
362
|
+
* // Continue rendering page...
|
|
363
363
|
* };
|
|
364
364
|
*
|
|
365
|
-
* // 2.
|
|
365
|
+
* // 2. Temporary redirect example
|
|
366
366
|
* export default async (rc: RenderContext) => {
|
|
367
367
|
* if (needMaintenance()) {
|
|
368
368
|
* rc.redirect = '/maintenance';
|
|
369
|
-
* rc.status = 307; //
|
|
369
|
+
* rc.status = 307; // Temporary redirect, keep request method unchanged
|
|
370
370
|
* return;
|
|
371
371
|
* }
|
|
372
|
-
* //
|
|
372
|
+
* // Continue rendering page...
|
|
373
373
|
* };
|
|
374
374
|
*
|
|
375
|
-
* // 3.
|
|
375
|
+
* // 3. Server-side processing example
|
|
376
376
|
* app.use(async (req, res) => {
|
|
377
377
|
* const rc = await esmx.render({
|
|
378
378
|
* params: {
|
|
@@ -380,7 +380,7 @@ export declare class RenderContext {
|
|
|
380
380
|
* }
|
|
381
381
|
* });
|
|
382
382
|
*
|
|
383
|
-
* //
|
|
383
|
+
* // Handle redirect
|
|
384
384
|
* if (rc.redirect) {
|
|
385
385
|
* res.statusCode = rc.status || 302;
|
|
386
386
|
* res.setHeader('Location', rc.redirect);
|
|
@@ -388,12 +388,12 @@ export declare class RenderContext {
|
|
|
388
388
|
* return;
|
|
389
389
|
* }
|
|
390
390
|
*
|
|
391
|
-
* //
|
|
391
|
+
* // Set status code
|
|
392
392
|
* if (rc.status) {
|
|
393
393
|
* res.statusCode = rc.status;
|
|
394
394
|
* }
|
|
395
395
|
*
|
|
396
|
-
* //
|
|
396
|
+
* // Respond with HTML content
|
|
397
397
|
* res.end(rc.html);
|
|
398
398
|
* });
|
|
399
399
|
* ```
|
|
@@ -401,80 +401,80 @@ export declare class RenderContext {
|
|
|
401
401
|
status: number | null;
|
|
402
402
|
private _html;
|
|
403
403
|
/**
|
|
404
|
-
*
|
|
404
|
+
* Base path for static assets
|
|
405
405
|
* @description
|
|
406
|
-
* base
|
|
406
|
+
* The base property is used to control the loading path of static assets and is the core of Esmx framework's dynamic base path configuration:
|
|
407
407
|
*
|
|
408
|
-
* 1.
|
|
409
|
-
* -
|
|
410
|
-
* -
|
|
411
|
-
* -
|
|
408
|
+
* 1. **Build-time Processing**
|
|
409
|
+
* - Static asset paths are marked with special placeholders: `[[[___ESMX_DYNAMIC_BASE___]]]/your-app-name/`
|
|
410
|
+
* - Placeholders are injected into all static asset reference paths
|
|
411
|
+
* - Supports various static assets like CSS, JavaScript, images, etc.
|
|
412
412
|
*
|
|
413
|
-
* 2.
|
|
414
|
-
* -
|
|
415
|
-
* - RenderContext
|
|
413
|
+
* 2. **Runtime Replacement**
|
|
414
|
+
* - Set the actual base path through the `base` parameter of `esmx.render()`
|
|
415
|
+
* - RenderContext automatically replaces placeholders in HTML with actual paths
|
|
416
416
|
*
|
|
417
|
-
* 3.
|
|
418
|
-
* -
|
|
419
|
-
* -
|
|
420
|
-
* -
|
|
417
|
+
* 3. **Technical Advantages**
|
|
418
|
+
* - Deployment flexibility: The same set of build artifacts can be deployed to any path
|
|
419
|
+
* - Performance optimization: Maintain the best caching strategy for static assets
|
|
420
|
+
* - Development-friendly: Simplify multi-environment configuration management
|
|
421
421
|
*
|
|
422
422
|
* @example
|
|
423
423
|
* ```ts
|
|
424
|
-
* // 1.
|
|
424
|
+
* // 1. Basic usage
|
|
425
425
|
* const rc = await esmx.render({
|
|
426
|
-
* base: '/esmx', //
|
|
426
|
+
* base: '/esmx', // Set base path
|
|
427
427
|
* params: { url: req.url }
|
|
428
428
|
* });
|
|
429
429
|
*
|
|
430
|
-
* // 2.
|
|
430
|
+
* // 2. Multi-language site example
|
|
431
431
|
* const rc = await esmx.render({
|
|
432
|
-
* base: '/cn', //
|
|
432
|
+
* base: '/cn', // Chinese site
|
|
433
433
|
* params: { lang: 'zh-CN' }
|
|
434
434
|
* });
|
|
435
435
|
*
|
|
436
|
-
* // 3.
|
|
436
|
+
* // 3. Micro-frontend application example
|
|
437
437
|
* const rc = await esmx.render({
|
|
438
|
-
* base: '/app1', //
|
|
438
|
+
* base: '/app1', // Sub-application 1
|
|
439
439
|
* params: { appId: 1 }
|
|
440
440
|
* });
|
|
441
441
|
* ```
|
|
442
442
|
*/
|
|
443
443
|
readonly base: string;
|
|
444
444
|
/**
|
|
445
|
-
*
|
|
445
|
+
* Server-side rendering entry function name
|
|
446
446
|
* @description
|
|
447
|
-
* entryName
|
|
447
|
+
* The entryName property is used to specify the entry function used during server-side rendering:
|
|
448
448
|
*
|
|
449
|
-
* 1.
|
|
450
|
-
* -
|
|
451
|
-
* -
|
|
452
|
-
* -
|
|
449
|
+
* 1. **Basic Usage**
|
|
450
|
+
* - Default value is 'default'
|
|
451
|
+
* - Used to select the rendering function to use from entry.server.ts
|
|
452
|
+
* - Supports scenarios where a module exports multiple rendering functions
|
|
453
453
|
*
|
|
454
|
-
* 2.
|
|
455
|
-
* -
|
|
456
|
-
* - A/B
|
|
457
|
-
* -
|
|
454
|
+
* 2. **Use Cases**
|
|
455
|
+
* - Multi-template rendering: Different pages use different rendering templates
|
|
456
|
+
* - A/B testing: The same page uses different rendering logic
|
|
457
|
+
* - Special rendering: Some pages need custom rendering processes
|
|
458
458
|
*
|
|
459
459
|
* @example
|
|
460
460
|
* ```ts
|
|
461
|
-
* // 1.
|
|
461
|
+
* // 1. Default entry function
|
|
462
462
|
* // entry.server.ts
|
|
463
463
|
* export default async (rc: RenderContext) => {
|
|
464
|
-
* //
|
|
464
|
+
* // Default rendering logic
|
|
465
465
|
* };
|
|
466
466
|
*
|
|
467
|
-
* // 2.
|
|
467
|
+
* // 2. Multiple entry functions
|
|
468
468
|
* // entry.server.ts
|
|
469
469
|
* export const mobile = async (rc: RenderContext) => {
|
|
470
|
-
* //
|
|
470
|
+
* // Mobile rendering logic
|
|
471
471
|
* };
|
|
472
472
|
*
|
|
473
473
|
* export const desktop = async (rc: RenderContext) => {
|
|
474
|
-
* //
|
|
474
|
+
* // Desktop rendering logic
|
|
475
475
|
* };
|
|
476
476
|
*
|
|
477
|
-
* // 3.
|
|
477
|
+
* // 3. Select entry function based on device type
|
|
478
478
|
* const rc = await esmx.render({
|
|
479
479
|
* entryName: isMobile ? 'mobile' : 'desktop',
|
|
480
480
|
* params: { url: req.url }
|
|
@@ -483,29 +483,29 @@ export declare class RenderContext {
|
|
|
483
483
|
*/
|
|
484
484
|
readonly entryName: string;
|
|
485
485
|
/**
|
|
486
|
-
*
|
|
486
|
+
* Rendering parameters
|
|
487
487
|
* @description
|
|
488
|
-
* params
|
|
488
|
+
* The params property is used to pass and access parameters during the server-side rendering process:
|
|
489
489
|
*
|
|
490
|
-
* 1.
|
|
491
|
-
* -
|
|
492
|
-
* -
|
|
493
|
-
* -
|
|
490
|
+
* 1. **Parameter Types**
|
|
491
|
+
* - Supports key-value pairs of any type
|
|
492
|
+
* - Defined through Record<string, any> type
|
|
493
|
+
* - Remains unchanged throughout the entire rendering lifecycle
|
|
494
494
|
*
|
|
495
|
-
* 2.
|
|
496
|
-
* -
|
|
497
|
-
* -
|
|
498
|
-
* -
|
|
499
|
-
* -
|
|
495
|
+
* 2. **Common Use Cases**
|
|
496
|
+
* - Pass request information (URL, query parameters, etc.)
|
|
497
|
+
* - Set page configuration (language, theme, etc.)
|
|
498
|
+
* - Inject environment variables (API address, version number, etc.)
|
|
499
|
+
* - Share server-side state (user information, permissions, etc.)
|
|
500
500
|
*
|
|
501
|
-
* 3.
|
|
502
|
-
* -
|
|
503
|
-
* -
|
|
504
|
-
* -
|
|
501
|
+
* 3. **Access Methods**
|
|
502
|
+
* - Accessed through rc.params in server-side rendering functions
|
|
503
|
+
* - Can destructure to get specific parameters
|
|
504
|
+
* - Supports setting default values
|
|
505
505
|
*
|
|
506
506
|
* @example
|
|
507
507
|
* ```ts
|
|
508
|
-
* // 1.
|
|
508
|
+
* // 1. Basic usage - Pass URL and language settings
|
|
509
509
|
* const rc = await esmx.render({
|
|
510
510
|
* params: {
|
|
511
511
|
* url: req.url,
|
|
@@ -513,7 +513,7 @@ export declare class RenderContext {
|
|
|
513
513
|
* }
|
|
514
514
|
* });
|
|
515
515
|
*
|
|
516
|
-
* // 2.
|
|
516
|
+
* // 2. Page configuration - Set theme and layout
|
|
517
517
|
* const rc = await esmx.render({
|
|
518
518
|
* params: {
|
|
519
519
|
* theme: 'dark',
|
|
@@ -521,7 +521,7 @@ export declare class RenderContext {
|
|
|
521
521
|
* }
|
|
522
522
|
* });
|
|
523
523
|
*
|
|
524
|
-
* // 3.
|
|
524
|
+
* // 3. Environment configuration - Inject API address
|
|
525
525
|
* const rc = await esmx.render({
|
|
526
526
|
* params: {
|
|
527
527
|
* apiBaseUrl: process.env.API_BASE_URL,
|
|
@@ -529,17 +529,17 @@ export declare class RenderContext {
|
|
|
529
529
|
* }
|
|
530
530
|
* });
|
|
531
531
|
*
|
|
532
|
-
* // 4.
|
|
532
|
+
* // 4. Use in rendering function
|
|
533
533
|
* export default async (rc: RenderContext) => {
|
|
534
|
-
* //
|
|
534
|
+
* // Destructure to get parameters
|
|
535
535
|
* const { url, lang = 'en' } = rc.params;
|
|
536
536
|
*
|
|
537
|
-
* //
|
|
537
|
+
* // Execute different logic based on parameters
|
|
538
538
|
* if (lang === 'zh-CN') {
|
|
539
|
-
* //
|
|
539
|
+
* // Chinese version processing...
|
|
540
540
|
* }
|
|
541
541
|
*
|
|
542
|
-
* //
|
|
542
|
+
* // Pass parameters to component
|
|
543
543
|
* const html = await renderToString(createApp({
|
|
544
544
|
* props: {
|
|
545
545
|
* currentUrl: url,
|
|
@@ -547,7 +547,7 @@ export declare class RenderContext {
|
|
|
547
547
|
* }
|
|
548
548
|
* }));
|
|
549
549
|
*
|
|
550
|
-
* //
|
|
550
|
+
* // Set HTML
|
|
551
551
|
* rc.html = `
|
|
552
552
|
* <!DOCTYPE html>
|
|
553
553
|
* <html lang="${lang}">
|
|
@@ -559,50 +559,50 @@ export declare class RenderContext {
|
|
|
559
559
|
*/
|
|
560
560
|
readonly params: Record<string, any>;
|
|
561
561
|
/**
|
|
562
|
-
*
|
|
562
|
+
* Module dependency collection set
|
|
563
563
|
* @description
|
|
564
|
-
* importMetaSet
|
|
564
|
+
* importMetaSet is the core of Esmx framework's intelligent dependency collection mechanism, used to track and record module dependencies during the server-side rendering process:
|
|
565
565
|
*
|
|
566
|
-
* 1.
|
|
567
|
-
* -
|
|
568
|
-
* -
|
|
569
|
-
* -
|
|
566
|
+
* 1. **On-demand Collection**
|
|
567
|
+
* - Automatically tracks and records module dependencies during the actual component rendering process
|
|
568
|
+
* - Only collects resources actually used during the current page rendering
|
|
569
|
+
* - Precisely records the module dependency relationships of each component
|
|
570
570
|
*
|
|
571
|
-
* 2.
|
|
572
|
-
* -
|
|
573
|
-
* -
|
|
574
|
-
* -
|
|
571
|
+
* 2. **Performance Optimization**
|
|
572
|
+
* - Avoids loading unused modules, significantly reducing first-screen loading time
|
|
573
|
+
* - Precisely controls resource loading order, optimizing page rendering performance
|
|
574
|
+
* - Automatically generates optimal import maps
|
|
575
575
|
*
|
|
576
|
-
* 3.
|
|
577
|
-
* -
|
|
578
|
-
* -
|
|
579
|
-
* -
|
|
576
|
+
* 3. **Usage**
|
|
577
|
+
* - Passed to renderToString in the rendering function
|
|
578
|
+
* - Framework automatically collects dependencies, no manual handling required
|
|
579
|
+
* - Supports dependency collection for async components and dynamic imports
|
|
580
580
|
*
|
|
581
581
|
* @example
|
|
582
582
|
* ```ts
|
|
583
|
-
* // 1.
|
|
583
|
+
* // 1. Basic usage
|
|
584
584
|
* const renderToString = (app: any, context: { importMetaSet: Set<ImportMeta> }) => {
|
|
585
|
-
* //
|
|
586
|
-
* //
|
|
587
|
-
* //
|
|
585
|
+
* // Automatically collect module dependencies during the rendering process
|
|
586
|
+
* // Framework will automatically call context.importMetaSet.add(import.meta) during component rendering
|
|
587
|
+
* // Developers do not need to manually handle dependency collection
|
|
588
588
|
* return '<div id="app">Hello World</div>';
|
|
589
589
|
* };
|
|
590
590
|
*
|
|
591
|
-
* //
|
|
591
|
+
* // Usage example
|
|
592
592
|
* const app = createApp();
|
|
593
593
|
* const html = await renderToString(app, {
|
|
594
594
|
* importMetaSet: rc.importMetaSet
|
|
595
595
|
* });
|
|
596
596
|
*
|
|
597
|
-
* // 2.
|
|
597
|
+
* // 2. Commit dependencies
|
|
598
598
|
* await rc.commit();
|
|
599
599
|
*
|
|
600
|
-
* // 3.
|
|
600
|
+
* // 3. Generate HTML
|
|
601
601
|
* rc.html = `
|
|
602
602
|
* <!DOCTYPE html>
|
|
603
603
|
* <html>
|
|
604
604
|
* <head>
|
|
605
|
-
* <!--
|
|
605
|
+
* <!-- Automatically inject resources based on collected dependencies -->
|
|
606
606
|
* ${rc.preload()}
|
|
607
607
|
* ${rc.css()}
|
|
608
608
|
* </head>
|
|
@@ -618,35 +618,35 @@ export declare class RenderContext {
|
|
|
618
618
|
*/
|
|
619
619
|
importMetaSet: Set<ImportMeta>;
|
|
620
620
|
/**
|
|
621
|
-
*
|
|
621
|
+
* Resource file list
|
|
622
622
|
* @description
|
|
623
|
-
* files
|
|
623
|
+
* The files property stores all static resource file paths collected during the server-side rendering process:
|
|
624
624
|
*
|
|
625
|
-
* 1.
|
|
626
|
-
* - js: JavaScript
|
|
627
|
-
* - css:
|
|
628
|
-
* - modulepreload:
|
|
629
|
-
* - importmap:
|
|
630
|
-
* - resources:
|
|
625
|
+
* 1. **Resource Types**
|
|
626
|
+
* - js: List of JavaScript files, containing all scripts and modules
|
|
627
|
+
* - css: List of stylesheet files
|
|
628
|
+
* - modulepreload: List of ESM modules that need to be preloaded
|
|
629
|
+
* - importmap: List of import map files
|
|
630
|
+
* - resources: List of other resource files (images, fonts, etc.)
|
|
631
631
|
*
|
|
632
|
-
* 2.
|
|
633
|
-
* -
|
|
634
|
-
* -
|
|
635
|
-
* -
|
|
632
|
+
* 2. **Use Cases**
|
|
633
|
+
* - Automatically collect and categorize resources in the commit() method
|
|
634
|
+
* - Inject resources into HTML through methods like preload(), css(), etc.
|
|
635
|
+
* - Supports base path configuration, implementing dynamic loading of resources
|
|
636
636
|
*
|
|
637
637
|
* @example
|
|
638
638
|
* ```ts
|
|
639
|
-
* // 1.
|
|
639
|
+
* // 1. Resource collection
|
|
640
640
|
* await rc.commit();
|
|
641
641
|
*
|
|
642
|
-
* // 2.
|
|
642
|
+
* // 2. Resource injection
|
|
643
643
|
* rc.html = `
|
|
644
644
|
* <!DOCTYPE html>
|
|
645
645
|
* <html>
|
|
646
646
|
* <head>
|
|
647
|
-
* <!--
|
|
647
|
+
* <!-- Preload resources -->
|
|
648
648
|
* ${rc.preload()}
|
|
649
|
-
* <!--
|
|
649
|
+
* <!-- Inject stylesheets -->
|
|
650
650
|
* ${rc.css()}
|
|
651
651
|
* </head>
|
|
652
652
|
* <body>
|
|
@@ -662,47 +662,47 @@ export declare class RenderContext {
|
|
|
662
662
|
files: RenderFiles;
|
|
663
663
|
private _importMap;
|
|
664
664
|
/**
|
|
665
|
-
*
|
|
665
|
+
* Define the generation mode for importmap
|
|
666
666
|
*
|
|
667
667
|
* @description
|
|
668
|
-
* ImportmapMode
|
|
669
|
-
* - `inline`:
|
|
670
|
-
* -
|
|
671
|
-
* -
|
|
672
|
-
* -
|
|
673
|
-
* - `js`:
|
|
674
|
-
* -
|
|
675
|
-
* -
|
|
676
|
-
* -
|
|
677
|
-
*
|
|
678
|
-
*
|
|
679
|
-
* 1.
|
|
680
|
-
* -
|
|
681
|
-
* -
|
|
682
|
-
* -
|
|
683
|
-
* 2.
|
|
684
|
-
* -
|
|
685
|
-
* -
|
|
686
|
-
* -
|
|
687
|
-
* 3.
|
|
688
|
-
* -
|
|
689
|
-
* -
|
|
690
|
-
* -
|
|
668
|
+
* ImportmapMode is used to control the generation method of importmap, supporting two modes:
|
|
669
|
+
* - `inline`: Inline importmap content directly into HTML (default value), suitable for the following scenarios:
|
|
670
|
+
* - Need to reduce the number of HTTP requests
|
|
671
|
+
* - Importmap content is small
|
|
672
|
+
* - High requirements for first-screen loading performance
|
|
673
|
+
* - `js`: Generate importmap content as an independent JS file, suitable for the following scenarios:
|
|
674
|
+
* - Importmap content is large
|
|
675
|
+
* - Need to utilize browser caching mechanisms
|
|
676
|
+
* - Multiple pages share the same importmap
|
|
677
|
+
*
|
|
678
|
+
* Reasons for choosing 'inline' as the default value:
|
|
679
|
+
* 1. Simple and direct
|
|
680
|
+
* - Reduce additional HTTP requests
|
|
681
|
+
* - No additional resource management required
|
|
682
|
+
* - Suitable for most application scenarios
|
|
683
|
+
* 2. First-screen performance
|
|
684
|
+
* - Avoid additional network requests
|
|
685
|
+
* - Ensure import maps are immediately available
|
|
686
|
+
* - Reduce page loading time
|
|
687
|
+
* 3. Easy to debug
|
|
688
|
+
* - Import maps are directly visible
|
|
689
|
+
* - Facilitate problem diagnosis
|
|
690
|
+
* - Simplify development process
|
|
691
691
|
*
|
|
692
692
|
* @example
|
|
693
693
|
* ```ts
|
|
694
|
-
* //
|
|
694
|
+
* // Use inline mode (default)
|
|
695
695
|
* const rc = await esmx.render({
|
|
696
696
|
* params: { url: req.url }
|
|
697
697
|
* });
|
|
698
698
|
*
|
|
699
|
-
* //
|
|
699
|
+
* // Explicitly specify inline mode
|
|
700
700
|
* const rc = await esmx.render({
|
|
701
701
|
* importmapMode: 'inline',
|
|
702
702
|
* params: { url: req.url }
|
|
703
703
|
* });
|
|
704
704
|
*
|
|
705
|
-
* //
|
|
705
|
+
* // Use JS file mode
|
|
706
706
|
* const rc = await esmx.render({
|
|
707
707
|
* importmapMode: 'js',
|
|
708
708
|
* params: { url: req.url }
|
|
@@ -711,25 +711,25 @@ export declare class RenderContext {
|
|
|
711
711
|
*/
|
|
712
712
|
importmapMode: ImportmapMode;
|
|
713
713
|
/**
|
|
714
|
-
* HTML
|
|
714
|
+
* HTML content
|
|
715
715
|
* @description
|
|
716
|
-
* html
|
|
716
|
+
* The html property is used to set and get the final generated HTML content:
|
|
717
717
|
*
|
|
718
|
-
* 1.
|
|
719
|
-
* -
|
|
720
|
-
* -
|
|
721
|
-
* -
|
|
718
|
+
* 1. **Base Path Replacement**
|
|
719
|
+
* - Automatically handles base path placeholders when setting HTML
|
|
720
|
+
* - Replaces `[[[___ESMX_DYNAMIC_BASE___]]]/your-app-name/` with the actual base path
|
|
721
|
+
* - Ensures all static asset reference paths are correct
|
|
722
722
|
*
|
|
723
|
-
* 2.
|
|
724
|
-
* -
|
|
725
|
-
* -
|
|
726
|
-
* -
|
|
723
|
+
* 2. **Use Cases**
|
|
724
|
+
* - Set HTML content generated by server-side rendering
|
|
725
|
+
* - Support dynamic base path configuration
|
|
726
|
+
* - Automatically handle static asset reference paths
|
|
727
727
|
*
|
|
728
728
|
* @example
|
|
729
729
|
* ```ts
|
|
730
|
-
* // 1.
|
|
730
|
+
* // 1. Basic usage
|
|
731
731
|
* export default async (rc: RenderContext) => {
|
|
732
|
-
* //
|
|
732
|
+
* // Set HTML content
|
|
733
733
|
* rc.html = `
|
|
734
734
|
* <!DOCTYPE html>
|
|
735
735
|
* <html>
|
|
@@ -747,15 +747,15 @@ export declare class RenderContext {
|
|
|
747
747
|
* `;
|
|
748
748
|
* };
|
|
749
749
|
*
|
|
750
|
-
* // 2.
|
|
750
|
+
* // 2. Dynamic base path
|
|
751
751
|
* const rc = await esmx.render({
|
|
752
|
-
* base: '/app', //
|
|
752
|
+
* base: '/app', // Set base path
|
|
753
753
|
* params: { url: req.url }
|
|
754
754
|
* });
|
|
755
755
|
*
|
|
756
|
-
* // HTML
|
|
757
|
-
* // [[[
|
|
758
|
-
* //
|
|
756
|
+
* // Placeholders in HTML will be automatically replaced:
|
|
757
|
+
* // [[[___ESMX_DYNAMIC_BASE___]]]/your-app-name/css/style.css
|
|
758
|
+
* // Replaced with:
|
|
759
759
|
* // /app/your-app-name/css/style.css
|
|
760
760
|
* ```
|
|
761
761
|
*/
|
|
@@ -763,23 +763,23 @@ export declare class RenderContext {
|
|
|
763
763
|
set html(html: string);
|
|
764
764
|
constructor(esmx: Esmx, options?: RenderContextOptions);
|
|
765
765
|
/**
|
|
766
|
-
*
|
|
766
|
+
* Serialize JavaScript object to string
|
|
767
767
|
* @description
|
|
768
|
-
* serialize
|
|
768
|
+
* The serialize method is used to serialize state data during the server-side rendering process for passing to the client:
|
|
769
769
|
*
|
|
770
|
-
* 1.
|
|
771
|
-
* -
|
|
772
|
-
* -
|
|
773
|
-
* -
|
|
770
|
+
* 1. **Main Uses**
|
|
771
|
+
* - Serialize server-side state data
|
|
772
|
+
* - Ensure data can be safely embedded in HTML
|
|
773
|
+
* - Support complex data structures (such as Date, RegExp, etc.)
|
|
774
774
|
*
|
|
775
|
-
* 2.
|
|
776
|
-
* -
|
|
777
|
-
* -
|
|
778
|
-
* -
|
|
775
|
+
* 2. **Security Handling**
|
|
776
|
+
* - Automatically escape special characters
|
|
777
|
+
* - Prevent XSS attacks
|
|
778
|
+
* - Maintain data type integrity
|
|
779
779
|
*
|
|
780
780
|
* @example
|
|
781
781
|
* ```ts
|
|
782
|
-
* // 1.
|
|
782
|
+
* // 1. Basic usage - Serialize state data
|
|
783
783
|
* export default async (rc: RenderContext) => {
|
|
784
784
|
* const state = {
|
|
785
785
|
* user: { id: 1, name: 'Alice' },
|
|
@@ -792,7 +792,7 @@ export declare class RenderContext {
|
|
|
792
792
|
* <html>
|
|
793
793
|
* <head>
|
|
794
794
|
* <script>
|
|
795
|
-
* //
|
|
795
|
+
* // Inject serialized state into global variable
|
|
796
796
|
* window.__INITIAL_STATE__ = ${rc.serialize(state)};
|
|
797
797
|
* </script>
|
|
798
798
|
* </head>
|
|
@@ -801,41 +801,41 @@ export declare class RenderContext {
|
|
|
801
801
|
* `;
|
|
802
802
|
* };
|
|
803
803
|
*
|
|
804
|
-
* // 2.
|
|
804
|
+
* // 2. Custom serialization options
|
|
805
805
|
* const state = { sensitive: 'data' };
|
|
806
806
|
* const serialized = rc.serialize(state, {
|
|
807
|
-
* isJSON: true, //
|
|
808
|
-
* unsafe: false //
|
|
807
|
+
* isJSON: true, // Use JSON compatible mode
|
|
808
|
+
* unsafe: false // Disable unsafe serialization
|
|
809
809
|
* });
|
|
810
810
|
* ```
|
|
811
811
|
*
|
|
812
|
-
* @param {any} input -
|
|
813
|
-
* @param {serialize.SerializeJSOptions} [options] -
|
|
814
|
-
* @returns {string}
|
|
812
|
+
* @param {any} input - Input data to be serialized
|
|
813
|
+
* @param {serialize.SerializeJSOptions} [options] - Serialization options
|
|
814
|
+
* @returns {string} Serialized string
|
|
815
815
|
*/
|
|
816
816
|
serialize(input: any, options?: serialize.SerializeJSOptions): string;
|
|
817
817
|
/**
|
|
818
|
-
*
|
|
818
|
+
* Serialize state data and inject it into HTML
|
|
819
819
|
* @description
|
|
820
|
-
* state
|
|
820
|
+
* The state method is used to serialize state data and inject it into HTML during server-side rendering, so that the client can restore these states when activating:
|
|
821
821
|
*
|
|
822
|
-
* 1.
|
|
823
|
-
* -
|
|
824
|
-
* -
|
|
825
|
-
* -
|
|
822
|
+
* 1. **Serialization Mechanism**
|
|
823
|
+
* - Use safe serialization methods to process data
|
|
824
|
+
* - Support complex data structures (objects, arrays, etc.)
|
|
825
|
+
* - Automatically handle special characters and XSS protection
|
|
826
826
|
*
|
|
827
|
-
* 2.
|
|
828
|
-
* -
|
|
829
|
-
* -
|
|
830
|
-
* -
|
|
827
|
+
* 2. **Use Cases**
|
|
828
|
+
* - Synchronize server-side state to client
|
|
829
|
+
* - Initialize client application state
|
|
830
|
+
* - Implement seamless server-side rendering to client activation
|
|
831
831
|
*
|
|
832
|
-
* @param varName
|
|
833
|
-
* @param data
|
|
834
|
-
* @returns
|
|
832
|
+
* @param varName Global variable name, used to access injected data on the client
|
|
833
|
+
* @param data Data object that needs to be serialized
|
|
834
|
+
* @returns Script tag string containing serialized data
|
|
835
835
|
*
|
|
836
836
|
* @example
|
|
837
837
|
* ```ts
|
|
838
|
-
* // 1.
|
|
838
|
+
* // 1. Basic usage - Inject user information
|
|
839
839
|
* export default async (rc: RenderContext) => {
|
|
840
840
|
* const userInfo = {
|
|
841
841
|
* id: 1,
|
|
@@ -856,12 +856,12 @@ export declare class RenderContext {
|
|
|
856
856
|
* `;
|
|
857
857
|
* };
|
|
858
858
|
*
|
|
859
|
-
* // 2.
|
|
860
|
-
* //
|
|
859
|
+
* // 2. Client-side usage
|
|
860
|
+
* // Can directly access injected data on the client
|
|
861
861
|
* const userInfo = window.__USER__;
|
|
862
|
-
* console.log(userInfo.name); //
|
|
862
|
+
* console.log(userInfo.name); // Output: 'John'
|
|
863
863
|
*
|
|
864
|
-
* // 3.
|
|
864
|
+
* // 3. Complex data structures
|
|
865
865
|
* export default async (rc: RenderContext) => {
|
|
866
866
|
* const appState = {
|
|
867
867
|
* user: {
|
|
@@ -893,42 +893,42 @@ export declare class RenderContext {
|
|
|
893
893
|
*/
|
|
894
894
|
state(varName: string, data: Record<string, any>): string;
|
|
895
895
|
/**
|
|
896
|
-
*
|
|
896
|
+
* Commit dependency collection and update resource list
|
|
897
897
|
* @description
|
|
898
|
-
* commit
|
|
899
|
-
*
|
|
900
|
-
* 1.
|
|
901
|
-
* -
|
|
902
|
-
* -
|
|
903
|
-
* -
|
|
904
|
-
* -
|
|
905
|
-
*
|
|
906
|
-
* 2.
|
|
907
|
-
* - js: JavaScript
|
|
908
|
-
* - css:
|
|
909
|
-
* - modulepreload:
|
|
910
|
-
* - importmap:
|
|
911
|
-
* - resources:
|
|
912
|
-
*
|
|
913
|
-
* 3.
|
|
914
|
-
* -
|
|
915
|
-
* -
|
|
916
|
-
* -
|
|
898
|
+
* The commit method is the core of RenderContext's dependency collection mechanism, responsible for handling all collected module dependencies and updating the file resource list:
|
|
899
|
+
*
|
|
900
|
+
* 1. **Dependency Processing Flow**
|
|
901
|
+
* - Collect all used modules from importMetaSet
|
|
902
|
+
* - Parse specific resources for each module based on manifest files
|
|
903
|
+
* - Handle different types of dependencies such as JS, CSS, resource files, etc.
|
|
904
|
+
* - Automatically handle module preloading and import maps
|
|
905
|
+
*
|
|
906
|
+
* 2. **Resource Classification**
|
|
907
|
+
* - js: JavaScript files, containing all scripts and modules
|
|
908
|
+
* - css: Stylesheet files
|
|
909
|
+
* - modulepreload: ESM modules that need to be preloaded
|
|
910
|
+
* - importmap: Import map files
|
|
911
|
+
* - resources: Other resource files (images, fonts, etc.)
|
|
912
|
+
*
|
|
913
|
+
* 3. **Path Processing**
|
|
914
|
+
* - Automatically add base path prefix
|
|
915
|
+
* - Ensure the correctness of resource paths
|
|
916
|
+
* - Support resource isolation for multi-application scenarios
|
|
917
917
|
*
|
|
918
918
|
* @example
|
|
919
919
|
* ```ts
|
|
920
|
-
* // 1.
|
|
920
|
+
* // 1. Basic usage
|
|
921
921
|
* export default async (rc: RenderContext) => {
|
|
922
|
-
* //
|
|
922
|
+
* // Render page and collect dependencies
|
|
923
923
|
* const app = createApp();
|
|
924
924
|
* const html = await renderToString(app, {
|
|
925
925
|
* importMetaSet: rc.importMetaSet
|
|
926
926
|
* });
|
|
927
927
|
*
|
|
928
|
-
* //
|
|
928
|
+
* // Commit dependency collection
|
|
929
929
|
* await rc.commit();
|
|
930
930
|
*
|
|
931
|
-
* //
|
|
931
|
+
* // Generate HTML
|
|
932
932
|
* rc.html = `
|
|
933
933
|
* <!DOCTYPE html>
|
|
934
934
|
* <html>
|
|
@@ -946,53 +946,53 @@ export declare class RenderContext {
|
|
|
946
946
|
* `;
|
|
947
947
|
* };
|
|
948
948
|
*
|
|
949
|
-
* // 2.
|
|
949
|
+
* // 2. Multi-application scenario
|
|
950
950
|
* const rc = await esmx.render({
|
|
951
|
-
* base: '/app1', //
|
|
951
|
+
* base: '/app1', // Set base path
|
|
952
952
|
* params: { appId: 1 }
|
|
953
953
|
* });
|
|
954
954
|
*
|
|
955
|
-
* //
|
|
955
|
+
* // Render and commit dependencies
|
|
956
956
|
* const html = await renderApp(rc);
|
|
957
957
|
* await rc.commit();
|
|
958
958
|
*
|
|
959
|
-
* //
|
|
960
|
-
* //
|
|
959
|
+
* // Resource paths will automatically add base path prefix
|
|
960
|
+
* // For example: /app1/your-app-name/js/main.js
|
|
961
961
|
* ```
|
|
962
962
|
*/
|
|
963
963
|
commit(): Promise<void>;
|
|
964
964
|
/**
|
|
965
|
-
*
|
|
965
|
+
* Generate resource preload tags
|
|
966
966
|
* @description
|
|
967
|
-
* preload()
|
|
967
|
+
* The preload() method is used to generate resource preload tags, optimizing page performance by loading critical resources in advance:
|
|
968
968
|
*
|
|
969
|
-
* 1.
|
|
970
|
-
* - CSS
|
|
971
|
-
* - JS
|
|
969
|
+
* 1. **Resource Types**
|
|
970
|
+
* - CSS files: Use `as="style"` to preload stylesheets
|
|
971
|
+
* - JS files: Use `as="script"` to preload import map scripts
|
|
972
972
|
*
|
|
973
|
-
* 2.
|
|
974
|
-
* -
|
|
975
|
-
* -
|
|
976
|
-
* -
|
|
977
|
-
* -
|
|
973
|
+
* 2. **Performance Optimization**
|
|
974
|
+
* - Discover and load critical resources in advance
|
|
975
|
+
* - Load in parallel with HTML parsing
|
|
976
|
+
* - Optimize resource loading order
|
|
977
|
+
* - Reduce page rendering blocking
|
|
978
978
|
*
|
|
979
|
-
* 3.
|
|
980
|
-
* -
|
|
981
|
-
* -
|
|
982
|
-
* -
|
|
979
|
+
* 3. **Best Practices**
|
|
980
|
+
* - Use as early as possible in the head
|
|
981
|
+
* - Only preload resources necessary for the current page
|
|
982
|
+
* - Use in conjunction with other resource loading methods
|
|
983
983
|
*
|
|
984
|
-
* @returns
|
|
984
|
+
* @returns Returns HTML string containing all preload tags
|
|
985
985
|
*
|
|
986
986
|
* @example
|
|
987
987
|
* ```ts
|
|
988
|
-
* //
|
|
988
|
+
* // Use in HTML head
|
|
989
989
|
* rc.html = `
|
|
990
990
|
* <!DOCTYPE html>
|
|
991
991
|
* <html>
|
|
992
992
|
* <head>
|
|
993
|
-
* <!--
|
|
993
|
+
* <!-- Preload critical resources -->
|
|
994
994
|
* ${rc.preload()}
|
|
995
|
-
* <!--
|
|
995
|
+
* <!-- Inject stylesheets -->
|
|
996
996
|
* ${rc.css()}
|
|
997
997
|
* </head>
|
|
998
998
|
* <body>
|
|
@@ -1007,34 +1007,34 @@ export declare class RenderContext {
|
|
|
1007
1007
|
*/
|
|
1008
1008
|
preload(): string;
|
|
1009
1009
|
/**
|
|
1010
|
-
*
|
|
1010
|
+
* Inject first-screen stylesheets
|
|
1011
1011
|
* @description
|
|
1012
|
-
* css()
|
|
1012
|
+
* The css() method is used to inject stylesheet resources required by the page:
|
|
1013
1013
|
*
|
|
1014
|
-
* 1.
|
|
1015
|
-
* -
|
|
1016
|
-
* -
|
|
1017
|
-
* -
|
|
1014
|
+
* 1. **Injection Position**
|
|
1015
|
+
* - Must be injected in the head tag
|
|
1016
|
+
* - Avoid page flickering (FOUC) and reflow
|
|
1017
|
+
* - Ensure styles are in place when content is rendered
|
|
1018
1018
|
*
|
|
1019
|
-
* 2.
|
|
1020
|
-
* -
|
|
1021
|
-
* -
|
|
1022
|
-
* -
|
|
1019
|
+
* 2. **Performance Optimization**
|
|
1020
|
+
* - Support critical CSS extraction
|
|
1021
|
+
* - Automatically handle style dependency relationships
|
|
1022
|
+
* - Utilize browser parallel loading capabilities
|
|
1023
1023
|
*
|
|
1024
|
-
* 3.
|
|
1025
|
-
* -
|
|
1026
|
-
* -
|
|
1027
|
-
* -
|
|
1024
|
+
* 3. **Use Cases**
|
|
1025
|
+
* - Inject styles necessary for the first screen
|
|
1026
|
+
* - Handle component-level styles
|
|
1027
|
+
* - Support theme switching and dynamic styles
|
|
1028
1028
|
*
|
|
1029
1029
|
* @example
|
|
1030
1030
|
* ```ts
|
|
1031
|
-
* // 1.
|
|
1031
|
+
* // 1. Basic usage
|
|
1032
1032
|
* rc.html = `
|
|
1033
1033
|
* <!DOCTYPE html>
|
|
1034
1034
|
* <html>
|
|
1035
1035
|
* <head>
|
|
1036
|
-
* ${rc.preload()} <!--
|
|
1037
|
-
* ${rc.css()} <!--
|
|
1036
|
+
* ${rc.preload()} <!-- Preload resources -->
|
|
1037
|
+
* ${rc.css()} <!-- Inject stylesheets -->
|
|
1038
1038
|
* </head>
|
|
1039
1039
|
* <body>
|
|
1040
1040
|
* <div id="app">Hello World</div>
|
|
@@ -1042,13 +1042,13 @@ export declare class RenderContext {
|
|
|
1042
1042
|
* </html>
|
|
1043
1043
|
* `;
|
|
1044
1044
|
*
|
|
1045
|
-
* // 2.
|
|
1045
|
+
* // 2. Use in conjunction with other resources
|
|
1046
1046
|
* rc.html = `
|
|
1047
1047
|
* <!DOCTYPE html>
|
|
1048
1048
|
* <html>
|
|
1049
1049
|
* <head>
|
|
1050
|
-
* ${rc.preload()} <!--
|
|
1051
|
-
* ${rc.css()} <!--
|
|
1050
|
+
* ${rc.preload()} <!-- Preload resources -->
|
|
1051
|
+
* ${rc.css()} <!-- Inject stylesheets -->
|
|
1052
1052
|
* </head>
|
|
1053
1053
|
* <body>
|
|
1054
1054
|
* ${html}
|
|
@@ -1062,35 +1062,35 @@ export declare class RenderContext {
|
|
|
1062
1062
|
*/
|
|
1063
1063
|
css(): string;
|
|
1064
1064
|
/**
|
|
1065
|
-
*
|
|
1065
|
+
* Inject module import map
|
|
1066
1066
|
* @description
|
|
1067
|
-
* importmap()
|
|
1068
|
-
*
|
|
1069
|
-
* 1.
|
|
1070
|
-
* -
|
|
1071
|
-
* -
|
|
1072
|
-
* -
|
|
1073
|
-
*
|
|
1074
|
-
* 2.
|
|
1075
|
-
* -
|
|
1076
|
-
* -
|
|
1077
|
-
* -
|
|
1078
|
-
* -
|
|
1079
|
-
* - JS
|
|
1080
|
-
* -
|
|
1081
|
-
* -
|
|
1082
|
-
* -
|
|
1083
|
-
*
|
|
1084
|
-
* 3.
|
|
1085
|
-
* -
|
|
1086
|
-
* -
|
|
1087
|
-
* -
|
|
1067
|
+
* The importmap() method is used to inject path resolution rules for ESM modules:
|
|
1068
|
+
*
|
|
1069
|
+
* 1. **Injection Position**
|
|
1070
|
+
* - Must be injected in the body
|
|
1071
|
+
* - Must be executed before moduleEntry
|
|
1072
|
+
* - Avoid blocking the first page render
|
|
1073
|
+
*
|
|
1074
|
+
* 2. **Import Map Modes**
|
|
1075
|
+
* - Inline mode (inline):
|
|
1076
|
+
* - Inline map content directly into HTML
|
|
1077
|
+
* - Suitable for scenarios with smaller map content
|
|
1078
|
+
* - Reduce the number of HTTP requests
|
|
1079
|
+
* - JS file mode (js):
|
|
1080
|
+
* - Generate independent JS files
|
|
1081
|
+
* - Suitable for scenarios with larger map content
|
|
1082
|
+
* - Can utilize browser caching mechanisms
|
|
1083
|
+
*
|
|
1084
|
+
* 3. **Technical Reasons**
|
|
1085
|
+
* - Define path resolution rules for ESM modules
|
|
1086
|
+
* - Client entry modules and their dependencies need to use these maps
|
|
1087
|
+
* - Ensure the map is correctly set before executing module code
|
|
1088
1088
|
*
|
|
1089
1089
|
* @example
|
|
1090
1090
|
* ```ts
|
|
1091
|
-
* // 1.
|
|
1091
|
+
* // 1. Basic usage - Inline mode
|
|
1092
1092
|
* const rc = await esmx.render({
|
|
1093
|
-
* importmapMode: 'inline' //
|
|
1093
|
+
* importmapMode: 'inline' // Default mode
|
|
1094
1094
|
* });
|
|
1095
1095
|
*
|
|
1096
1096
|
* rc.html = `
|
|
@@ -1102,42 +1102,42 @@ export declare class RenderContext {
|
|
|
1102
1102
|
* </head>
|
|
1103
1103
|
* <body>
|
|
1104
1104
|
* ${html}
|
|
1105
|
-
* ${rc.importmap()} <!--
|
|
1106
|
-
* ${rc.moduleEntry()} <!--
|
|
1105
|
+
* ${rc.importmap()} <!-- Inject import map -->
|
|
1106
|
+
* ${rc.moduleEntry()} <!-- Execute after import map -->
|
|
1107
1107
|
* ${rc.modulePreload()}
|
|
1108
1108
|
* </body>
|
|
1109
1109
|
* </html>
|
|
1110
1110
|
* `;
|
|
1111
1111
|
*
|
|
1112
|
-
* // 2. JS
|
|
1112
|
+
* // 2. JS file mode - Suitable for large applications
|
|
1113
1113
|
* const rc = await esmx.render({
|
|
1114
|
-
* importmapMode: 'js' //
|
|
1114
|
+
* importmapMode: 'js' // Use JS file mode
|
|
1115
1115
|
* });
|
|
1116
1116
|
* ```
|
|
1117
1117
|
*/
|
|
1118
1118
|
importmap(): string;
|
|
1119
1119
|
/**
|
|
1120
|
-
*
|
|
1120
|
+
* Inject client entry module
|
|
1121
1121
|
* @description
|
|
1122
|
-
* moduleEntry()
|
|
1123
|
-
* 1.
|
|
1124
|
-
* -
|
|
1125
|
-
* -
|
|
1126
|
-
* -
|
|
1127
|
-
*
|
|
1128
|
-
* 2.
|
|
1129
|
-
* -
|
|
1130
|
-
* -
|
|
1131
|
-
* -
|
|
1132
|
-
*
|
|
1133
|
-
* 3.
|
|
1134
|
-
* -
|
|
1135
|
-
* -
|
|
1136
|
-
* -
|
|
1122
|
+
* The moduleEntry() method is used to inject the client's entry module:
|
|
1123
|
+
* 1. **Injection Position**
|
|
1124
|
+
* - Must be executed after importmap
|
|
1125
|
+
* - Ensure the import map is correctly set before executing module code
|
|
1126
|
+
* - Control the start timing of client activation (Hydration)
|
|
1127
|
+
*
|
|
1128
|
+
* 2. **Technical Reasons**
|
|
1129
|
+
* - Serve as the entry point for client code
|
|
1130
|
+
* - Need to wait for infrastructure (such as import maps) to be ready
|
|
1131
|
+
* - Ensure correct module path resolution
|
|
1132
|
+
*
|
|
1133
|
+
* 3. **Use Cases**
|
|
1134
|
+
* - Start the client application
|
|
1135
|
+
* - Execute client activation
|
|
1136
|
+
* - Initialize client state
|
|
1137
1137
|
*
|
|
1138
1138
|
* @example
|
|
1139
1139
|
* ```ts
|
|
1140
|
-
* // 1.
|
|
1140
|
+
* // 1. Basic usage
|
|
1141
1141
|
* rc.html = `
|
|
1142
1142
|
* <!DOCTYPE html>
|
|
1143
1143
|
* <html>
|
|
@@ -1147,44 +1147,44 @@ export declare class RenderContext {
|
|
|
1147
1147
|
* </head>
|
|
1148
1148
|
* <body>
|
|
1149
1149
|
* ${html}
|
|
1150
|
-
* ${rc.importmap()} <!--
|
|
1151
|
-
* ${rc.moduleEntry()} <!--
|
|
1150
|
+
* ${rc.importmap()} <!-- Inject import map first -->
|
|
1151
|
+
* ${rc.moduleEntry()} <!-- Then inject entry module -->
|
|
1152
1152
|
* ${rc.modulePreload()}
|
|
1153
1153
|
* </body>
|
|
1154
1154
|
* </html>
|
|
1155
1155
|
* `;
|
|
1156
1156
|
*
|
|
1157
|
-
* // 2.
|
|
1157
|
+
* // 2. Multiple entry configuration
|
|
1158
1158
|
* const rc = await esmx.render({
|
|
1159
|
-
* entryName: 'mobile', //
|
|
1159
|
+
* entryName: 'mobile', // Specify entry name
|
|
1160
1160
|
* params: { device: 'mobile' }
|
|
1161
1161
|
* });
|
|
1162
1162
|
* ```
|
|
1163
1163
|
*/
|
|
1164
1164
|
moduleEntry(): string;
|
|
1165
1165
|
/**
|
|
1166
|
-
*
|
|
1166
|
+
* Preload module dependencies
|
|
1167
1167
|
* @description
|
|
1168
|
-
* modulePreload()
|
|
1168
|
+
* The modulePreload() method is used to preload modules that may be needed later:
|
|
1169
1169
|
*
|
|
1170
|
-
* 1.
|
|
1171
|
-
* -
|
|
1172
|
-
* -
|
|
1173
|
-
* -
|
|
1170
|
+
* 1. **Injection Position**
|
|
1171
|
+
* - Must be after importmap and moduleEntry
|
|
1172
|
+
* - Ensure the correct module path mapping is used
|
|
1173
|
+
* - Avoid competing with first-screen rendering for resources
|
|
1174
1174
|
*
|
|
1175
|
-
* 2.
|
|
1176
|
-
* -
|
|
1177
|
-
* -
|
|
1178
|
-
* -
|
|
1175
|
+
* 2. **Performance Optimization**
|
|
1176
|
+
* - Preload modules that may be needed later
|
|
1177
|
+
* - Improve runtime performance
|
|
1178
|
+
* - Optimize on-demand loading experience
|
|
1179
1179
|
*
|
|
1180
|
-
* 3.
|
|
1181
|
-
* -
|
|
1182
|
-
* -
|
|
1183
|
-
* -
|
|
1180
|
+
* 3. **Technical Reasons**
|
|
1181
|
+
* - Need correct path resolution rules
|
|
1182
|
+
* - Avoid duplicate loading
|
|
1183
|
+
* - Control loading priority
|
|
1184
1184
|
*
|
|
1185
1185
|
* @example
|
|
1186
1186
|
* ```ts
|
|
1187
|
-
* // 1.
|
|
1187
|
+
* // 1. Basic usage
|
|
1188
1188
|
* rc.html = `
|
|
1189
1189
|
* <!DOCTYPE html>
|
|
1190
1190
|
* <html>
|
|
@@ -1196,16 +1196,16 @@ export declare class RenderContext {
|
|
|
1196
1196
|
* ${html}
|
|
1197
1197
|
* ${rc.importmap()}
|
|
1198
1198
|
* ${rc.moduleEntry()}
|
|
1199
|
-
* ${rc.modulePreload()} <!--
|
|
1199
|
+
* ${rc.modulePreload()} <!-- Preload module dependencies -->
|
|
1200
1200
|
* </body>
|
|
1201
1201
|
* </html>
|
|
1202
1202
|
* `;
|
|
1203
1203
|
*
|
|
1204
|
-
* // 2.
|
|
1204
|
+
* // 2. Use with async components
|
|
1205
1205
|
* const AsyncComponent = defineAsyncComponent(() =>
|
|
1206
1206
|
* import('./components/AsyncComponent.vue')
|
|
1207
1207
|
* );
|
|
1208
|
-
* // modulePreload
|
|
1208
|
+
* // modulePreload will automatically collect and preload dependencies of async components
|
|
1209
1209
|
* ```
|
|
1210
1210
|
*/
|
|
1211
1211
|
modulePreload(): string;
|