From 45f431ef629136398bef9ce428de5af780a6a16e Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 28 Jun 2021 00:59:54 +0800 Subject: [PATCH] support react 18 --- package.json | 4 +- packages/next/client/index.tsx | 2 +- .../react-18/prerelease/next.config.js | 14 +++++++ .../node_modules/react-dom/index.js | 38 ------------------- .../react-18/prerelease/package.json | 1 + .../react-18/prerelease/pages/index.js | 3 ++ .../react-18/supported/next.config.js | 5 --- .../react-18/supported/pages/index.js | 4 -- test/integration/react-18/test/index.test.js | 10 +---- 9 files changed, 23 insertions(+), 58 deletions(-) create mode 100644 test/integration/react-18/prerelease/next.config.js delete mode 100644 test/integration/react-18/prerelease/node_modules/react-dom/index.js delete mode 100644 test/integration/react-18/supported/next.config.js diff --git a/package.json b/package.json index 113bd996c4056..60bb603af76f9 100644 --- a/package.json +++ b/package.json @@ -115,9 +115,9 @@ "pretty-bytes": "5.3.0", "pretty-ms": "7.0.0", "react": "17.0.2", - "react-18": "npm:react@18", + "react-18": "npm:react@18.0.0", "react-dom": "17.0.2", - "react-dom-18": "npm:react-dom@18", + "react-dom-18": "npm:react-dom@18.0.0", "react-ssr-prepass": "1.0.8", "release": "6.3.0", "request-promise-core": "1.1.2", diff --git a/packages/next/client/index.tsx b/packages/next/client/index.tsx index dbc75cf172711..d6c595e933ea6 100644 --- a/packages/next/client/index.tsx +++ b/packages/next/client/index.tsx @@ -516,8 +516,8 @@ function renderReactElement( reactRoot = ReactDOM18.createRoot(domEl, { hydrate: shouldHydrate }) reactRoot.render(reactEl) } - shouldHydrate = false } + shouldHydrate = false } else { // The check for `.hydrate` is there to support React alternatives like preact if (shouldHydrate) { diff --git a/test/integration/react-18/prerelease/next.config.js b/test/integration/react-18/prerelease/next.config.js new file mode 100644 index 0000000000000..21f2ba0abbec5 --- /dev/null +++ b/test/integration/react-18/prerelease/next.config.js @@ -0,0 +1,14 @@ +module.exports = { + webpack(config) { + const { alias } = config.resolve + // FIXME: resolving react/jsx-runtime https://github.com/facebook/react/issues/20235 + alias['react/jsx-dev-runtime'] = require.resolve('react/jsx-dev-runtime.js') + alias['react/jsx-runtime'] = require.resolve('react/jsx-runtime.js') + + // Use react 18 + alias['react'] = require.resolve('react-18') + alias['react-dom'] = require.resolve('react-dom-18') + + return config + }, +} diff --git a/test/integration/react-18/prerelease/node_modules/react-dom/index.js b/test/integration/react-18/prerelease/node_modules/react-dom/index.js deleted file mode 100644 index 1c36a9b284a58..0000000000000 --- a/test/integration/react-18/prerelease/node_modules/react-dom/index.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict' - -function checkDCE() { - /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ - if ( - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' || - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function' - ) { - return - } - if (process.env.NODE_ENV !== 'production') { - // This branch is unreachable because this function is only called - // in production, but the condition is true only in development. - // Therefore if the branch is still here, dead code elimination wasn't - // properly applied. - // Don't change the message. React DevTools relies on it. Also make sure - // this message doesn't occur elsewhere in this function, or it will cause - // a false positive. - throw new Error('^_^') - } - try { - // Verify that the code above has been dead code eliminated (DCE'd). - __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE) - } catch (err) { - // DevTools shouldn't crash React, no matter what. - // We should still report in case we break this code. - console.error(err) - } -} - -if (process.env.NODE_ENV === 'production') { - // DCE check should happen before ReactDOM bundle executes so that - // DevTools can report bad minification during injection. - checkDCE() - module.exports = require('./cjs/react-dom.production.min.js') -} else { - module.exports = require('./cjs/react-dom.development.js') -} diff --git a/test/integration/react-18/prerelease/package.json b/test/integration/react-18/prerelease/package.json index 1e0b54f840c56..be823a58af7d7 100644 --- a/test/integration/react-18/prerelease/package.json +++ b/test/integration/react-18/prerelease/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "react": "*", "react-dom": "*" } } diff --git a/test/integration/react-18/prerelease/pages/index.js b/test/integration/react-18/prerelease/pages/index.js index fb077e8078c9e..17c78ff7937ea 100644 --- a/test/integration/react-18/prerelease/pages/index.js +++ b/test/integration/react-18/prerelease/pages/index.js @@ -1,3 +1,6 @@ export default function Index() { + if (typeof window !== 'undefined') { + window.didHydrate = true + } return

Hello

} diff --git a/test/integration/react-18/supported/next.config.js b/test/integration/react-18/supported/next.config.js deleted file mode 100644 index c981dcdb8c8b6..0000000000000 --- a/test/integration/react-18/supported/next.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - experimental: { - reactRoot: true, - }, -} diff --git a/test/integration/react-18/supported/pages/index.js b/test/integration/react-18/supported/pages/index.js index a34e4ef37de18..fb077e8078c9e 100644 --- a/test/integration/react-18/supported/pages/index.js +++ b/test/integration/react-18/supported/pages/index.js @@ -1,7 +1,3 @@ export default function Index() { - if (typeof window !== 'undefined') { - window.didHydrate = true - } - return 'details' return

Hello

} diff --git a/test/integration/react-18/test/index.test.js b/test/integration/react-18/test/index.test.js index 49b92f5672df8..a621479e950b9 100644 --- a/test/integration/react-18/test/index.test.js +++ b/test/integration/react-18/test/index.test.js @@ -82,19 +82,13 @@ describe('React 18 Support', () => { let app let appPort beforeAll(async () => { - jest.mock('react', () => { - return jest.requireActual('react-18') - }) - jest.mock('react-dom', () => { - return jest.requireActual('react-dom-18') - }) await fs.remove(join(appDir, '.next')) const { stderr } = await nextBuild(appDir, [dirPrerelease], { stderr: true, }) - console.error(stderr) + // stderr && console.error(stderr) appPort = await findPort() - app = await nextStart(appDir, appPort, { stderr: true }) + app = await nextStart(appDir, appPort) }) afterAll(async () => await killApp(app)) it('hydrates correctly for normal page', async () => {