From a7ebe76db6931b4112fbe79feaa46702c967e523 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 9 Mar 2022 01:00:04 +0100 Subject: [PATCH] Adopt react 18 rc2 --- package.json | 4 +-- packages/next/server/render.tsx | 33 ++++--------------- test/integration/react-18/app/pages/index.js | 4 --- .../app/pages/err/render.js | 2 +- .../app/pages/err/suspense.js | 6 ++-- .../test/basic.js | 22 +++++++++---- .../react-18-streaming-ssr/index.test.ts | 8 ++--- yarn.lock | 20 +++++------ 8 files changed, 41 insertions(+), 58 deletions(-) diff --git a/package.json b/package.json index 20602cc71f07..fc5da08d6f4a 100644 --- a/package.json +++ b/package.json @@ -146,9 +146,9 @@ "pretty-ms": "7.0.0", "random-seed": "0.3.0", "react": "17.0.2", - "react-18": "npm:react@18.0.0-rc.1", + "react-18": "npm:react@18.0.0-rc.2", "react-dom": "17.0.2", - "react-dom-18": "npm:react-dom@18.0.0-rc.1", + "react-dom-18": "npm:react-dom@18.0.0-rc.2", "react-ssr-prepass": "1.0.8", "react-virtualized": "9.22.3", "relay-compiler": "13.0.2", diff --git a/packages/next/server/render.tsx b/packages/next/server/render.tsx index d2e68b23669f..3203f516246a 100644 --- a/packages/next/server/render.tsx +++ b/packages/next/server/render.tsx @@ -67,7 +67,6 @@ import isError from '../lib/is-error' import { readableStreamTee } from './web/utils' import { ImageConfigContext } from '../shared/lib/image-config-context' import { FlushEffectsContext } from '../shared/lib/flush-effects' -import { execOnce } from '../shared/lib/utils' let optimizeAmp: typeof import('./optimize-amp').default let getFontDefinitionFromManifest: typeof import('./font-utils').getFontDefinitionFromManifest @@ -1733,6 +1732,7 @@ function createFlushEffectStream( return createTransformStream({ async transform(chunk, controller) { const extraChunk = await handleFlushEffect() + // those should flush together at once controller.enqueue(encodeText(extraChunk + decodeText(chunk))) }, }) @@ -1755,31 +1755,12 @@ async function renderToStream({ }): Promise> { const closeTag = '' const suffixUnclosed = suffix ? suffix.split(closeTag)[0] : null - - let completeCallback: (value?: unknown) => void - const allComplete = new Promise((resolveError, rejectError) => { - completeCallback = execOnce((err: unknown) => { - if (err) { - rejectError(err) - } else { - resolveError(null) - } - }) - }) - - const renderStream: ReadableStream = await ( - ReactDOMServer as any - ).renderToReadableStream(element, { - onError(err: Error) { - completeCallback(err) - }, - onCompleteAll() { - completeCallback() - }, - }) + const renderStream: ReadableStream & { + allReady?: Promise + } = await (ReactDOMServer as any).renderToReadableStream(element) if (generateStaticHTML) { - await allComplete + await renderStream.allReady } const transforms: Array> = [ @@ -1822,12 +1803,10 @@ function createPrefixStream( let prefixFlushed = false return createTransformStream({ transform(chunk, controller) { + controller.enqueue(chunk) if (!prefixFlushed && prefix) { prefixFlushed = true - controller.enqueue(chunk) controller.enqueue(encodeText(prefix)) - } else { - controller.enqueue(chunk) } }, flush(controller) { diff --git a/test/integration/react-18/app/pages/index.js b/test/integration/react-18/app/pages/index.js index a5079245fd67..beef70aff7f4 100644 --- a/test/integration/react-18/app/pages/index.js +++ b/test/integration/react-18/app/pages/index.js @@ -19,7 +19,3 @@ export default function Index() { ) } - -// export const config = { -// runtime: 'edge', -// } diff --git a/test/integration/react-streaming-and-server-components/app/pages/err/render.js b/test/integration/react-streaming-and-server-components/app/pages/err/render.js index c05e49826ae7..0c6ec0bd1bae 100644 --- a/test/integration/react-streaming-and-server-components/app/pages/err/render.js +++ b/test/integration/react-streaming-and-server-components/app/pages/err/render.js @@ -1,5 +1,5 @@ let did = false -export default function Error() { +export default function MyError() { if (!did && typeof window === 'undefined') { did = true throw new Error('oops') diff --git a/test/integration/react-streaming-and-server-components/app/pages/err/suspense.js b/test/integration/react-streaming-and-server-components/app/pages/err/suspense.js index d88d9082d69d..e23ccd094bba 100644 --- a/test/integration/react-streaming-and-server-components/app/pages/err/suspense.js +++ b/test/integration/react-streaming-and-server-components/app/pages/err/suspense.js @@ -1,7 +1,7 @@ import { Suspense } from 'react' let did = false -function Error() { +function MyError() { if (!did && typeof window === 'undefined') { did = true throw new Error('oops') @@ -12,8 +12,8 @@ export default function page() { return ( <>

Hey Error

- - + + ) diff --git a/test/integration/react-streaming-and-server-components/test/basic.js b/test/integration/react-streaming-and-server-components/test/basic.js index 0427ee5e3ff2..de482f112dee 100644 --- a/test/integration/react-streaming-and-server-components/test/basic.js +++ b/test/integration/react-streaming-and-server-components/test/basic.js @@ -37,12 +37,20 @@ export default async function basic(context, { env }) { }) it('should render 500 error correctly', async () => { - const html = await renderViaHTTP(context.appPort, '/err') - if (env === 'dev') { - // In dev mode it should show the error popup. - expect(html).toContain('Error: oops') - } else { - expect(html).toContain('custom-500-page') - } + const errPaths = ['/err', '/err/render'] + errPaths.forEach(async (pagePath) => { + const html = await renderViaHTTP(context.appPort, pagePath) + if (env === 'dev') { + // In dev mode it should show the error popup. + expect(html).toContain('Error: oops') + } else { + expect(html).toContain('custom-500-page') + } + }) + }) + + it('should render fallback if error raised from suspense during streaming', async () => { + const html = await renderViaHTTP(context.appPort, '/err/suspense') + expect(html).toContain('error-fallback') }) } diff --git a/test/production/react-18-streaming-ssr/index.test.ts b/test/production/react-18-streaming-ssr/index.test.ts index 0a8e355a7a49..0029c0ce2395 100644 --- a/test/production/react-18-streaming-ssr/index.test.ts +++ b/test/production/react-18-streaming-ssr/index.test.ts @@ -24,8 +24,8 @@ describe('react 18 streaming SSR in minimal mode', () => { }, }, dependencies: { - react: '18.0.0-rc.1', - 'react-dom': '18.0.0-rc.1', + react: '18.0.0-rc.2', + 'react-dom': '18.0.0-rc.2', }, }) }) @@ -60,8 +60,8 @@ describe('react 18 streaming SSR with custom next configs', () => { }, }, dependencies: { - react: '18.0.0-rc.1', - 'react-dom': '18.0.0-rc.1', + react: '18.0.0-rc.2', + 'react-dom': '18.0.0-rc.2', }, }) }) diff --git a/yarn.lock b/yarn.lock index aa72d1b57018..3466ef1dd988 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17778,20 +17778,20 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -"react-18@npm:react@18.0.0-rc.1": - version "18.0.0-rc.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.0.0-rc.1.tgz#fbaef1cbf8b1eddb36a869ee1ea723044aa670c2" - integrity sha512-IdvjOtyeFhITZwDrj+GMvY7kbWnGklRzNByO7/pOVIt0o3VZi++BUybpK3Fen1gDPkOZDP/rag7lSh6RZuWOeQ== +"react-18@npm:react@18.0.0-rc.2": + version "18.0.0-rc.2" + resolved "https://registry.yarnpkg.com/react/-/react-18.0.0-rc.2.tgz#f54de68a912454331f7f718794fbf5e6c01eb855" + integrity sha512-q32FWyA5HvqfRCN0ZOk0gUOpzJGPPh8fqbk8DYQuh4DyiGWiNgN/BxMq3/ScY0SlwDB1HOAMU1lUgtaOr5p2Ng== dependencies: loose-envify "^1.1.0" -"react-dom-18@npm:react-dom@18.0.0-rc.1": - version "18.0.0-rc.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.0.0-rc.1.tgz#97296d5a5e7582e65ea0d82a9ccd5953aa05e7f6" - integrity sha512-BZ9NEwUp56MEguEwAzuh3u4bYE9Jv3QrzjaTmu11PV4C/lJCARTELEI16vjnHLq184GoJcCHMBrDILqlCrkZFQ== +"react-dom-18@npm:react-dom@18.0.0-rc.2": + version "18.0.0-rc.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.0.0-rc.2.tgz#b0a55afc2a2385e9e518071eaf7c89f0c214bba5" + integrity sha512-EvLlgtc/wAzAIXX5V1gnLgeK9B3wAdEGmmrXXKRoRzXM0RNNwGN+6OxQPBlACiGDUYYEOk+GT8f6u+gNWDnTtg== dependencies: loose-envify "^1.1.0" - scheduler "^0.21.0-rc.1" + scheduler "^0.21.0-rc.2" react-dom@17.0.2: version "17.0.2" @@ -18802,7 +18802,7 @@ scheduler@^0.20.2: loose-envify "^1.1.0" object-assign "^4.1.1" -scheduler@^0.21.0-rc.1: +scheduler@^0.21.0-rc.2: version "0.21.0-rc.1-next-f468816ef-20220225" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.21.0-rc.1-next-f468816ef-20220225.tgz#1909b9ce9e67de48f5ca06b52d98828401771e66" integrity sha512-/maKldJ78Ba2o1e9kh2mUpqNZH7XrmSQ1o1aa3HUPN/OMotUB9+pBKX/y3Zihkjco21H4cujG9hK2sJOZUpzJw==