Skip to content

Commit

Permalink
make sure polyfill is added in app
Browse files Browse the repository at this point in the history
  • Loading branch information
shuding committed Sep 29, 2022
1 parent 596148c commit 899b1bb
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
27 changes: 19 additions & 8 deletions packages/next/server/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,13 @@ export async function renderToHTMLOrFlight(
return flushed
}

const polyfills = buildManifest.polyfillFiles
.filter(
(polyfill) =>
polyfill.endsWith('.js') && !polyfill.endsWith('.module.js')
)
.map((polyfill) => `${renderOpts.assetPrefix || ''}/_next/${polyfill}`)

try {
const renderStream = await renderToInitialStream({
ReactDOMServer,
Expand All @@ -1295,14 +1302,16 @@ export async function renderToHTMLOrFlight(
onError: htmlRendererErrorHandler,
nonce,
// Include hydration scripts in the HTML
bootstrapScripts: subresourceIntegrityManifest
? buildManifest.rootMainFiles.map((src) => ({
src: `${renderOpts.assetPrefix || ''}/_next/` + src,
integrity: subresourceIntegrityManifest[src],
}))
: buildManifest.rootMainFiles.map(
(src) => `${renderOpts.assetPrefix || ''}/_next/` + src
),
bootstrapScripts: [
...(subresourceIntegrityManifest
? buildManifest.rootMainFiles.map((src) => ({
src: `${renderOpts.assetPrefix || ''}/_next/` + src,
integrity: subresourceIntegrityManifest[src],
}))
: buildManifest.rootMainFiles.map(
(src) => `${renderOpts.assetPrefix || ''}/_next/` + src
)),
],
},
})

Expand All @@ -1311,6 +1320,7 @@ export async function renderToHTMLOrFlight(
generateStaticHTML: generateStaticHTML,
flushEffectHandler,
flushEffectsToHead: true,
polyfills,
})
} catch (err: any) {
// TODO-APP: show error overlay in development. `element` should probably be wrapped in AppRouter for this case.
Expand Down Expand Up @@ -1341,6 +1351,7 @@ export async function renderToHTMLOrFlight(
generateStaticHTML: generateStaticHTML,
flushEffectHandler,
flushEffectsToHead: true,
polyfills,
})
}
}
Expand Down
12 changes: 11 additions & 1 deletion packages/next/server/node-web-streams-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,14 @@ export async function continueFromInitialStream(
generateStaticHTML,
flushEffectHandler,
flushEffectsToHead,
polyfills,
}: {
suffix?: string
dataStream?: ReadableStream<Uint8Array>
generateStaticHTML: boolean
flushEffectHandler?: () => Promise<string>
flushEffectsToHead: boolean
polyfills?: string[]
}
): Promise<ReadableStream<Uint8Array>> {
const closeTag = '</body></html>'
Expand All @@ -289,13 +291,21 @@ export async function continueFromInitialStream(
dataStream ? createInlineDataStream(dataStream) : null,
suffixUnclosed != null ? createSuffixStream(closeTag) : null,
createHeadInjectionTransformStream(async () => {
// Inject polyfills for browsers that don't support modules. It has to be
// blocking here and can't be `defer` because other scripts have `async`.
const polyfillScripts = polyfills
? polyfills
.map((src) => `<script src="${src}" nomodule=""></script>`)
.join('')
: ''

// TODO-APP: Inject flush effects to end of head in app layout rendering, to avoid
// hydration errors. Remove this once it's ready to be handled by react itself.
const flushEffectsContent =
flushEffectHandler && flushEffectsToHead
? await flushEffectHandler()
: ''
return flushEffectsContent
return polyfillScripts + flushEffectsContent
}),
].filter(nonNullable)

Expand Down
7 changes: 7 additions & 0 deletions test/e2e/app-dir/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ describe('app dir', () => {
expect(html).toContain('hello from dynamic on client')
})

it('should serve polyfills for browsers that do not support modules', async () => {
const html = await renderViaHTTP(next.url, '/dashboard/index')
expect(html).toMatch(
/<script src="\/_next\/static\/chunks\/polyfills(-\w+)?\.js" nomodule="">/
)
})

// TODO-APP: handle css modules fouc in dev
it.skip('should handle css imports in next/dynamic correctly', async () => {
const browser = await webdriver(next.url, '/dashboard/index')
Expand Down

0 comments on commit 899b1bb

Please sign in to comment.