@@ -210,56 +210,152 @@ export function getRequestDependencies(ssrContext: SSRContext, rendererContext:
210
210
211
211
export function renderStyles ( ssrContext : SSRContext , rendererContext : RendererContext ) : string {
212
212
const { styles } = getRequestDependencies ( ssrContext , rendererContext )
213
- return Object . values ( styles ) . map ( resource =>
214
- renderLinkToString ( { rel : 'stylesheet' , href : rendererContext . buildAssetsURL ( resource . file ) , crossorigin : '' } ) ,
215
- ) . join ( '' )
213
+ let result = ''
214
+ for ( const key in styles ) {
215
+ const resource = styles [ key ] !
216
+ result += `<link rel="stylesheet" href="${ rendererContext . buildAssetsURL ( resource . file ) } " crossorigin>`
217
+ }
218
+ return result
216
219
}
217
220
218
221
export function getResources ( ssrContext : SSRContext , rendererContext : RendererContext ) : LinkAttributes [ ] {
219
222
return [ ...getPreloadLinks ( ssrContext , rendererContext ) , ...getPrefetchLinks ( ssrContext , rendererContext ) ]
220
223
}
221
224
222
- export function renderResourceHints ( ssrContext : SSRContext , rendererContext : RendererContext ) : string {
223
- return getResources ( ssrContext , rendererContext ) . map ( renderLinkToString ) . join ( '' )
225
+ function renderResourceHints ( ssrContext : SSRContext , rendererContext : RendererContext ) : string {
226
+ const { preload, prefetch } = getRequestDependencies ( ssrContext , rendererContext )
227
+ let result = ''
228
+
229
+ // Render preload links
230
+ for ( const key in preload ) {
231
+ const resource = preload [ key ] !
232
+ const href = rendererContext . buildAssetsURL ( resource . file )
233
+ const rel = resource . module ? 'modulepreload' : 'preload'
234
+ const crossorigin = ( resource . resourceType === 'style' || resource . resourceType === 'font' || resource . resourceType === 'script' || resource . module ) ? ' crossorigin' : ''
235
+
236
+ if ( resource . resourceType && resource . mimeType ) {
237
+ result += `<link rel="${ rel } " as="${ resource . resourceType } " type="${ resource . mimeType } "${ crossorigin } href="${ href } ">`
238
+ }
239
+ else if ( resource . resourceType ) {
240
+ result += `<link rel="${ rel } " as="${ resource . resourceType } "${ crossorigin } href="${ href } ">`
241
+ }
242
+ else {
243
+ result += `<link rel="${ rel } "${ crossorigin } href="${ href } ">`
244
+ }
245
+ }
246
+ // Render prefetch links
247
+ for ( const key in prefetch ) {
248
+ const resource = prefetch [ key ] !
249
+ const href = rendererContext . buildAssetsURL ( resource . file )
250
+ const crossorigin = ( resource . resourceType === 'style' || resource . resourceType === 'font' || resource . resourceType === 'script' || resource . module ) ? ' crossorigin' : ''
251
+
252
+ if ( resource . resourceType && resource . mimeType ) {
253
+ result += `<link rel="prefetch" as="${ resource . resourceType } " type="${ resource . mimeType } "${ crossorigin } href="${ href } ">`
254
+ }
255
+ else if ( resource . resourceType ) {
256
+ result += `<link rel="prefetch" as="${ resource . resourceType } "${ crossorigin } href="${ href } ">`
257
+ }
258
+ else {
259
+ result += `<link rel="prefetch"${ crossorigin } href="${ href } ">`
260
+ }
261
+ }
262
+
263
+ return result
224
264
}
225
265
226
- export function renderResourceHeaders ( ssrContext : SSRContext , rendererContext : RendererContext ) : Record < string , string > {
266
+ function renderResourceHeaders ( ssrContext : SSRContext , rendererContext : RendererContext ) : Record < string , string > {
267
+ const { preload, prefetch } = getRequestDependencies ( ssrContext , rendererContext )
268
+ const links : string [ ] = [ ]
269
+
270
+ // Render preload headers
271
+ for ( const key in preload ) {
272
+ const resource = preload [ key ] !
273
+ const href = rendererContext . buildAssetsURL ( resource . file )
274
+ const rel = resource . module ? 'modulepreload' : 'preload'
275
+ let header = `<${ href } >; rel="${ rel } "`
276
+
277
+ if ( resource . resourceType ) {
278
+ header += `; as="${ resource . resourceType } "`
279
+ }
280
+ if ( resource . mimeType ) {
281
+ header += `; type="${ resource . mimeType } "`
282
+ }
283
+ if ( resource . resourceType === 'style' || resource . resourceType === 'font' || resource . resourceType === 'script' || resource . module ) {
284
+ header += '; crossorigin'
285
+ }
286
+
287
+ links . push ( header )
288
+ }
289
+
290
+ // Render prefetch headers
291
+ for ( const key in prefetch ) {
292
+ const resource = prefetch [ key ] !
293
+ const href = rendererContext . buildAssetsURL ( resource . file )
294
+ let header = `<${ href } >; rel="prefetch"`
295
+
296
+ if ( resource . resourceType ) {
297
+ header += `; as="${ resource . resourceType } "`
298
+ }
299
+ if ( resource . mimeType ) {
300
+ header += `; type="${ resource . mimeType } "`
301
+ }
302
+ if ( resource . resourceType === 'style' || resource . resourceType === 'font' || resource . resourceType === 'script' || resource . module ) {
303
+ header += '; crossorigin'
304
+ }
305
+
306
+ links . push ( header )
307
+ }
308
+
227
309
return {
228
- link : getResources ( ssrContext , rendererContext ) . map ( renderLinkToHeader ) . join ( ', ' ) ,
310
+ link : links . join ( ', ' ) ,
229
311
}
230
312
}
231
313
232
314
export function getPreloadLinks ( ssrContext : SSRContext , rendererContext : RendererContext ) : LinkAttributes [ ] {
233
315
const { preload } = getRequestDependencies ( ssrContext , rendererContext )
234
- return Object . values ( preload )
235
- . map ( resource => ( {
316
+ const result : LinkAttributes [ ] = [ ]
317
+ for ( const key in preload ) {
318
+ const resource = preload [ key ] !
319
+ result . push ( {
236
320
rel : resource . module ? 'modulepreload' : 'preload' ,
237
321
as : resource . resourceType ,
238
322
type : resource . mimeType ?? null ,
239
323
crossorigin : resource . resourceType === 'style' || resource . resourceType === 'font' || resource . resourceType === 'script' || resource . module ? '' : null ,
240
324
href : rendererContext . buildAssetsURL ( resource . file ) ,
241
- } ) )
325
+ } )
326
+ }
327
+ return result
242
328
}
243
329
244
330
export function getPrefetchLinks ( ssrContext : SSRContext , rendererContext : RendererContext ) : LinkAttributes [ ] {
245
331
const { prefetch } = getRequestDependencies ( ssrContext , rendererContext )
246
- return Object . values ( prefetch ) . map ( resource => ( {
247
- rel : 'prefetch' ,
248
- as : resource . resourceType ,
249
- type : resource . mimeType ?? null ,
250
- crossorigin : resource . resourceType === 'style' || resource . resourceType === 'font' || resource . resourceType === 'script' || resource . module ? '' : null ,
251
- href : rendererContext . buildAssetsURL ( resource . file ) ,
252
- } ) )
332
+ const result : LinkAttributes [ ] = [ ]
333
+ for ( const key in prefetch ) {
334
+ const resource = prefetch [ key ] !
335
+ result . push ( {
336
+ rel : 'prefetch' ,
337
+ as : resource . resourceType ,
338
+ type : resource . mimeType ?? null ,
339
+ crossorigin : resource . resourceType === 'style' || resource . resourceType === 'font' || resource . resourceType === 'script' || resource . module ? '' : null ,
340
+ href : rendererContext . buildAssetsURL ( resource . file ) ,
341
+ } )
342
+ }
343
+ return result
253
344
}
254
345
255
346
export function renderScripts ( ssrContext : SSRContext , rendererContext : RendererContext ) : string {
256
347
const { scripts } = getRequestDependencies ( ssrContext , rendererContext )
257
- return Object . values ( scripts ) . map ( resource => renderScriptToString ( {
258
- type : resource . module ? 'module' : null ,
259
- src : rendererContext . buildAssetsURL ( resource . file ) ,
260
- defer : resource . module ? null : '' ,
261
- crossorigin : '' ,
262
- } ) ) . join ( '' )
348
+ let result = ''
349
+ for ( const key in scripts ) {
350
+ const resource = scripts [ key ] !
351
+ if ( resource . module ) {
352
+ result += `<script type="module" src="${ rendererContext . buildAssetsURL ( resource . file ) } " crossorigin></script>`
353
+ }
354
+ else {
355
+ result += `<script src="${ rendererContext . buildAssetsURL ( resource . file ) } " defer crossorigin></script>`
356
+ }
357
+ }
358
+ return result
263
359
}
264
360
265
361
export type RenderFunction = ( ssrContext : SSRContext , rendererContext : RendererContext ) => unknown
@@ -293,18 +389,3 @@ export function createRenderer<App>(createApp: ImportOf<CreateApp<App>>, renderO
293
389
} ,
294
390
}
295
391
}
296
-
297
- // --- Internal ---
298
-
299
- // Utilities to render script and link tags, and link headers
300
- function renderScriptToString ( attrs : Record < string , string | null > ) {
301
- return `<script${ Object . entries ( attrs ) . map ( ( [ key , value ] ) => value === null ? '' : value ? ` ${ key } ="${ value } "` : ' ' + key ) . join ( '' ) } ></script>`
302
- }
303
-
304
- function renderLinkToString ( attrs : LinkAttributes ) {
305
- return `<link${ Object . entries ( attrs ) . map ( ( [ key , value ] ) => value === null ? '' : value ? ` ${ key } ="${ value } "` : ' ' + key ) . join ( '' ) } >`
306
- }
307
-
308
- function renderLinkToHeader ( attrs : LinkAttributes ) {
309
- return `<${ attrs . href } >${ Object . entries ( attrs ) . map ( ( [ key , value ] ) => key === 'href' || value === null ? '' : value ? `; ${ key } ="${ value } "` : `; ${ key } ` ) . join ( '' ) } `
310
- }
0 commit comments