Skip to content

Commit 36ec1b4

Browse files
committed
re. preactjs#34 discussion
1 parent 3b18dfb commit 36ec1b4

1 file changed

Lines changed: 21 additions & 11 deletions

File tree

src/plugins/prerender-plugin.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -175,16 +175,18 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
175175
if (ssrBuild) return;
176176
// We're only going to alter the chunking behavior in the default cases, where the user and/or
177177
// other plugins haven't already configured this. It'd be impossible to avoid breakages otherwise.
178+
// Vite 8 renamed `rollupOptions` to `rolldownOptions` :( -> fall back to rollupOptions for Vite 5–7
179+
const _buildOpts = config.build.rolldownOptions ?? config.build.rollupOptions;
178180
if (
179-
Array.isArray(config.build.rollupOptions.output) ||
180-
config.build.rollupOptions.output?.manualChunks
181+
Array.isArray(_buildOpts.output) ||
182+
_buildOpts.output?.manualChunks
181183
) {
182184
viteConfig = config;
183185
return;
184186
}
185187

186-
config.build.rollupOptions.output ??= {};
187-
config.build.rollupOptions.output.manualChunks = (id) => {
188+
_buildOpts.output ??= {};
189+
_buildOpts.output.manualChunks = (id) => {
188190
if (id.includes(prerenderScript) || id.includes(preloadPolyfillId)) {
189191
return 'index';
190192
}
@@ -233,17 +235,13 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
233235
};
234236
} else if (id.includes(preloadPolyfillId)) {
235237
const s = new MagicString(code);
236-
// Replacement for `'link'` && `"link"` as the output from their tooling has
237-
// differed over the years. Should be better than switching to regex.
238+
// Matches both quote styles ('link' / "link") and optional semicolons, as the
239+
// compiled output has varied across Vite/Rollup/Rolldown versions over the years.
238240
// https://github.com/vitejs/vite/blob/20fdf210ee0ac0824b2db74876527cb7f378a9e8/packages/vite/src/node/plugins/modulePreloadPolyfill.ts#L62
239241
s.replace(
240-
`const relList = document.createElement('link').relList;`,
242+
/const relList = document\.createElement\(["']link["']\)\.relList;?/,
241243
`if (typeof window === "undefined") return;\n const relList = document.createElement('link').relList;`,
242244
);
243-
s.replace(
244-
`const relList = document.createElement("link").relList;`,
245-
`if (typeof window === "undefined") return;\n const relList = document.createElement("link").relList;`,
246-
);
247245
return {
248246
code: s.toString(),
249247
map: s.generateMap({ hires: true }),
@@ -388,6 +386,15 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
388386
/** @type {Partial<import('./types.d.ts').Head>} */
389387
let head = { lang: '', title: '', elements: new Set() };
390388

389+
// Vite 8 native Rolldown path: modulepreload polyfill is injected by rolldown/experimental
390+
// and bypasses Vite's transform hook, so our window-check patch never runs. Stub document
391+
// only for the duration of the import so the polyfill's feature-detection exits early
392+
// (`relList.supports('modulepreload') === true`), without affecting user prerender code.
393+
// @ts-ignore
394+
const _documentStubbed = !('document' in globalThis);
395+
// @ts-ignore
396+
if (_documentStubbed) globalThis.document = { createElement: () => ({ relList: { supports: () => true } }) };
397+
391398
let prerender;
392399
try {
393400
const m = await import(
@@ -397,6 +404,9 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
397404
} catch (e) {
398405
const message = await handlePrerenderError(e);
399406
this.error(message);
407+
} finally {
408+
// @ts-ignore
409+
if (_documentStubbed) delete globalThis.document;
400410
}
401411

402412
if (typeof prerender !== 'function') {

0 commit comments

Comments
 (0)