From ac4503b5443d69eeaa6f34bdbfe27921745a7505 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Wed, 23 Nov 2022 15:32:40 +0100 Subject: [PATCH 1/5] add clean up process to manifest globals --- .../webpack/plugins/flight-client-entry-plugin.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts index 77545f5c2b85..8162def22111 100644 --- a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts @@ -3,6 +3,8 @@ import type { ClientComponentImports, NextFlightClientEntryLoaderOptions, } from '../loaders/next-flight-client-entry-loader' +import type { FlightCSSManifest } from './flight-manifest-plugin' + import { webpack } from 'next/dist/compiled/webpack/webpack' import { stringify } from 'querystring' import path from 'path' @@ -19,7 +21,6 @@ import { EDGE_RUNTIME_WEBPACK, FLIGHT_SERVER_CSS_MANIFEST, } from '../../../shared/lib/constants' -import { FlightCSSManifest } from './flight-manifest-plugin' import { ASYNC_CLIENT_MODULES } from './flight-manifest-plugin' import { isClientComponentModule, regexCSS } from '../loaders/utils' import { traverseModules } from '../utils' @@ -37,9 +38,6 @@ export const injectedClientEntries = new Map() export const serverModuleIds = new Map() export const edgeServerModuleIds = new Map() -// TODO-APP: move CSS manifest generation to the flight manifest plugin. -const flightCSSManifest: FlightCSSManifest = {} - export class FlightClientEntryPlugin { dev: boolean appDir: string @@ -111,6 +109,9 @@ export class FlightClientEntryPlugin { } } + edgeServerModuleIds.clear() + serverModuleIds.clear() + traverseModules(compilation, (mod, _chunk, _chunkGroup, modId) => { recordModule(modId + '', mod) }) @@ -121,6 +122,9 @@ export class FlightClientEntryPlugin { const promises: Array< ReturnType > = [] + let flightCSSManifest: FlightCSSManifest = {} + + injectedClientEntries.clear() // Loop over all the entry modules. function forEachEntryModule( @@ -234,6 +238,7 @@ export class FlightClientEntryPlugin { // by the certain chunk. compilation.hooks.afterOptimizeModules.tap(PLUGIN_NAME, () => { const cssImportsForChunk: Record = {} + flightCSSManifest = {} function collectModule(entryName: string, mod: any) { const resource = mod.resource From b5c22395355dd82996e5aaeef3480aa65fc8a1ec Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Wed, 23 Nov 2022 20:37:20 +0100 Subject: [PATCH 2/5] fix --- .../build/webpack/plugins/flight-client-entry-plugin.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts index 8162def22111..f2396fc886d2 100644 --- a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts @@ -109,8 +109,11 @@ export class FlightClientEntryPlugin { } } - edgeServerModuleIds.clear() - serverModuleIds.clear() + if (this.isEdgeServer) { + edgeServerModuleIds.clear() + } else { + serverModuleIds.clear() + } traverseModules(compilation, (mod, _chunk, _chunkGroup, modId) => { recordModule(modId + '', mod) @@ -124,8 +127,6 @@ export class FlightClientEntryPlugin { > = [] let flightCSSManifest: FlightCSSManifest = {} - injectedClientEntries.clear() - // Loop over all the entry modules. function forEachEntryModule( callback: ({ From caf849a56a11c5d04157255847af7a1aef6f6f3e Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Fri, 25 Nov 2022 16:02:38 +0100 Subject: [PATCH 3/5] fix race condition --- .../plugins/flight-client-entry-plugin.ts | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts index 979e7f7e54d5..0ade9a5c3e7a 100644 --- a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts @@ -38,6 +38,9 @@ export const injectedClientEntries = new Map() export const serverModuleIds = new Map() export const edgeServerModuleIds = new Map() +let serverCSSManifest: FlightCSSManifest = {} +let edgeServerCSSManifest: FlightCSSManifest = {} + export class FlightClientEntryPlugin { dev: boolean appDir: string @@ -125,7 +128,6 @@ export class FlightClientEntryPlugin { const promises: Array< ReturnType > = [] - let flightCSSManifest: FlightCSSManifest = {} // Loop over all the entry modules. function forEachEntryModule( @@ -239,7 +241,15 @@ export class FlightClientEntryPlugin { // by the certain chunk. compilation.hooks.afterOptimizeModules.tap(PLUGIN_NAME, () => { const cssImportsForChunk: Record = {} - flightCSSManifest = {} + if (this.isEdgeServer) { + edgeServerCSSManifest = {} + } else { + serverCSSManifest = {} + } + + let cssManifest = this.isEdgeServer + ? edgeServerCSSManifest + : serverCSSManifest function collectModule(entryName: string, mod: any) { const resource = mod.resource @@ -278,10 +288,10 @@ export class FlightClientEntryPlugin { } const entryCSSInfo: Record = - flightCSSManifest.__entry_css__ || {} + cssManifest.__entry_css__ || {} entryCSSInfo[entryName] = cssImportsForChunk[entryName] - Object.assign(flightCSSManifest, { + Object.assign(cssManifest, { __entry_css__: entryCSSInfo, }) }) @@ -326,7 +336,7 @@ export class FlightClientEntryPlugin { clientEntryDependencyMap, }) - Object.assign(flightCSSManifest, cssImports) + Object.assign(cssManifest, cssImports) } }) }) @@ -339,7 +349,14 @@ export class FlightClientEntryPlugin { stage: webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH, }, (assets: webpack.Compilation['assets']) => { - const manifest = JSON.stringify(flightCSSManifest) + const manifest = JSON.stringify({ + ...serverCSSManifest, + ...edgeServerCSSManifest, + __entry_css__: { + ...serverCSSManifest.__entry_css__, + ...edgeServerCSSManifest.__entry_css__, + }, + }) assets[FLIGHT_SERVER_CSS_MANIFEST + '.json'] = new sources.RawSource( manifest ) as unknown as webpack.sources.RawSource From 0284e72c7b3608d568c3fd2110e161e062f78325 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Tue, 29 Nov 2022 00:30:14 +0100 Subject: [PATCH 4/5] fix tests --- .../plugins/flight-client-entry-plugin.ts | 2 +- test/e2e/app-dir/index.test.ts | 89 +++++++++---------- 2 files changed, 44 insertions(+), 47 deletions(-) diff --git a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts index 0ade9a5c3e7a..e2e2267624f3 100644 --- a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts @@ -119,7 +119,7 @@ export class FlightClientEntryPlugin { } traverseModules(compilation, (mod, _chunk, _chunkGroup, modId) => { - recordModule(modId + '', mod) + recordModule(String(modId), mod) }) }) } diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index c9f0bcd1b34f..012435662951 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -382,6 +382,49 @@ describe('app dir', () => { } } ) + ;(isDev ? describe : describe.skip)('HMR', () => { + it('should HMR correctly for client component', async () => { + const filePath = 'app/client-component-route/page.js' + const origContent = await next.readFile(filePath) + + try { + const browser = await webdriver(next.url, '/client-component-route') + + const ssrInitial = await renderViaHTTP( + next.url, + '/client-component-route' + ) + + expect(ssrInitial).toContain('hello from app/client-component-route') + + expect(await browser.elementByCss('p').text()).toContain( + 'hello from app/client-component-route' + ) + + await next.patchFile( + filePath, + origContent.replace('hello from', 'swapped from') + ) + + await check(() => browser.elementByCss('p').text(), /swapped from/) + + const ssrUpdated = await renderViaHTTP( + next.url, + '/client-component-route' + ) + expect(ssrUpdated).toContain('swapped from') + + await next.patchFile(filePath, origContent) + + await check(() => browser.elementByCss('p').text(), /hello from/) + expect( + await renderViaHTTP(next.url, '/client-component-route') + ).toContain('hello from') + } finally { + await next.patchFile(filePath, origContent) + } + }) + }) it('should handle hash in initial url', async () => { const browser = await webdriver(next.url, '/dashboard#abc') @@ -1332,52 +1375,6 @@ describe('app dir', () => { }) }) }) - - if (isDev) { - it('should HMR correctly for client component', async () => { - const filePath = 'app/client-component-route/page.js' - const origContent = await next.readFile(filePath) - - try { - const browser = await webdriver(next.url, '/client-component-route') - - const ssrInitial = await renderViaHTTP( - next.url, - '/client-component-route' - ) - - expect(ssrInitial).toContain( - 'hello from app/client-component-route' - ) - - expect(await browser.elementByCss('p').text()).toContain( - 'hello from app/client-component-route' - ) - - await next.patchFile( - filePath, - origContent.replace('hello from', 'swapped from') - ) - - await check(() => browser.elementByCss('p').text(), /swapped from/) - - const ssrUpdated = await renderViaHTTP( - next.url, - '/client-component-route' - ) - expect(ssrUpdated).toContain('swapped from') - - await next.patchFile(filePath, origContent) - - await check(() => browser.elementByCss('p').text(), /hello from/) - expect( - await renderViaHTTP(next.url, '/client-component-route') - ).toContain('hello from') - } finally { - await next.patchFile(filePath, origContent) - } - }) - } }) describe('css support', () => { From 4e8a9a06e8bedfa334ee45c36f9d4c281d532280 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Tue, 29 Nov 2022 16:10:08 +0100 Subject: [PATCH 5/5] remove clean up for now --- .../build/webpack/plugins/flight-client-entry-plugin.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts index e2e2267624f3..622d837a01b0 100644 --- a/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-client-entry-plugin.ts @@ -112,12 +112,6 @@ export class FlightClientEntryPlugin { } } - if (this.isEdgeServer) { - edgeServerModuleIds.clear() - } else { - serverModuleIds.clear() - } - traverseModules(compilation, (mod, _chunk, _chunkGroup, modId) => { recordModule(String(modId), mod) })