Skip to content

Commit

Permalink
fix: duplicate app server (#36710)
Browse files Browse the repository at this point in the history
Fixes #36659

`App` is alreay included in `ServerComponentWrapper`

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
  • Loading branch information
huozhi committed May 5, 2022
1 parent 41c0a66 commit 4fb0beb
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
22 changes: 11 additions & 11 deletions packages/next/server/render.tsx
Expand Up @@ -208,7 +208,6 @@ function renderPageTree(
isServerComponent: boolean
) {
const { router: _, ...rest } = props

if (isServerComponent) {
return (
<App>
Expand Down Expand Up @@ -400,7 +399,7 @@ const useFlightResponse = createFlightHook()
// Create the wrapper component for a Flight stream.
function createServerComponentRenderer(
App: any,
ComponentMod: any,
Component: any,
{
cachePrefix,
inlinedTransformStream,
Expand All @@ -413,12 +412,6 @@ function createServerComponentRenderer(
serverComponentManifest: NonNullable<RenderOpts['serverComponentManifest']>
}
) {
// We need to expose the `__webpack_require__` API globally for
// react-server-dom-webpack. This is a hack until we find a better way.
// @ts-ignore
globalThis.__webpack_require__ = ComponentMod.__next_rsc__.__webpack_require__
const Component = interopDefault(ComponentMod)

function ServerComponentWrapper({ router, ...props }: any) {
const id = (React as any).useId()

Expand Down Expand Up @@ -527,7 +520,13 @@ export async function renderToHTML(
if (isServerComponent) {
serverComponentsInlinedTransformStream = new TransformStream()
const search = urlQueryToSearchParams(query).toString()
Component = createServerComponentRenderer(App, ComponentMod, {
// We need to expose the `__webpack_require__` API globally for
// react-server-dom-webpack. This is a hack until we find a better way.
// @ts-ignore
globalThis.__webpack_require__ =
ComponentMod.__next_rsc__.__webpack_require__

Component = createServerComponentRenderer(App, Component, {
cachePrefix: pathname + (search ? `?${search}` : ''),
inlinedTransformStream: serverComponentsInlinedTransformStream,
staticTransformStream: serverComponentsPageDataTransformStream,
Expand Down Expand Up @@ -1257,7 +1256,7 @@ export async function renderToHTML(
...props.pageProps,
...serverComponentProps,
},
isServerComponent
true
),
serverComponentManifest
).pipeThrough(createBufferedTransformStream())
Expand Down Expand Up @@ -1425,7 +1424,8 @@ export async function renderToHTML(
<Body>
<AppContainerWithIsomorphicFiberStructure>
{renderPageTree(
EnhancedApp,
// AppServer is included in the EnhancedComponent in ServerComponentWrapper
isServerComponent ? React.Fragment : EnhancedApp,
EnhancedComponent,
{ ...(isServerComponent ? props.pageProps : props), router },
isServerComponent
Expand Down
@@ -0,0 +1,7 @@
export default function App({ Component, pageProps }) {
return (
<div className="app-client-root">
<Component {...pageProps} />
</div>
)
}
Expand Up @@ -38,12 +38,16 @@ async function testRoute(appPort, url, { isStatic, isEdge, isRSC }) {
// Should be re-rendered.
expect(renderedAt1).toBeLessThan(renderedAt2)
}
const customAppServerHtml = '<div class="app-server-root"'
if (isRSC) {
expect(html1).toContain(customAppServerHtml)
} else {
expect(html1).not.toContain(customAppServerHtml)
}
// If the page is using 1 root, it won't use the other.
// e.g. server component page won't have client app root.
const rootClasses = ['app-server-root', 'app-client-root']
const [rootClass, oppositeRootClass] = isRSC
? [rootClasses[0], rootClasses[1]]
: [rootClasses[1], rootClasses[0]]
const appServerOccurrence =
html1.match(new RegExp(`class="${rootClass}"`, 'g')) || []
expect(appServerOccurrence.length).toBe(1)
expect(html1).not.toContain(`"${oppositeRootClass}"`)
}

describe('Switchable runtime (prod)', () => {
Expand Down

0 comments on commit 4fb0beb

Please sign in to comment.