From 1d2f636bba4104bbada294330726e279ab06791f Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Wed, 7 Dec 2022 21:04:51 +0100 Subject: [PATCH] refactor code --- packages/next/server/dev/hot-reloader.ts | 14 +- test/e2e/app-dir/index.test.ts | 371 ++++++++++++----------- 2 files changed, 194 insertions(+), 191 deletions(-) diff --git a/packages/next/server/dev/hot-reloader.ts b/packages/next/server/dev/hot-reloader.ts index d95f281a9fd361d..7b9ba8b263f5b5f 100644 --- a/packages/next/server/dev/hot-reloader.ts +++ b/packages/next/server/dev/hot-reloader.ts @@ -766,7 +766,7 @@ export default class HotReloader { ( pageHashMap: Map, changedItems: Set, - serverComponentChangeCallback?: (key: string) => void + serverComponentChangedItems?: Set ) => (stats: webpack.Compilation) => { try { @@ -849,12 +849,12 @@ export default class HotReloader { } pageHashMap.set(key, curHash) - if (serverComponentChangeCallback) { + if (serverComponentChangedItems) { const serverKey = WEBPACK_LAYERS.server + ':' + key const prevServerHash = pageHashMap.get(serverKey) const curServerHash = chunksHashServerLayer.toString() if (prevServerHash && prevServerHash !== curServerHash) { - serverComponentChangeCallback(key) + serverComponentChangedItems.add(key) } pageHashMap.set(serverKey, curServerHash) } @@ -877,8 +877,10 @@ export default class HotReloader { ) this.multiCompiler.compilers[1].hooks.emit.tap( 'NextjsHotReloaderForServer', - trackPageChanges(prevServerPageHashes, changedServerPages, (key) => - changedServerComponentPages.add(key) + trackPageChanges( + prevServerPageHashes, + changedServerPages, + changedServerComponentPages ) ) this.multiCompiler.compilers[2].hooks.emit.tap( @@ -886,7 +888,7 @@ export default class HotReloader { trackPageChanges( prevEdgeServerPageHashes, changedEdgeServerPages, - (key) => changedServerComponentPages.add(key) + changedServerComponentPages ) ) diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index e80861d4acd9a29..dea29e38e34c3f8 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -404,141 +404,6 @@ describe('app dir', () => { } } ) - ;(isDev ? describe : describe.skip)('HMR', () => { - it('should HMR correctly for server component', async () => { - const filePath = 'app/dashboard/index/page.js' - const origContent = await next.readFile(filePath) - - try { - const browser = await webdriver(next.url, '/dashboard/index') - expect(await browser.elementByCss('p').text()).toContain( - 'hello from app/dashboard/index' - ) - - await next.patchFile( - filePath, - origContent.replace('hello from', 'swapped from') - ) - - await check(() => browser.elementByCss('p').text(), /swapped from/) - } finally { - await next.patchFile(filePath, origContent) - } - }) - - 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 HMR correctly when changing the component type', async () => { - const filePath = 'app/dashboard/page/page.jsx' - const origContent = await next.readFile(filePath) - - try { - const browser = await webdriver(next.url, '/dashboard/page') - - expect(await browser.elementByCss('p').text()).toContain( - 'hello dashboard/page!' - ) - - // Test HMR with server component - await next.patchFile( - filePath, - origContent.replace( - 'hello dashboard/page!', - 'hello dashboard/page in server component!' - ) - ) - await check( - () => browser.elementByCss('p').text(), - /in server component/ - ) - - // Change to client component - await next.patchFile( - filePath, - origContent - .replace("// 'use client'", "'use client'") - .replace( - 'hello dashboard/page!', - 'hello dashboard/page in client component!' - ) - ) - await check( - () => browser.elementByCss('p').text(), - /in client component/ - ) - - // Change back to server component - await next.patchFile( - filePath, - origContent.replace( - 'hello dashboard/page!', - 'hello dashboard/page in server component2!' - ) - ) - await check( - () => browser.elementByCss('p').text(), - /in server component2/ - ) - - // Change to client component again - await next.patchFile( - filePath, - origContent - .replace("// 'use client'", "'use client'") - .replace( - 'hello dashboard/page!', - 'hello dashboard/page in client component2!' - ) - ) - await check( - () => browser.elementByCss('p').text(), - /in client component2/ - ) - } finally { - await next.patchFile(filePath, origContent) - } - }) - }) it('should handle hash in initial url', async () => { const browser = await webdriver(next.url, '/dashboard#abc') @@ -1699,66 +1564,202 @@ describe('app dir', () => { ).toBe('50px') }) }) + }) - if (isDev) { - describe('HMR', () => { - it('should support HMR for CSS imports in server components', async () => { - const filePath = 'app/css/css-page/style.css' - const origContent = await next.readFile(filePath) + if (isDev) { + describe('HMR', () => { + it('should support HMR for CSS imports in server components', async () => { + const filePath = 'app/css/css-page/style.css' + const origContent = await next.readFile(filePath) - // h1 should be red - const browser = await webdriver(next.url, '/css/css-page') - expect( - await browser.eval( - `window.getComputedStyle(document.querySelector('h1')).color` - ) - ).toBe('rgb(255, 0, 0)') + // h1 should be red + const browser = await webdriver(next.url, '/css/css-page') + expect( + await browser.eval( + `window.getComputedStyle(document.querySelector('h1')).color` + ) + ).toBe('rgb(255, 0, 0)') - try { - await next.patchFile(filePath, origContent.replace('red', 'blue')) - - // Wait for HMR to trigger - await check( - () => - browser.eval( - `window.getComputedStyle(document.querySelector('h1')).color` - ), - 'rgb(0, 0, 255)' - ) - } finally { - await next.patchFile(filePath, origContent) - } - }) + try { + await next.patchFile(filePath, origContent.replace('red', 'blue')) + + // Wait for HMR to trigger + await check( + () => + browser.eval( + `window.getComputedStyle(document.querySelector('h1')).color` + ), + 'rgb(0, 0, 255)' + ) + } finally { + await next.patchFile(filePath, origContent) + } + }) + + it('should support HMR for CSS imports in client components', async () => { + const filePath = 'app/css/css-client/client-page.css' + const origContent = await next.readFile(filePath) + + // h1 should be red + const browser = await webdriver(next.url, '/css/css-client') + expect( + await browser.eval( + `window.getComputedStyle(document.querySelector('h1')).color` + ) + ).toBe('rgb(255, 0, 0)') + + try { + await next.patchFile(filePath, origContent.replace('red', 'blue')) + + await check( + () => + browser.eval( + `window.getComputedStyle(document.querySelector('h1')).color` + ), + 'rgb(0, 0, 255)' + ) + } finally { + await next.patchFile(filePath, origContent) + } + }) + + it('should HMR correctly for server component', async () => { + const filePath = 'app/dashboard/index/page.js' + const origContent = await next.readFile(filePath) + + try { + const browser = await webdriver(next.url, '/dashboard/index') + expect(await browser.elementByCss('p').text()).toContain( + 'hello from app/dashboard/index' + ) + + await next.patchFile( + filePath, + origContent.replace('hello from', 'swapped from') + ) + + await check(() => browser.elementByCss('p').text(), /swapped from/) + } finally { + await next.patchFile(filePath, origContent) + } + }) + + 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') + ) - it('should support HMR for CSS imports in client components', async () => { - const filePath = 'app/css/css-client/client-page.css' - const origContent = await next.readFile(filePath) + await check(() => browser.elementByCss('p').text(), /swapped from/) - // h1 should be red - const browser = await webdriver(next.url, '/css/css-client') + 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 browser.eval( - `window.getComputedStyle(document.querySelector('h1')).color` + await renderViaHTTP(next.url, '/client-component-route') + ).toContain('hello from') + } finally { + await next.patchFile(filePath, origContent) + } + }) + + it('should HMR correctly when changing the component type', async () => { + const filePath = 'app/dashboard/page/page.jsx' + const origContent = await next.readFile(filePath) + + try { + const browser = await webdriver(next.url, '/dashboard/page') + + expect(await browser.elementByCss('p').text()).toContain( + 'hello dashboard/page!' + ) + + // Test HMR with server component + await next.patchFile( + filePath, + origContent.replace( + 'hello dashboard/page!', + 'hello dashboard/page in server component!' ) - ).toBe('rgb(255, 0, 0)') + ) + await check( + () => browser.elementByCss('p').text(), + /in server component/ + ) - try { - await next.patchFile(filePath, origContent.replace('red', 'blue')) - - await check( - () => - browser.eval( - `window.getComputedStyle(document.querySelector('h1')).color` - ), - 'rgb(0, 0, 255)' + // Change to client component + await next.patchFile( + filePath, + origContent + .replace("// 'use client'", "'use client'") + .replace( + 'hello dashboard/page!', + 'hello dashboard/page in client component!' + ) + ) + await check( + () => browser.elementByCss('p').text(), + /in client component/ + ) + + // Change back to server component + await next.patchFile( + filePath, + origContent.replace( + 'hello dashboard/page!', + 'hello dashboard/page in server component2!' ) - } finally { - await next.patchFile(filePath, origContent) - } - }) + ) + await check( + () => browser.elementByCss('p').text(), + /in server component2/ + ) + + // Change to client component again + await next.patchFile( + filePath, + origContent + .replace("// 'use client'", "'use client'") + .replace( + 'hello dashboard/page!', + 'hello dashboard/page in client component2!' + ) + ) + await check( + () => browser.elementByCss('p').text(), + /in client component2/ + ) + } finally { + await next.patchFile(filePath, origContent) + } }) - } - }) + }) + } describe('searchParams prop', () => { describe('client component', () => {