Skip to content

Commit

Permalink
Add experimental config for React Mode (#9207)
Browse files Browse the repository at this point in the history
* Add experimental config for React Mode

* Use latest types

* Use latest types
  • Loading branch information
devknoll authored and Timer committed Oct 30, 2019
1 parent 4c6e294 commit f632567
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 10 deletions.
3 changes: 3 additions & 0 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,9 @@ export default async function getBaseWebpackConfig(
'process.env.__NEXT_STRICT_MODE': JSON.stringify(
config.reactStrictMode
),
'process.env.__NEXT_REACT_MODE': JSON.stringify(
config.experimental.reactMode
),
...(isServer
? {
// Fix bad-actors in the npm ecosystem (e.g. `node-formidable`)
Expand Down
26 changes: 21 additions & 5 deletions packages/next/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { DataManager } from '../next-server/lib/data-manager'
import { parse as parseQs, stringify as stringifyQs } from 'querystring'
import { isDynamicRoute } from '../next-server/lib/router/utils/is-dynamic'

/// <reference types="react-dom/experimental" />

// Polyfill Promise globally
// This is needed because Webpack's dynamic loading(common chunks) code
// depends on Promise.
Expand Down Expand Up @@ -236,18 +238,32 @@ export async function renderError (props) {

// If hydrate does not exist, eg in preact.
let isInitialRender = typeof ReactDOM.hydrate === 'function'
let reactRoot = null
function renderReactElement (reactEl, domEl) {
// mark start of hydrate/render
if (SUPPORTS_PERFORMANCE_USER_TIMING) {
performance.mark('beforeRender')
}

// The check for `.hydrate` is there to support React alternatives like preact
if (isInitialRender) {
ReactDOM.hydrate(reactEl, domEl, markHydrateComplete)
isInitialRender = false
if (process.env.__NEXT_REACT_MODE !== 'legacy') {
let callback = markRenderComplete
if (!reactRoot) {
const opts = { hydrate: true }
reactRoot =
process.env.__NEXT_REACT_MODE === 'concurrent'
? ReactDOM.createRoot(domEl, opts)
: ReactDOM.createBlockingRoot(domEl, opts)
callback = markHydrateComplete
}
reactRoot.render(reactEl, callback)
} else {
ReactDOM.render(reactEl, domEl, markRenderComplete)
// The check for `.hydrate` is there to support React alternatives like preact
if (isInitialRender) {
ReactDOM.hydrate(reactEl, domEl, markHydrateComplete)
isInitialRender = false
} else {
ReactDOM.render(reactEl, domEl, markRenderComplete)
}
}

if (onPerfEntry) {
Expand Down
14 changes: 14 additions & 0 deletions packages/next/next-server/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CONFIG_FILE } from '../lib/constants'
import { execOnce } from '../lib/utils'

const targets = ['server', 'serverless', 'experimental-serverless-trace']
const reactModes = ['legacy', 'blocking', 'concurrent']

const defaultConfig: { [key: string]: any } = {
env: [],
Expand Down Expand Up @@ -49,6 +50,7 @@ const defaultConfig: { [key: string]: any } = {
publicDirectory: false,
sprFlushToDisk: true,
deferScripts: false,
reactMode: 'legacy',
workerThreads: false,
},
future: {
Expand Down Expand Up @@ -162,6 +164,18 @@ export default function loadConfig(
)
}

if (
userConfig.experimental &&
userConfig.experimental.reactMode &&
!reactModes.includes(userConfig.experimental.reactMode)
) {
throw new Error(
`Specified React Mode is invalid. Provided: ${
userConfig.experimental.reactMode
} should be one of ${reactModes.join(', ')}`
)
}

return assignDefaults({ configOrigin: CONFIG_FILE, ...userConfig })
} else {
const configBaseName = basename(CONFIG_FILE, extname(CONFIG_FILE))
Expand Down
2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
"@types/nanoid": "2.0.0",
"@types/node-fetch": "2.3.4",
"@types/react": "16.8.18",
"@types/react-dom": "16.8.4",
"@types/react-dom": "16.9.3",
"@types/react-is": "16.7.1",
"@types/resolve": "0.0.8",
"@types/send": "0.14.4",
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2452,10 +2452,10 @@
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==

"@types/react-dom@16.8.4":
version "16.8.4"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.8.4.tgz#7fb7ba368857c7aa0f4e4511c4710ca2c5a12a88"
integrity sha512-eIRpEW73DCzPIMaNBDP5pPIpK1KXyZwNgfxiVagb5iGiz6da+9A5hslSX6GAQKdO7SayVCS/Fr2kjqprgAvkfA==
"@types/react-dom@16.9.3":
version "16.9.3"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.3.tgz#4006ff0e13958af91313869077c04cb20d9b9d04"
integrity sha512-FUuZKXPr9qlzUT9lhuzrZgLjH63TvNn28Ch3MvKG4B+F52zQtO8DtE0Opbncy3xaucNZM2WIPfuNTgkbKx5Brg==
dependencies:
"@types/react" "*"

Expand Down

0 comments on commit f632567

Please sign in to comment.