diff --git a/packages/next/src/build/create-compiler-aliases.ts b/packages/next/src/build/create-compiler-aliases.ts index 154f516fc6870..c47a43e73029c 100644 --- a/packages/next/src/build/create-compiler-aliases.ts +++ b/packages/next/src/build/create-compiler-aliases.ts @@ -255,15 +255,14 @@ export function createRSCAliases( 'react-dom/static$': `next/dist/compiled/react-dom-experimental/static`, 'react-dom/static.edge$': `next/dist/compiled/react-dom-experimental/static.edge`, 'react-dom/static.browser$': `next/dist/compiled/react-dom-experimental/static.browser`, - 'react-dom/server.edge$': `next/dist/compiled/react-dom${bundledReactChannel}/server.edge`, - 'react-dom/server.browser$': `next/dist/compiled/react-dom${bundledReactChannel}/server.browser`, + // optimizations to ignore the legacy build of react-dom/server in `server.browser` build + 'react-dom/server.edge$': `next/dist/build/webpack/alias/react-dom-server-edge${bundledReactChannel}.js`, + 'react-dom/server.browser$': `next/dist/build/webpack/alias/react-dom-server-browser${bundledReactChannel}.js`, + // react-server-dom-webpack alias 'react-server-dom-webpack/client$': `next/dist/compiled/react-server-dom-webpack${bundledReactChannel}/client`, 'react-server-dom-webpack/client.edge$': `next/dist/compiled/react-server-dom-webpack${bundledReactChannel}/client.edge`, 'react-server-dom-webpack/server.edge$': `next/dist/compiled/react-server-dom-webpack${bundledReactChannel}/server.edge`, 'react-server-dom-webpack/server.node$': `next/dist/compiled/react-server-dom-webpack${bundledReactChannel}/server.node`, - // optimisations to ignore the legacy build of react-dom/server - './cjs/react-dom-server-legacy.browser.production.min.js': `next/dist/build/noop-react-dom-server-legacy`, - './cjs/react-dom-server-legacy.browser.development.js': `next/dist/build/noop-react-dom-server-legacy`, } if (!isEdgeServer) { diff --git a/packages/next/src/build/noop-react-dom-server-legacy.ts b/packages/next/src/build/noop-react-dom-server-legacy.ts deleted file mode 100644 index 21d696afc9537..0000000000000 --- a/packages/next/src/build/noop-react-dom-server-legacy.ts +++ /dev/null @@ -1,10 +0,0 @@ -const ERROR_MESSAGE = - 'Internal Error: do not use legacy react-dom/server APIs. If you encountered this error, please open an issue on the Next.js repo.' - -export function renderToString() { - throw new Error(ERROR_MESSAGE) -} - -export function renderToStaticMarkup() { - throw new Error(ERROR_MESSAGE) -} diff --git a/packages/next/src/build/webpack/alias/react-dom-server-browser-experimental.js b/packages/next/src/build/webpack/alias/react-dom-server-browser-experimental.js new file mode 100644 index 0000000000000..a5d6643a6c240 --- /dev/null +++ b/packages/next/src/build/webpack/alias/react-dom-server-browser-experimental.js @@ -0,0 +1,18 @@ +var l, s +if (process.env.NODE_ENV === 'production') { + l = require('next/dist/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.min.js') + s = require('next/dist/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.min.js') +} else { + l = require('next/dist/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js') + s = require('next/dist/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js') +} + +exports.version = l.version +exports.renderToString = l.renderToString +exports.renderToStaticMarkup = l.renderToStaticMarkup +exports.renderToNodeStream = l.renderToNodeStream +exports.renderToStaticNodeStream = l.renderToStaticNodeStream +exports.renderToReadableStream = s.renderToReadableStream +if (s.resume) { + exports.resume = s.resume +} diff --git a/packages/next/src/build/webpack/alias/react-dom-server-browser.js b/packages/next/src/build/webpack/alias/react-dom-server-browser.js new file mode 100644 index 0000000000000..f462b442ae41e --- /dev/null +++ b/packages/next/src/build/webpack/alias/react-dom-server-browser.js @@ -0,0 +1,18 @@ +var l, s +if (process.env.NODE_ENV === 'production') { + l = require('next/dist/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.min.js') + s = require('next/dist/compiled/react-dom/cjs/react-dom-server.browser.production.min.js') +} else { + l = require('next/dist/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js') + s = require('next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js') +} + +exports.version = l.version +exports.renderToString = l.renderToString +exports.renderToStaticMarkup = l.renderToStaticMarkup +exports.renderToNodeStream = l.renderToNodeStream +exports.renderToStaticNodeStream = l.renderToStaticNodeStream +exports.renderToReadableStream = s.renderToReadableStream +if (s.resume) { + exports.resume = s.resume +} diff --git a/packages/next/src/build/webpack/alias/react-dom-server-edge-experimental.js b/packages/next/src/build/webpack/alias/react-dom-server-edge-experimental.js new file mode 100644 index 0000000000000..b14af3c288f1c --- /dev/null +++ b/packages/next/src/build/webpack/alias/react-dom-server-edge-experimental.js @@ -0,0 +1,23 @@ +const ERROR_MESSAGE = + 'Internal Error: do not use legacy react-dom/server APIs. If you encountered this error, please open an issue on the Next.js repo.' + +function error() { + throw new Error(ERROR_MESSAGE) +} + +var b +if (process.env.NODE_ENV === 'production') { + b = require('next/dist/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.min.js') +} else { + b = require('next/dist/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js') +} + +exports.version = b.version +exports.renderToReadableStream = b.renderToReadableStream +exports.renderToNodeStream = b.renderToNodeStream +exports.renderToStaticNodeStream = b.renderToStaticNodeStream +exports.renderToString = error +exports.renderToStaticMarkup = error +if (b.resume) { + exports.resume = b.resume +} diff --git a/packages/next/src/build/webpack/alias/react-dom-server-edge.js b/packages/next/src/build/webpack/alias/react-dom-server-edge.js new file mode 100644 index 0000000000000..f6b6056bc271e --- /dev/null +++ b/packages/next/src/build/webpack/alias/react-dom-server-edge.js @@ -0,0 +1,23 @@ +const ERROR_MESSAGE = + 'Internal Error: do not use legacy react-dom/server APIs. If you encountered this error, please open an issue on the Next.js repo.' + +function error() { + throw new Error(ERROR_MESSAGE) +} + +var b +if (process.env.NODE_ENV === 'production') { + b = require('next/dist/compiled/react-dom/cjs/react-dom-server.edge.production.min.js') +} else { + b = require('next/dist/compiled/react-dom/cjs/react-dom-server.edge.development.js') +} + +exports.version = b.version +exports.renderToReadableStream = b.renderToReadableStream +exports.renderToNodeStream = b.renderToNodeStream +exports.renderToStaticNodeStream = b.renderToStaticNodeStream +exports.renderToString = error +exports.renderToStaticMarkup = error +if (b.resume) { + exports.resume = b.resume +} diff --git a/packages/next/webpack.config.js b/packages/next/webpack.config.js index 952e8ccba9819..e995e7f9d634b 100644 --- a/packages/next/webpack.config.js +++ b/packages/next/webpack.config.js @@ -20,6 +20,15 @@ const pagesExternals = [ 'react-server-dom-webpack/server.node', ] +const appExternals = [ + // Externalize the react-dom/server legacy implementation outside of the runtime. + // If users are using them and imported from 'react-dom/server' they will get the external asset bundled. + 'next/dist/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js', + 'next/dist/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.min.js', + 'next/dist/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js', + 'next/dist/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.min.js', +] + function makeAppAliases(reactChannel = '') { return { react$: `next/dist/compiled/react${reactChannel}`, @@ -30,11 +39,14 @@ function makeAppAliases(reactChannel = '') { 'react/jsx-dev-runtime$': `next/dist/compiled/react${reactChannel}/jsx-dev-runtime`, 'react-dom/client$': `next/dist/compiled/react-dom${reactChannel}/client`, 'react-dom/server$': `next/dist/compiled/react-dom${reactChannel}/server`, - 'react-dom/server.edge$': `next/dist/compiled/react-dom${reactChannel}/server.edge`, - 'react-dom/server.browser$': `next/dist/compiled/react-dom${reactChannel}/server.browser`, 'react-dom/static$': `next/dist/compiled/react-dom-experimental/static`, 'react-dom/static.edge$': `next/dist/compiled/react-dom-experimental/static.edge`, 'react-dom/static.browser$': `next/dist/compiled/react-dom-experimental/static.browser`, + // optimizations to ignore the legacy build of react-dom/server in `server.browser` build + 'react-dom/server.edge$': `next/dist/build/webpack/alias/react-dom-server-edge${reactChannel}.js`, + // In Next.js runtime only use react-dom/server.edge + 'react-dom/server.browser$': 'react-dom/server.edge', + // react-server-dom-webpack alias 'react-server-dom-turbopack/client$': `next/dist/compiled/react-server-dom-turbopack${reactChannel}/client`, 'react-server-dom-turbopack/client.edge$': `next/dist/compiled/react-server-dom-turbopack${reactChannel}/client.edge`, 'react-server-dom-turbopack/server.edge$': `next/dist/compiled/react-server-dom-turbopack${reactChannel}/server.edge`, @@ -43,9 +55,6 @@ function makeAppAliases(reactChannel = '') { 'react-server-dom-webpack/client.edge$': `next/dist/compiled/react-server-dom-webpack${reactChannel}/client.edge`, 'react-server-dom-webpack/server.edge$': `next/dist/compiled/react-server-dom-webpack${reactChannel}/server.edge`, 'react-server-dom-webpack/server.node$': `next/dist/compiled/react-server-dom-webpack${reactChannel}/server.node`, - // optimisations to ignore the legacy build of react-dom/server - './cjs/react-dom-server-legacy.browser.production.min.js': `next/dist/build/noop-react-dom-server-legacy`, - './cjs/react-dom-server-legacy.browser.development.js': `next/dist/build/noop-react-dom-server-legacy`, } } @@ -252,7 +261,7 @@ module.exports = ({ dev, turbo, bundleType, experimental }) => { }, externals: [ ...sharedExternals, - ...(bundleType === 'pages' ? pagesExternals : []), + ...(bundleType === 'pages' ? pagesExternals : appExternals), externalsMap, externalHandler, ], diff --git a/test/e2e/app-dir/rsc-basic/app/app-react/client-react.js b/test/e2e/app-dir/rsc-basic/app/app-react/client-react.js index 2e5f208139730..751df16075552 100644 --- a/test/e2e/app-dir/rsc-basic/app/app-react/client-react.js +++ b/test/e2e/app-dir/rsc-basic/app/app-react/client-react.js @@ -3,8 +3,13 @@ import React from 'react' import ReactDOM from 'react-dom' import ReactDOMServer from 'react-dom/server.edge' +import { renderToStaticMarkup } from 'react-dom/server' export default function ClientReact() { + const markup = renderToStaticMarkup( +
{'React.version=' + React.version}
@@ -12,6 +17,7 @@ export default function ClientReact() {{'ReactDOMServer.version=' + ReactDOMServer.version}
+{markup}