@@ -75,6 +75,7 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
7575 let viteConfig = { } ;
7676 let userEnabledSourceMaps ;
7777 let ssrBuild = false ;
78+ let prerenderEntryHtml ;
7879
7980 /** @type {import('./types.d.ts').PrerenderedRoute[] } */
8081 let routes = [ ] ;
@@ -90,12 +91,9 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
9091 const tmpDirId = 'headless-prerender' ;
9192
9293 /**
93- * From the non-external scripts in entry HTML document, find the one (if any)
94- * that provides a `prerender` export
95- *
9694 * @param {import('vite').Rollup.InputOption } input
9795 */
98- const getPrerenderScriptFromHTML = async ( input ) => {
96+ const getPrerenderEntryHtml = ( input ) => {
9997 // prettier-ignore
10098 const entryHtml =
10199 typeof input === "string"
@@ -106,7 +104,17 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
106104
107105 if ( ! entryHtml ) throw new Error ( 'Unable to detect entry HTML' ) ;
108106
109- const htmlDoc = htmlParse ( await fs . readFile ( entryHtml , 'utf-8' ) ) ;
107+ return path . resolve ( viteConfig . root , entryHtml ) ;
108+ } ;
109+
110+ /**
111+ * From the non-external scripts in the entry HTML document, find the one (if any)
112+ * that provides a `prerender` export
113+ */
114+ const getPrerenderScriptFromHtml = async ( ) => {
115+ if ( ! prerenderEntryHtml ) throw new Error ( 'Unable to detect entry HTML' ) ;
116+
117+ const htmlDoc = htmlParse ( await fs . readFile ( prerenderEntryHtml , 'utf-8' ) ) ;
110118
111119 const entryScriptTag = htmlDoc
112120 . getElementsByTagName ( 'script' )
@@ -118,7 +126,9 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
118126 if ( ! entrySrc || / ^ h t t p s : / . test ( entrySrc ) )
119127 throw new Error ( 'Prerender entry script must have a `src` attribute and be local' ) ;
120128
121- return path . join ( viteConfig . root , entrySrc ) ;
129+ return entrySrc . startsWith ( '/' )
130+ ? path . join ( viteConfig . root , entrySrc )
131+ : path . resolve ( path . dirname ( prerenderEntryHtml ) , entrySrc ) ;
122132 } ;
123133
124134 return {
@@ -134,7 +144,7 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
134144 // Only required for Vite 5 and older. In 6+, this is handled by the
135145 // Environment API (`applyToEnvironment`)
136146 if ( config . build ?. ssr ) {
137- ssrBuild = true
147+ ssrBuild = true ;
138148 return ;
139149 }
140150
@@ -194,8 +204,9 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
194204 } ,
195205 async options ( opts ) {
196206 if ( ssrBuild || ! opts . input ) return ;
207+ prerenderEntryHtml = getPrerenderEntryHtml ( opts . input ) ;
197208 if ( ! prerenderScript ) {
198- prerenderScript = await getPrerenderScriptFromHTML ( opts . input ) ;
209+ prerenderScript = await getPrerenderScriptFromHtml ( ) ;
199210 }
200211
201212 // prettier-ignore
@@ -288,9 +299,25 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
288299 } ;
289300
290301 // Grab the generated HTML file, we'll use it as a template for all pages:
291- const tpl = /** @type {string } */ (
292- /** @type {OutputAsset } */ ( bundle [ 'index.html' ] ) . source
293- ) ;
302+ const entryHtmlAsset =
303+ ( prerenderEntryHtml &&
304+ Object . values ( bundle ) . find (
305+ ( output ) =>
306+ output . type === 'asset' &&
307+ output . fileName . endsWith ( '.html' ) &&
308+ ( output . originalFileName === prerenderEntryHtml ||
309+ output . originalFileNames ?. includes ( prerenderEntryHtml ) ) ,
310+ ) ) ||
311+ /** @type {OutputAsset | undefined } */ ( bundle [ 'index.html' ] ) ||
312+ Object . values ( bundle ) . find (
313+ ( output ) => output . type === 'asset' && output . fileName . endsWith ( '.html' ) ,
314+ ) ;
315+
316+ if ( ! entryHtmlAsset ) {
317+ this . error ( 'Unable to detect generated entry HTML asset' ) ;
318+ }
319+
320+ const tpl = /** @type {string } */ ( entryHtmlAsset . source ) ;
294321
295322 // Create a tmp dir to allow importing & consuming the built modules,
296323 // before Rollup writes them to the disk
@@ -319,10 +346,7 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
319346
320347 const assetPath = path . join ( tmpDir , output ) ;
321348 await fs . mkdir ( path . dirname ( assetPath ) , { recursive : true } ) ;
322- await fs . writeFile (
323- assetPath ,
324- /** @type {OutputChunk } */ ( bundle [ output ] ) . code ,
325- ) ;
349+ await fs . writeFile ( assetPath , /** @type {OutputChunk } */ ( bundle [ output ] ) . code ) ;
326350
327351 if ( /** @type {OutputChunk } */ ( bundle [ output ] ) . exports ?. includes ( 'prerender' ) ) {
328352 prerenderEntry = /** @type {OutputChunk } */ ( bundle [ output ] ) ;
@@ -348,9 +372,7 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
348372 // do something in browsers only
349373 }` . replace ( / ^ { 20 } / gm, '' ) ;
350374
351- const stack = StackTraceParse ( e ) . find ( ( s ) =>
352- s . getFileName ( ) ?. includes ( tmpDirId ) ,
353- ) ;
375+ const stack = StackTraceParse ( e ) . find ( ( s ) => s . getFileName ( ) ?. includes ( tmpDirId ) ) ;
354376
355377 const sourceMapContent = prerenderEntry . map ;
356378 if ( stack && sourceMapContent ) {
@@ -390,9 +412,7 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
390412
391413 let prerender ;
392414 try {
393- const m = await import (
394- `file://${ path . join ( tmpDir , prerenderEntry . fileName ) } `
395- ) ;
415+ const m = await import ( `file://${ path . join ( tmpDir , prerenderEntry . fileName ) } ` ) ;
396416 prerender = m . prerender ;
397417 } catch ( e ) {
398418 const message = await handlePrerenderError ( e ) ;
@@ -506,8 +526,7 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
506526
507527 // Add generated HTML to compilation:
508528 route . url == '/'
509- ? ( /** @type {OutputAsset } */ ( bundle [ 'index.html' ] ) . source =
510- htmlDoc . toString ( ) )
529+ ? ( entryHtmlAsset . source = htmlDoc . toString ( ) )
511530 : this . emitFile ( {
512531 type : 'asset' ,
513532 fileName : assetName ,
@@ -535,6 +554,6 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
535554 }
536555 }
537556 }
538- }
557+ } ,
539558 } ;
540559}
0 commit comments