diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index d65810e6c31e93..d80c12db5eee64 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -88,7 +88,6 @@ import { getBabelLoader, getReactCompilerLoader, } from './get-babel-loader-config' -import type { NextFlightLoaderOptions } from './webpack/loaders/next-flight-loader' import { NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_DIST_CLIENT, @@ -519,13 +518,6 @@ export default async function getBaseWebpackConfig( babel: useSWCLoader ? swcDefaultLoader : babelLoader!, } - const nextFlightLoader = { - loader: 'next-flight-loader', - options: { - isEdgeServer, - } satisfies NextFlightLoaderOptions, - } - const appServerLayerLoaders = hasAppDir ? [ // When using Babel, we will have to add the SWC loader @@ -539,7 +531,7 @@ export default async function getBaseWebpackConfig( : [] const instrumentLayerLoaders = [ - nextFlightLoader, + 'next-flight-loader', // When using Babel, we will have to add the SWC loader // as an additional pass to handle RSC correctly. // This will cause some performance overhead but @@ -549,7 +541,7 @@ export default async function getBaseWebpackConfig( ].filter(Boolean) const middlewareLayerLoaders = [ - nextFlightLoader, + 'next-flight-loader', // When using Babel, we will have to use SWC to do the optimization // for middleware to tree shake the unused default optimized imports like "next/server". // This will cause some performance overhead but @@ -1366,7 +1358,7 @@ export default async function getBaseWebpackConfig( isEdgeServer, }), }, - use: nextFlightLoader, + use: 'next-flight-loader', }, ] : []), diff --git a/packages/next/src/build/webpack/loaders/next-flight-loader/index.ts b/packages/next/src/build/webpack/loaders/next-flight-loader/index.ts index 805360591f1d0d..dd1182d3236547 100644 --- a/packages/next/src/build/webpack/loaders/next-flight-loader/index.ts +++ b/packages/next/src/build/webpack/loaders/next-flight-loader/index.ts @@ -2,8 +2,6 @@ import type { webpack } from 'next/dist/compiled/webpack/webpack' import { RSC_MOD_REF_PROXY_ALIAS } from '../../../../lib/constants' import { BARREL_OPTIMIZATION_PREFIX, - DEFAULT_RUNTIME_WEBPACK, - EDGE_RUNTIME_WEBPACK, RSC_MODULE_TYPES, } from '../../../../shared/lib/constants' import { warnOnce } from '../../../../shared/lib/utils/warn-once' @@ -14,11 +12,6 @@ import type { javascript, LoaderContext, } from 'next/dist/compiled/webpack/webpack' -import picomatch from 'next/dist/compiled/picomatch' - -export interface NextFlightLoaderOptions { - isEdgeServer: boolean -} type SourceType = javascript.JavascriptParser['sourceType'] | 'commonjs' @@ -27,10 +20,6 @@ const noopHeadPath = require.resolve('next/dist/client/components/noop-head') const MODULE_PROXY_PATH = 'next/dist/build/webpack/loaders/next-flight-loader/module-proxy' -const isSharedRuntime = picomatch('**/next/dist/**/*.shared-runtime.js', { - dot: true, // required for .pnpm paths -}) - export function getAssumedSourceType( mod: webpack.Module, sourceType: SourceType @@ -66,7 +55,7 @@ export function getAssumedSourceType( } export default function transformSource( - this: LoaderContext, + this: LoaderContext, source: string, sourceMap: any ) { @@ -75,8 +64,6 @@ export default function transformSource( throw new Error('Expected source to have been transformed to a string.') } - const options = this.getOptions() - const { isEdgeServer } = options const module = this._module! // Assign the RSC meta information to buildInfo. @@ -124,18 +111,6 @@ export default function transformSource( return } - if (!isSharedRuntime(resourceKey)) { - // Prevent module concatenation, and prevent export names from being - // mangled, in production builds, so that exports of client reference - // modules can be resolved by React using the metadata from the client - // manifest. - this._compilation!.moduleGraph.getExportsInfo( - module - ).setUsedInUnknownWay( - isEdgeServer ? EDGE_RUNTIME_WEBPACK : DEFAULT_RUNTIME_WEBPACK - ) - } - let esmSource = `\ import { registerClientReference } from "react-server-dom-webpack/server.edge"; ` diff --git a/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts index 8bd7fbca56aa30..7188849bb47aa7 100644 --- a/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts @@ -286,7 +286,7 @@ export class FlightClientEntryPlugin { > = [] const createdSSRDependenciesForEntry: Record< string, - ReturnType[2][] + ReturnType[3][] > = {} const addActionEntryList: Array> = @@ -400,7 +400,7 @@ export class FlightClientEntryPlugin { createdSSRDependenciesForEntry[clientEntryToInject.entryName] = [] } createdSSRDependenciesForEntry[clientEntryToInject.entryName].push( - injected[2] + injected[3] ) addClientEntryAndSSRModulesList.push(injected) @@ -457,12 +457,14 @@ export class FlightClientEntryPlugin { invalidator.invalidate([COMPILER_NAMES.client]) } - // Client compiler is invalidated before awaiting the compilation of the SSR client component entries - // so that the client compiler is running in parallel to the server compiler. + // Client compiler is invalidated before awaiting the compilation of the SSR + // and RSC client component entries so that the client compiler is running + // in parallel to the server compiler. await Promise.all( - addClientEntryAndSSRModulesList.map( - (addClientEntryAndSSRModules) => addClientEntryAndSSRModules[1] - ) + addClientEntryAndSSRModulesList.flatMap((addClientEntryAndSSRModules) => [ + addClientEntryAndSSRModules[1], + addClientEntryAndSSRModules[2], + ]) ) // Wait for action entries to be added. @@ -744,7 +746,8 @@ export class FlightClientEntryPlugin { absolutePagePath?: string }): [ shouldInvalidate: boolean, - addEntryPromise: Promise, + addSSREntryPromise: Promise, + addRSCEntryPromise: Promise, ssrDep: ReturnType, ] { let shouldInvalidate = false @@ -773,7 +776,7 @@ export class FlightClientEntryPlugin { server: false, })}!` - const clientSSRLoader = `next-flight-client-entry-loader?${stringify({ + const clientServerLoader = `next-flight-client-entry-loader?${stringify({ modules: modules.map((x) => JSON.stringify(x)), server: true, })}!` @@ -816,33 +819,30 @@ export class FlightClientEntryPlugin { pluginState.injectedClientEntries[bundlePath] = clientBrowserLoader } - // Inject the entry to the server compiler (__ssr__). - const clientComponentEntryDep = webpack.EntryPlugin.createDependency( - clientSSRLoader, - { - name: bundlePath, - } + const clientComponentSSREntryDep = webpack.EntryPlugin.createDependency( + clientServerLoader, + { name: bundlePath } + ) + + const clientComponentRSCEntryDep = webpack.EntryPlugin.createDependency( + clientServerLoader, + { name: bundlePath } ) return [ shouldInvalidate, - // Add the dependency to the server compiler. - // This promise is awaited later using `Promise.all` in order to parallelize adding the entries. - // It ensures we can parallelize the SSR and Client compiler entries. - this.addEntry( - compilation, - // Reuse compilation context. - compiler.context, - clientComponentEntryDep, - { - // By using the same entry name - name: entryName, - // Layer should be client for the SSR modules - // This ensures the client components are bundled on client layer - layer: WEBPACK_LAYERS.serverSideRendering, - } - ), - clientComponentEntryDep, + // Add the entries to the SSR and RSC server compilers. The promises are + // awaited later using `Promise.all` in order to parallelize adding the + // entries. + this.addEntry(compilation, compiler.context, clientComponentSSREntryDep, { + name: entryName, + layer: WEBPACK_LAYERS.serverSideRendering, + }), + this.addEntry(compilation, compiler.context, clientComponentRSCEntryDep, { + name: entryName, + layer: WEBPACK_LAYERS.reactServerComponents, + }), + clientComponentSSREntryDep, ] }