From c9af1cc78f6b5f95c78a61ee160d0f0e0517eb4c 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 +---- yarn.lock | 4 +- 10 files changed, 25 insertions(+), 60 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 113bd996c40567..1293175eb12889 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-alpha-e6be2d531", "react-dom": "17.0.2", - "react-dom-18": "npm:react-dom@18", + "react-dom-18": "npm:react-dom@18.0.0-alpha-e6be2d531", "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 dbc75cf172711d..d6c595e933ea69 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 00000000000000..21f2ba0abbec55 --- /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 1c36a9b284a58e..00000000000000 --- 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 1e0b54f840c569..be823a58af7d76 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 fb077e8078c9e5..17c78ff7937eaf 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 c981dcdb8c8b64..00000000000000 --- 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 a34e4ef37de188..fb077e8078c9e5 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 49b92f5672df85..a621479e950b9c 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 () => { diff --git a/yarn.lock b/yarn.lock index e20f8464a50e2e..7e56531b9506dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15632,7 +15632,7 @@ 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": +"react-18@npm:react@18.0.0-alpha-e6be2d531": version "18.0.0-alpha-e6be2d531" resolved "https://registry.yarnpkg.com/react/-/react-18.0.0-alpha-e6be2d531.tgz#c5cf6d5706f7b6411d36848b483a7937c94fc5c9" integrity sha512-roZmm4MYfuGN65PiagPvhumBb3Da1FAgyj6Ti2sHwQDIxhi40PMq5V90gBSKXl7qXbaXHrtpuAtG5R+XkqpDYA== @@ -15640,7 +15640,7 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8: loose-envify "^1.1.0" object-assign "^4.1.1" -"react-dom-18@npm:react-dom@18": +"react-dom-18@npm:react-dom@18.0.0-alpha-e6be2d531": version "18.0.0-alpha-e6be2d531" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.0.0-alpha-e6be2d531.tgz#89b1aef488a56ceac7cc0169ae02d7fbb58cbbb6" integrity sha512-mMGiX/kyhxaUTRDt+Q5oIbpU6cPvO8Sp/kHz3cdNFviwVTHHF2YrnnD70BD2F1R0b7wAdfVVit9EfE+Rqt0sJA==