From 6fb1121e8c437bb5342d4eddfdced9b611130604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Born=C3=B6?= Date: Fri, 9 Sep 2022 22:09:15 +0200 Subject: [PATCH] Add missing trace for full reload event (#40393) Added missing trace for `client-full-reload` event in hot reloader. Full reload tests moved to hmr, think they make more sense there than on their own. --- packages/next/server/dev/hot-reloader.ts | 4 + test/development/basic/hmr.test.ts | 83 ++++++++++++++++ .../hmr/pages/hmr/anonymous-page-function.js | 3 + .../basic/hmr/pages/hmr/runtime-error.js | 4 + .../full-reload-warning/index.test.ts | 97 ------------------- 5 files changed, 94 insertions(+), 97 deletions(-) create mode 100644 test/development/basic/hmr/pages/hmr/anonymous-page-function.js create mode 100644 test/development/basic/hmr/pages/hmr/runtime-error.js delete mode 100644 test/development/full-reload-warning/index.test.ts diff --git a/packages/next/server/dev/hot-reloader.ts b/packages/next/server/dev/hot-reloader.ts index 7a7584b43bdc7e5..0130ed5a93ffab0 100644 --- a/packages/next/server/dev/hot-reloader.ts +++ b/packages/next/server/dev/hot-reloader.ts @@ -361,6 +361,10 @@ export default class HotReloader { break } case 'client-full-reload': { + traceChild = { + name: payload.event, + attrs: { stackTrace: payload.stackTrace ?? '' }, + } Log.warn( 'Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works' ) diff --git a/test/development/basic/hmr.test.ts b/test/development/basic/hmr.test.ts index 48c49a704e69163..1b852b8df2ab352 100644 --- a/test/development/basic/hmr.test.ts +++ b/test/development/basic/hmr.test.ts @@ -776,11 +776,94 @@ describe('basic HMR', () => { }) }) + describe('Full reload', () => { + it('should warn about full reload in cli output - anonymous page function', async () => { + const start = next.cliOutput.length + const browser = await webdriver( + next.appPort, + `/hmr/anonymous-page-function` + ) + expect(await browser.elementByCss('p').text()).toBe('hello world') + expect(next.cliOutput.slice(start)).not.toContain( + 'Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works' + ) + + const currentFileContent = await next.readFile( + './pages/hmr/anonymous-page-function.js' + ) + const newFileContent = currentFileContent.replace( + '

hello world

', + '

hello world!!!

' + ) + await next.patchFile( + './pages/hmr/anonymous-page-function.js', + newFileContent + ) + await check(() => browser.elementByCss('p').text(), 'hello world!!!') + + // CLI warning and stacktrace + expect(next.cliOutput.slice(start)).toContain( + 'Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works' + ) + expect(next.cliOutput.slice(start)).toContain( + 'Error: Aborted because ./pages/hmr/anonymous-page-function.js is not accepted' + ) + + // Browser warning + const browserLogs = await browser.log() + expect( + browserLogs.some(({ message }) => + message.includes( + "Fast Refresh will perform a full reload when you edit a file that's imported by modules outside of the React rendering tree." + ) + ) + ).toBeTruthy() + }) + + it('should warn about full reload in cli output - runtime-error', async () => { + const start = next.cliOutput.length + const browser = await webdriver(next.appPort, `/hmr/runtime-error`) + await check( + () => getRedboxHeader(browser), + /ReferenceError: whoops is not defined/ + ) + expect(next.cliOutput.slice(start)).not.toContain( + 'Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works' + ) + + const currentFileContent = await next.readFile( + './pages/hmr/runtime-error.js' + ) + const newFileContent = currentFileContent.replace('whoops', '"whoops"') + await next.patchFile('./pages/hmr/runtime-error.js', newFileContent) + await check(() => browser.elementByCss('body').text(), 'whoops') + + // CLI warning and stacktrace + expect(next.cliOutput.slice(start)).toContain( + 'Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works' + ) + expect(next.cliOutput.slice(start)).not.toContain( + 'Error: Aborted because ./pages/runtime-error.js is not accepted' + ) + + // Browser warning + const browserLogs = await browser.log() + expect( + browserLogs.some(({ message }) => + message.includes( + '[Fast Refresh] performing full reload because your application had an unrecoverable error' + ) + ) + ).toBeTruthy() + }) + }) + it('should have client HMR events in trace file', async () => { const traceData = await next.readFile('.next/trace') expect(traceData).toContain('client-hmr-latency') expect(traceData).toContain('client-error') expect(traceData).toContain('client-success') + expect(traceData).toContain('client-full-reload') }) it('should have correct compile timing after fixing error', async () => { diff --git a/test/development/basic/hmr/pages/hmr/anonymous-page-function.js b/test/development/basic/hmr/pages/hmr/anonymous-page-function.js new file mode 100644 index 000000000000000..10e018391ed83cc --- /dev/null +++ b/test/development/basic/hmr/pages/hmr/anonymous-page-function.js @@ -0,0 +1,3 @@ +export default function () { + return

hello world

+} diff --git a/test/development/basic/hmr/pages/hmr/runtime-error.js b/test/development/basic/hmr/pages/hmr/runtime-error.js new file mode 100644 index 000000000000000..8ee8aeb6ea45c13 --- /dev/null +++ b/test/development/basic/hmr/pages/hmr/runtime-error.js @@ -0,0 +1,4 @@ +export default function () { + // eslint-disable-next-line no-undef + return whoops +} diff --git a/test/development/full-reload-warning/index.test.ts b/test/development/full-reload-warning/index.test.ts deleted file mode 100644 index 1ff815fa566493f..000000000000000 --- a/test/development/full-reload-warning/index.test.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { createNext } from 'e2e-utils' -import { NextInstance } from 'test/lib/next-modes/base' -import { check, getRedboxHeader } from 'next-test-utils' -import webdriver from 'next-webdriver' - -describe('show a warning in CLI and browser when doing a full reload', () => { - let next: NextInstance - - beforeEach(async () => { - next = await createNext({ - files: { - 'pages/anonymous-page-function.js': ` - export default function() { - return

hello world

- } - `, - 'pages/runtime-error.js': ` - export default function() { - return whoops - } - `, - }, - dependencies: {}, - }) - }) - afterEach(() => next.destroy()) - - test('error', async () => { - const browser = await webdriver(next.url, `/anonymous-page-function`) - expect(await browser.elementByCss('p').text()).toBe('hello world') - expect(next.cliOutput).not.toContain( - 'Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works' - ) - - const currentFileContent = await next.readFile( - './pages/anonymous-page-function.js' - ) - const newFileContent = currentFileContent.replace( - '

hello world

', - '

hello world!!!

' - ) - await next.patchFile('./pages/anonymous-page-function.js', newFileContent) - await check(() => browser.elementByCss('p').text(), 'hello world!!!') - - // CLI warning and stacktrace - expect(next.cliOutput).toContain( - 'Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works' - ) - expect(next.cliOutput).toContain( - 'Error: Aborted because ./pages/anonymous-page-function.js is not accepted' - ) - - // Browser warning - const browserLogs = await browser.log() - expect( - browserLogs.some(({ message }) => - message.includes( - "Fast Refresh will perform a full reload when you edit a file that's imported by modules outside of the React rendering tree." - ) - ) - ).toBeTruthy() - }) - - test('runtime-error', async () => { - const browser = await webdriver(next.url, `/runtime-error`) - await check( - () => getRedboxHeader(browser), - /ReferenceError: whoops is not defined/ - ) - expect(next.cliOutput).not.toContain( - 'Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works' - ) - - const currentFileContent = await next.readFile('./pages/runtime-error.js') - const newFileContent = currentFileContent.replace('whoops', '"whoops"') - await next.patchFile('./pages/runtime-error.js', newFileContent) - await check(() => browser.elementByCss('body').text(), 'whoops') - - // CLI warning and stacktrace - expect(next.cliOutput).toContain( - 'Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works' - ) - expect(next.cliOutput).not.toContain( - 'Error: Aborted because ./pages/runtime-error.js is not accepted' - ) - - // Browser warning - const browserLogs = await browser.log() - expect( - browserLogs.some(({ message }) => - message.includes( - '[Fast Refresh] performing full reload because your application had an unrecoverable error' - ) - ) - ).toBeTruthy() - }) -})