From feba8860b5716c2be514dc739a7a932cabbcf256 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 19 Nov 2021 17:08:32 +0100 Subject: [PATCH 1/4] Add properties for request using in RSC --- .../next-middleware-ssr-loader/render.ts | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts index 122bd32179441..d38479d35f54e 100644 --- a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts +++ b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts @@ -2,6 +2,11 @@ import { NextRequest } from '../../../../server/web/spec-extension/request' import { renderToHTML } from '../../../../server/web/render' import RenderResult from '../../../../server/render-result' +const createHeaders = (args?: any) => ({ + ...args, + 'x-middleware-ssr': '1', +}) + export function getRender({ App, Document, @@ -24,15 +29,15 @@ export function getRender({ restRenderOpts: any }) { return async function render(request: NextRequest) { - const url = request.nextUrl + const { nextUrl: url, cookies, headers } = request const { pathname, searchParams } = url const query = Object.fromEntries(searchParams) // Preflight request if (request.method === 'HEAD') { - return new Response('OK.', { - headers: { 'x-middleware-ssr': '1' }, + return new Response(null, { + headers: createHeaders(), }) } @@ -41,7 +46,11 @@ export function getRender({ : false delete query.__flight__ - const req = { url: pathname } + const req = { + url: pathname, + cookies, + headers, + } const renderOpts = { ...restRenderOpts, // Locales are not supported yet. @@ -103,7 +112,7 @@ export function getRender({ ).toString(), { status: 500, - headers: { 'x-middleware-ssr': '1' }, + headers: createHeaders(), } ) } @@ -114,7 +123,7 @@ export function getRender({ 'An error occurred while rendering ' + pathname + '.', { status: 500, - headers: { 'x-middleware-ssr': '1' }, + headers: createHeaders(), } ) } @@ -126,7 +135,7 @@ export function getRender({ } as any) return new Response(transformStream.readable, { - headers: { 'x-middleware-ssr': '1' }, + headers: createHeaders(), status: 200, }) } From 2888926bf63d41c306b7a6352f67efe4a28340e4 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 19 Nov 2021 19:52:41 +0100 Subject: [PATCH 2/4] pass down pageProps to rsc --- packages/next/client/index.tsx | 9 ++++++--- packages/next/server/render.tsx | 2 +- .../app/pages/index.server.js | 15 ++++++++++++++- .../test/index.test.js | 7 ++++++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/packages/next/client/index.tsx b/packages/next/client/index.tsx index 695e1dc117419..51e4962a78939 100644 --- a/packages/next/client/index.tsx +++ b/packages/next/client/index.tsx @@ -652,6 +652,7 @@ if (process.env.__NEXT_RSC) { cacheKey, serialized, _fresh, + ...restProps }: { cacheKey: string serialized?: string @@ -684,17 +685,19 @@ if (process.env.__NEXT_RSC) { } const root = response.readRoot() - return root + return React.cloneElement(root, restProps) } RSCComponent = (props: any) => { const { asPath: cacheKey } = useRouter() as any + const { __flight_serialized__, __flight_fresh__, ...rest } = props return ( ) diff --git a/packages/next/server/render.tsx b/packages/next/server/render.tsx index 91fdb62bd3699..814de4e30d59a 100644 --- a/packages/next/server/render.tsx +++ b/packages/next/server/render.tsx @@ -1002,7 +1002,7 @@ export async function renderToHTML( if (renderServerComponentData) { const stream: ReadableStream = renderToReadableStream( - , + , serverComponentManifest ) const reader = stream.getReader() diff --git a/test/integration/react-streaming-and-server-components/app/pages/index.server.js b/test/integration/react-streaming-and-server-components/app/pages/index.server.js index 4b61e6c76bad9..10fac48d165e6 100644 --- a/test/integration/react-streaming-and-server-components/app/pages/index.server.js +++ b/test/integration/react-streaming-and-server-components/app/pages/index.server.js @@ -1,15 +1,28 @@ import Foo from '../components/foo.client' const envVar = process.env.ENV_VAR_TEST +const headerKey = 'x-next-test-client' -export default function Index() { +export default function Index({ header }) { return (

{`thisistheindexpage.server`}

{envVar}
+
{header}
) } + +export function getServerSideProps({ req }) { + const { headers } = req + const header = headers.get(headerKey) + + return { + props: { + header, + }, + } +} diff --git a/test/integration/react-streaming-and-server-components/test/index.test.js b/test/integration/react-streaming-and-server-components/test/index.test.js index d801c484e5ff3..af7ee5f564f19 100644 --- a/test/integration/react-streaming-and-server-components/test/index.test.js +++ b/test/integration/react-streaming-and-server-components/test/index.test.js @@ -216,7 +216,11 @@ runSuite('document', 'prod', documentSuite) async function runBasicTests(context, env) { const isDev = env === 'dev' it('should render the correct html', async () => { - const homeHTML = await renderViaHTTP(context.appPort, '/') + const homeHTML = await renderViaHTTP(context.appPort, '/', null, { + headers: { + 'x-next-test-client': 'test-util', + }, + }) // should have only 1 DOCTYPE expect(homeHTML).toMatch(/^ Date: Mon, 22 Nov 2021 16:33:18 +0100 Subject: [PATCH 3/4] fix mismatch warning --- packages/next/client/index.tsx | 4 +++- .../app/pages/index.server.js | 9 +++++---- .../test/index.test.js | 7 ++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/next/client/index.tsx b/packages/next/client/index.tsx index 51e4962a78939..7bdb67c9b4739 100644 --- a/packages/next/client/index.tsx +++ b/packages/next/client/index.tsx @@ -657,6 +657,7 @@ if (process.env.__NEXT_RSC) { cacheKey: string serialized?: string _fresh?: boolean + [x: string]: any }) => { const { createFromFetch, @@ -685,11 +686,12 @@ if (process.env.__NEXT_RSC) { } const root = response.readRoot() + delete restProps.router return React.cloneElement(root, restProps) } RSCComponent = (props: any) => { - const { asPath: cacheKey } = useRouter() as any + const cacheKey = useRouter().asPath const { __flight_serialized__, __flight_fresh__, ...rest } = props return ( diff --git a/test/integration/react-streaming-and-server-components/app/pages/index.server.js b/test/integration/react-streaming-and-server-components/app/pages/index.server.js index 10fac48d165e6..1ec9eda6e3b8c 100644 --- a/test/integration/react-streaming-and-server-components/app/pages/index.server.js +++ b/test/integration/react-streaming-and-server-components/app/pages/index.server.js @@ -3,12 +3,13 @@ import Foo from '../components/foo.client' const envVar = process.env.ENV_VAR_TEST const headerKey = 'x-next-test-client' -export default function Index({ header }) { +export default function Index({ header, router }) { return (
-

{`thisistheindexpage.server`}

-
{envVar}
-
{header}
+

{`component:index.server`}

+
{'path:' + router.pathname}
+
{'env:' + envVar}
+
{'header:' + header}
diff --git a/test/integration/react-streaming-and-server-components/test/index.test.js b/test/integration/react-streaming-and-server-components/test/index.test.js index af7ee5f564f19..34fd86cd794fa 100644 --- a/test/integration/react-streaming-and-server-components/test/index.test.js +++ b/test/integration/react-streaming-and-server-components/test/index.test.js @@ -242,10 +242,11 @@ async function runBasicTests(context, env) { '/this-is-not-found' ) - expect(homeHTML).toContain('thisistheindexpage.server') - expect(homeHTML).toContain('env_var_test') + expect(homeHTML).toContain('component:index.server') + expect(homeHTML).toContain('env:env_var_test') + expect(homeHTML).toContain('header:test-util') + expect(homeHTML).toContain('path:/') expect(homeHTML).toContain('foo.client') - expect(homeHTML).toContain('test-util') expect(dynamicRouteHTML1).toContain('[pid]') expect(dynamicRouteHTML2).toContain('[pid]') From 39d754119f3b8f777b7cf116a46cc2838c311b07 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 22 Nov 2021 17:13:03 +0100 Subject: [PATCH 4/4] remove clone --- packages/next/client/index.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/next/client/index.tsx b/packages/next/client/index.tsx index 7bdb67c9b4739..e4d987c3f766f 100644 --- a/packages/next/client/index.tsx +++ b/packages/next/client/index.tsx @@ -652,12 +652,10 @@ if (process.env.__NEXT_RSC) { cacheKey, serialized, _fresh, - ...restProps }: { cacheKey: string serialized?: string _fresh?: boolean - [x: string]: any }) => { const { createFromFetch, @@ -686,20 +684,18 @@ if (process.env.__NEXT_RSC) { } const root = response.readRoot() - delete restProps.router - return React.cloneElement(root, restProps) + return root } RSCComponent = (props: any) => { const cacheKey = useRouter().asPath - const { __flight_serialized__, __flight_fresh__, ...rest } = props + const { __flight_serialized__, __flight_fresh__ } = props return ( )