From 87763d73e0d90a16666b39a1cb12729f6858bd9f Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 18 Jul 2023 12:48:27 -0600 Subject: [PATCH] Rename Webpack Layers (#52605) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renames the webpack layers to be more semantical: ``` server compiler: server layer → RSC layer client layer → SSR layer shared layer → shared layer client compiler: appClient layer → app browser layer ``` --- packages/next/src/build/entries.ts | 12 ++--- packages/next/src/build/webpack-build/impl.ts | 4 +- packages/next/src/build/webpack-config.ts | 43 ++++++++-------- .../build/webpack/config/blocks/css/index.ts | 12 ++++- .../plugins/flight-client-entry-plugin.ts | 24 +++++---- .../webpack/plugins/flight-manifest-plugin.ts | 4 +- .../plugins/next-types-plugin/index.ts | 2 +- .../nextjs-require-cache-hot-reloader.ts | 2 +- packages/next/src/lib/constants.ts | 49 +++++++++++++++---- packages/next/src/server/dev/hot-reloader.ts | 13 +++-- packages/next/src/shared/lib/constants.ts | 4 +- 11 files changed, 110 insertions(+), 59 deletions(-) diff --git a/packages/next/src/build/entries.ts b/packages/next/src/build/entries.ts index e8fa4276771ed..39e1da4e6e2ff 100644 --- a/packages/next/src/build/entries.ts +++ b/packages/next/src/build/entries.ts @@ -314,7 +314,7 @@ export function getEdgeServerEntry(opts: { return { import: `next-edge-app-route-loader?${stringify(loaderParams)}!`, - layer: WEBPACK_LAYERS.server, + layer: WEBPACK_LAYERS.reactServerComponents, } } if (isMiddlewareFile(opts.page)) { @@ -386,14 +386,14 @@ export function getEdgeServerEntry(opts: { // The Edge bundle includes the server in its entrypoint, so it has to // be in the SSR layer — we later convert the page request to the RSC layer // via a webpack rule. - layer: opts.appDirLoader ? WEBPACK_LAYERS.client : undefined, + layer: opts.appDirLoader ? WEBPACK_LAYERS.serverSideRendering : undefined, } } export function getAppEntry(opts: Readonly) { return { import: `next-app-loader?${stringify(opts)}!`, - layer: WEBPACK_LAYERS.server, + layer: WEBPACK_LAYERS.reactServerComponents, } } @@ -716,7 +716,7 @@ export function finalizeEntrypoint({ layer: isApi ? WEBPACK_LAYERS.api : isServerComponent - ? WEBPACK_LAYERS.server + ? WEBPACK_LAYERS.reactServerComponents : undefined, ...entry, } @@ -751,7 +751,7 @@ export function finalizeEntrypoint({ if (isAppLayer) { return { dependOn: CLIENT_STATIC_FILES_RUNTIME_MAIN_APP, - layer: WEBPACK_LAYERS.appClient, + layer: WEBPACK_LAYERS.appPagesBrowser, ...entry, } } @@ -767,7 +767,7 @@ export function finalizeEntrypoint({ if (isAppLayer) { return { - layer: WEBPACK_LAYERS.appClient, + layer: WEBPACK_LAYERS.appPagesBrowser, ...entry, } } diff --git a/packages/next/src/build/webpack-build/impl.ts b/packages/next/src/build/webpack-build/impl.ts index 319f033d5b9c0..fcd43f24dbc75 100644 --- a/packages/next/src/build/webpack-build/impl.ts +++ b/packages/next/src/build/webpack-build/impl.ts @@ -211,13 +211,13 @@ export async function webpackBuildImpl( ...clientEntry[CLIENT_STATIC_FILES_RUNTIME_MAIN_APP].import, value, ], - layer: WEBPACK_LAYERS.appClient, + layer: WEBPACK_LAYERS.appPagesBrowser, } } else { clientEntry[key] = { dependOn: [CLIENT_STATIC_FILES_RUNTIME_MAIN_APP], import: value, - layer: WEBPACK_LAYERS.appClient, + layer: WEBPACK_LAYERS.appPagesBrowser, } } } diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 971e286374226..f7354d7830d13 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -1320,10 +1320,10 @@ export default async function getBaseWebpackConfig( } const isAppLayer = [ - WEBPACK_LAYERS.server, - WEBPACK_LAYERS.client, - WEBPACK_LAYERS.appClient, - WEBPACK_LAYERS.action, + WEBPACK_LAYERS.reactServerComponents, + WEBPACK_LAYERS.serverSideRendering, + WEBPACK_LAYERS.appPagesBrowser, + WEBPACK_LAYERS.actionBrowser, ].includes(layer!) if ( @@ -1340,7 +1340,7 @@ export default async function getBaseWebpackConfig( } // Special internal modules that must be bundled for Server Components. - if (layer === WEBPACK_LAYERS.server) { + if (layer === WEBPACK_LAYERS.reactServerComponents) { // React needs to be bundled for Server Components so the special // `react-server` export condition can be used. if (reactPackagesRegex.test(request)) { @@ -1361,9 +1361,9 @@ export default async function getBaseWebpackConfig( // override react-dom to server-rendering-stub for server if ( request === 'react-dom' && - (layer === WEBPACK_LAYERS.client || - layer === WEBPACK_LAYERS.server || - layer === WEBPACK_LAYERS.action) + (layer === WEBPACK_LAYERS.serverSideRendering || + layer === WEBPACK_LAYERS.reactServerComponents || + layer === WEBPACK_LAYERS.actionBrowser) ) { request = `next/dist/compiled/react-dom${bundledReactChannel}/server-rendering-stub` } else if (isAppLayer) { @@ -1468,7 +1468,7 @@ export default async function getBaseWebpackConfig( // Early return if the request needs to be bundled, such as in the client layer. // Treat react packages and next internals as external for SSR layer, // also map react to builtin ones with require-hook. - if (layer === WEBPACK_LAYERS.client) { + if (layer === WEBPACK_LAYERS.serverSideRendering) { if (reactPackagesRegex.test(request)) { return `commonjs next/dist/compiled/${request.replace( /^(react-server-dom-webpack|react-dom|react)/, @@ -1952,22 +1952,22 @@ export default async function getBaseWebpackConfig( resourceQuery: new RegExp( WEBPACK_RESOURCE_QUERIES.metadataRoute ), - layer: WEBPACK_LAYERS.metadataRoute, + layer: WEBPACK_LAYERS.appMetadataRoute, }, { // Ensure that the app page module is in the client layers, this // enables React to work correctly for RSC. - layer: WEBPACK_LAYERS.client, + layer: WEBPACK_LAYERS.serverSideRendering, test: /next[\\/]dist[\\/](esm[\\/])?server[\\/]future[\\/]route-modules[\\/]app-page[\\/]module/, }, { // All app dir layers need to use this configured resolution logic issuerLayer: { or: [ - WEBPACK_LAYERS.server, - WEBPACK_LAYERS.client, - WEBPACK_LAYERS.appClient, - WEBPACK_LAYERS.action, + WEBPACK_LAYERS.reactServerComponents, + WEBPACK_LAYERS.serverSideRendering, + WEBPACK_LAYERS.appPagesBrowser, + WEBPACK_LAYERS.actionBrowser, WEBPACK_LAYERS.shared, ], }, @@ -2047,7 +2047,7 @@ export default async function getBaseWebpackConfig( resourceQuery: new RegExp( WEBPACK_RESOURCE_QUERIES.edgeSSREntry ), - layer: WEBPACK_LAYERS.server, + layer: WEBPACK_LAYERS.reactServerComponents, }, ] : []), @@ -2085,7 +2085,7 @@ export default async function getBaseWebpackConfig( }, { test: codeCondition.test, - issuerLayer: WEBPACK_LAYERS.client, + issuerLayer: WEBPACK_LAYERS.serverSideRendering, resolve: { alias: createRSCAliases(bundledReactChannel, { reactSharedSubset: false, @@ -2099,7 +2099,7 @@ export default async function getBaseWebpackConfig( }, { test: codeCondition.test, - issuerLayer: WEBPACK_LAYERS.appClient, + issuerLayer: WEBPACK_LAYERS.appPagesBrowser, resolve: { alias: createRSCAliases(bundledReactChannel, { // Only alias server rendering stub in client SSR layer. @@ -2148,7 +2148,10 @@ export default async function getBaseWebpackConfig( { ...codeCondition, issuerLayer: { - or: [WEBPACK_LAYERS.client, WEBPACK_LAYERS.appClient], + or: [ + WEBPACK_LAYERS.serverSideRendering, + WEBPACK_LAYERS.appPagesBrowser, + ], }, exclude: [asyncStoragesRegex, codeCondition.exclude], use: [ @@ -2323,7 +2326,7 @@ export default async function getBaseWebpackConfig( { test: /(node_modules|next[/\\]dist[/\\]compiled)[/\\]server-only[/\\]index.js/, loader: 'next-invalid-import-error-loader', - issuerLayer: WEBPACK_LAYERS.client, + issuerLayer: WEBPACK_LAYERS.serverSideRendering, options: { message: "'server-only' cannot be imported from a Client Component module. It should only be used from a Server Component.", diff --git a/packages/next/src/build/webpack/config/blocks/css/index.ts b/packages/next/src/build/webpack/config/blocks/css/index.ts index 1647db4515867..632c5fa959993 100644 --- a/packages/next/src/build/webpack/config/blocks/css/index.ts +++ b/packages/next/src/build/webpack/config/blocks/css/index.ts @@ -26,11 +26,19 @@ const regexSassGlobal = /(? { const modResource = mod.resourceResolveData?.path || mod.resource - if (mod.layer !== WEBPACK_LAYERS.client) { + if (mod.layer !== WEBPACK_LAYERS.serverSideRendering) { return } @@ -720,7 +720,7 @@ export class FlightClientEntryPlugin { pluginState.injectedClientEntries[bundlePath] = clientLoader } - // Inject the entry to the server compiler (__sc_client__). + // Inject the entry to the server compiler (__ssr__). const clientComponentEntryDep = webpack.EntryPlugin.createDependency( clientSSRLoader, { @@ -743,7 +743,7 @@ export class FlightClientEntryPlugin { name: entryName, // Layer should be client for the SSR modules // This ensures the client components are bundled on client layer - layer: WEBPACK_LAYERS.client, + layer: WEBPACK_LAYERS.serverSideRendering, } ), clientComponentEntryDep, @@ -785,8 +785,8 @@ export class FlightClientEntryPlugin { } currentCompilerServerActions[id].workers[bundlePath] = '' currentCompilerServerActions[id].layer[bundlePath] = fromClient - ? WEBPACK_LAYERS.action - : WEBPACK_LAYERS.server + ? WEBPACK_LAYERS.actionBrowser + : WEBPACK_LAYERS.reactServerComponents } } @@ -802,7 +802,9 @@ export class FlightClientEntryPlugin { actionEntryDep, { name: entryName, - layer: fromClient ? WEBPACK_LAYERS.action : WEBPACK_LAYERS.server, + layer: fromClient + ? WEBPACK_LAYERS.actionBrowser + : WEBPACK_LAYERS.reactServerComponents, } ) } @@ -869,7 +871,9 @@ export class FlightClientEntryPlugin { for (let name in action.workers) { const modId = pluginState.actionModServerId[name][ - action.layer[name] === WEBPACK_LAYERS.action ? 'client' : 'server' + action.layer[name] === WEBPACK_LAYERS.actionBrowser + ? 'client' + : 'server' ] action.workers[name] = modId! } @@ -881,7 +885,9 @@ export class FlightClientEntryPlugin { for (let name in action.workers) { const modId = pluginState.actionModEdgeServerId[name][ - action.layer[name] === WEBPACK_LAYERS.action ? 'client' : 'server' + action.layer[name] === WEBPACK_LAYERS.actionBrowser + ? 'client' + : 'server' ] action.workers[name] = modId! } diff --git a/packages/next/src/build/webpack/plugins/flight-manifest-plugin.ts b/packages/next/src/build/webpack/plugins/flight-manifest-plugin.ts index 9707072db90f1..de834e64bb979 100644 --- a/packages/next/src/build/webpack/plugins/flight-manifest-plugin.ts +++ b/packages/next/src/build/webpack/plugins/flight-manifest-plugin.ts @@ -185,7 +185,7 @@ export class ClientReferenceManifestPlugin { const requiredChunks = getAppPathRequiredChunks(chunkGroup) const recordModule = (id: ModuleId, mod: webpack.NormalModule) => { // Skip all modules from the pages folder. - if (mod.layer !== WEBPACK_LAYERS.appClient) { + if (mod.layer !== WEBPACK_LAYERS.appPagesBrowser) { return } @@ -289,7 +289,7 @@ export class ClientReferenceManifestPlugin { const entryMods = compilation.chunkGraph.getChunkEntryModulesIterable(chunk) for (const mod of entryMods) { - if (mod.layer !== WEBPACK_LAYERS.appClient) continue + if (mod.layer !== WEBPACK_LAYERS.appPagesBrowser) continue const request = (mod as webpack.NormalModule).request diff --git a/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts b/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts index 1e468649f67bf..560cbdfff902f 100644 --- a/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts +++ b/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts @@ -576,7 +576,7 @@ export class NextTypesPlugin { return } - if (mod.layer !== WEBPACK_LAYERS.server) return + if (mod.layer !== WEBPACK_LAYERS.reactServerComponents) return const IS_LAYOUT = /[/\\]layout\.[^./\\]+$/.test(mod.resource) const IS_PAGE = !IS_LAYOUT && /[/\\]page\.[^.]+$/.test(mod.resource) diff --git a/packages/next/src/build/webpack/plugins/nextjs-require-cache-hot-reloader.ts b/packages/next/src/build/webpack/plugins/nextjs-require-cache-hot-reloader.ts index e59ab16f5039c..b80baf123050e 100644 --- a/packages/next/src/build/webpack/plugins/nextjs-require-cache-hot-reloader.ts +++ b/packages/next/src/build/webpack/plugins/nextjs-require-cache-hot-reloader.ts @@ -24,7 +24,7 @@ export function deleteAppClientCache() { if ((global as any)._nextDeleteAppClientCache) { ;(global as any)._nextDeleteAppClientCache() } - // ensure we reset the cache for sc_server components + // ensure we reset the cache for rsc components // loaded via react-server-dom-webpack const reactServerDomModId = require.resolve( 'react-server-dom-webpack/client.edge' diff --git a/packages/next/src/lib/constants.ts b/packages/next/src/lib/constants.ts index b4511c146ff8f..29e849eb5cf03 100644 --- a/packages/next/src/lib/constants.ts +++ b/packages/next/src/lib/constants.ts @@ -86,25 +86,56 @@ export const SERVER_RUNTIME: Record = { nodejs: 'nodejs', } +/** + * The names of the webpack layers. These layers are the primitives for the + * webpack chunks. + */ const WEBPACK_LAYERS_NAMES = { - shared: 'sc_shared', - server: 'sc_server', - client: 'sc_client', - action: 'sc_action', + /** + * The layer for the shared code between the client and server bundles. + */ + shared: 'shared', + /** + * React Server Components layer (rsc). + */ + reactServerComponents: 'rsc', + /** + * Server Side Rendering layer (ssr). + */ + serverSideRendering: 'ssr', + /** + * The browser client bundle layer for actions. + */ + actionBrowser: 'actionBrowser', + /** + * The layer for the API routes. + */ api: 'api', + /** + * The layer for the middleware code. + */ middleware: 'middleware', + /** + * The layer for assets on the edge. + */ edgeAsset: 'edge-asset', - appClient: 'app-client', - metadataRoute: 'app-metadata-route', + /** + * The browser client bundle layer for App directory. + */ + appPagesBrowser: 'app-pages-browser', + /** + * The server bundle layer for metadata routes. + */ + appMetadataRoute: 'app-metadata-route', } export const WEBPACK_LAYERS = { ...WEBPACK_LAYERS_NAMES, GROUP: { server: [ - WEBPACK_LAYERS_NAMES.server, - WEBPACK_LAYERS_NAMES.action, - WEBPACK_LAYERS_NAMES.metadataRoute, + WEBPACK_LAYERS_NAMES.reactServerComponents, + WEBPACK_LAYERS_NAMES.actionBrowser, + WEBPACK_LAYERS_NAMES.appMetadataRoute, ], }, } diff --git a/packages/next/src/server/dev/hot-reloader.ts b/packages/next/src/server/dev/hot-reloader.ts index d0fba49f910c9..465aed27e82ca 100644 --- a/packages/next/src/server/dev/hot-reloader.ts +++ b/packages/next/src/server/dev/hot-reloader.ts @@ -427,8 +427,10 @@ export default class HotReloader { )?.[1] if (file) { // `file` is filepath in `pages/` but it can be weird long webpack url in `app/`. - // If it's a webpack loader URL, it will start with '(app-client)/./' - if (file.startsWith('(app-client)/./')) { + // If it's a webpack loader URL, it will start with '(app-pages)/./' + if ( + file.startsWith(`(${WEBPACK_LAYERS.appPagesBrowser})/./`) + ) { const fileUrl = new URL(file, 'file://') const cwd = process.cwd() const modules = fileUrl.searchParams @@ -1044,7 +1046,7 @@ export default class HotReloader { .toString('hex') if ( - mod.layer === WEBPACK_LAYERS.server && + mod.layer === WEBPACK_LAYERS.reactServerComponents && mod?.buildInfo?.rsc?.type !== 'client' ) { chunksHashServerLayer.add(hash) @@ -1059,7 +1061,7 @@ export default class HotReloader { ) if ( - mod.layer === WEBPACK_LAYERS.server && + mod.layer === WEBPACK_LAYERS.reactServerComponents && mod?.buildInfo?.rsc?.type !== 'client' ) { chunksHashServerLayer.add(hash) @@ -1092,7 +1094,8 @@ export default class HotReloader { pageHashMap.set(key, curHash) if (serverComponentChangedItems) { - const serverKey = WEBPACK_LAYERS.server + ':' + key + const serverKey = + WEBPACK_LAYERS.reactServerComponents + ':' + key const prevServerHash = pageHashMap.get(serverKey) const curServerHash = chunksHashServerLayer.toString() if (prevServerHash && prevServerHash !== curServerHash) { diff --git a/packages/next/src/shared/lib/constants.ts b/packages/next/src/shared/lib/constants.ts index f81f65aa426b8..18f36b31980a3 100644 --- a/packages/next/src/shared/lib/constants.ts +++ b/packages/next/src/shared/lib/constants.ts @@ -54,7 +54,7 @@ export const CLIENT_STATIC_FILES_PATH = 'static' export const CLIENT_STATIC_FILES_RUNTIME = 'runtime' export const STRING_LITERAL_DROP_BUNDLE = '__NEXT_DROP_CLIENT_FILE__' export const NEXT_BUILTIN_DOCUMENT = '__NEXT_BUILTIN_DOCUMENT__' -export const NEXT_CLIENT_SSR_ENTRY_SUFFIX = '.__sc_client__' +export const NEXT_CLIENT_SSR_ENTRY_SUFFIX = '.__ssr__' // server/[entry]/page_client-reference-manifest.js export const CLIENT_REFERENCE_MANIFEST = 'client-reference-manifest' @@ -70,7 +70,7 @@ export const MIDDLEWARE_REACT_LOADABLE_MANIFEST = export const CLIENT_STATIC_FILES_RUNTIME_MAIN = `main` export const CLIENT_STATIC_FILES_RUNTIME_MAIN_APP = `${CLIENT_STATIC_FILES_RUNTIME_MAIN}-app` // next internal client components chunk for layouts -export const APP_CLIENT_INTERNALS = 'app-client-internals' +export const APP_CLIENT_INTERNALS = 'app-pages-internals' // static/runtime/react-refresh.js export const CLIENT_STATIC_FILES_RUNTIME_REACT_REFRESH = `react-refresh` // static/runtime/amp.js