From 927fc9e2209b4c42f5850020fa952d6da7648397 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 6 Jul 2023 02:06:11 +0200 Subject: [PATCH] skip hot reload sync event for applying hmr updates (#52270) ### Issue x-ref: https://github.com/vercel/next.js/actions/runs/5469070005/jobs/9957658991?pr=52282#step:27:526 metadata tests are failing as flaky recently, then after digging into it, noticed it as a hmr issue. **Steps to repro with metadata test app** The later (after the 1st one) visited page with client components imports sometimes throw an full reload refresh warning > Fast Refresh will perform a full reload when you edit a file that's imported by modules outside of the React rendering tree. Turns out there's some unexpected hmr events when `"sync"` event is triggered, and client tries to apply the updates but then failed. This PR excludes the triggering by `"sync"` for RSC pages updates. `'sync'` event with errors/warnings will still be handled and then `'built'` event will be handled with hot reload updates Possibly related to #40184 --- .../components/react-dev-overlay/hot-reloader-client.tsx | 6 +++--- test/e2e/app-dir/metadata/app/api/manifest/route.ts | 7 +++++++ test/e2e/app-dir/metadata/app/api/preload/route.ts | 7 +++++++ test/e2e/app-dir/metadata/app/api/route.ts | 4 +--- test/e2e/app-dir/metadata/app/basic-edge/client.tsx | 2 +- test/e2e/app-dir/metadata/app/basic-edge/page.tsx | 2 +- test/e2e/app-dir/metadata/app/basic/client.tsx | 2 +- test/e2e/app-dir/metadata/app/basic/page.tsx | 2 +- .../metadata/app/title-template/extra/inner/page.tsx | 4 ++-- test/e2e/app-dir/metadata/metadata.test.ts | 8 ++++---- 10 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 test/e2e/app-dir/metadata/app/api/manifest/route.ts create mode 100644 test/e2e/app-dir/metadata/app/api/preload/route.ts diff --git a/packages/next/src/client/components/react-dev-overlay/hot-reloader-client.tsx b/packages/next/src/client/components/react-dev-overlay/hot-reloader-client.tsx index f4a87d7c03901..7b089eebff165 100644 --- a/packages/next/src/client/components/react-dev-overlay/hot-reloader-client.tsx +++ b/packages/next/src/client/components/react-dev-overlay/hot-reloader-client.tsx @@ -335,9 +335,9 @@ function processMessage( ) const isHotUpdate = - obj.action !== 'sync' || - ((!window.__NEXT_DATA__ || window.__NEXT_DATA__.page !== '/_error') && - isUpdateAvailable()) + obj.action !== 'sync' && + (!window.__NEXT_DATA__ || window.__NEXT_DATA__.page !== '/_error') && + isUpdateAvailable() // Attempt to apply hot updates or reload. if (isHotUpdate) { diff --git a/test/e2e/app-dir/metadata/app/api/manifest/route.ts b/test/e2e/app-dir/metadata/app/api/manifest/route.ts new file mode 100644 index 0000000000000..44ea9cef54e45 --- /dev/null +++ b/test/e2e/app-dir/metadata/app/api/manifest/route.ts @@ -0,0 +1,7 @@ +export function GET() { + return new Response('{ "name": "metadata-app", }', { + headers: { + 'Content-Type': 'application/xml; charset=utf-8', + }, + }) +} diff --git a/test/e2e/app-dir/metadata/app/api/preload/route.ts b/test/e2e/app-dir/metadata/app/api/preload/route.ts new file mode 100644 index 0000000000000..f6fb8004e88d4 --- /dev/null +++ b/test/e2e/app-dir/metadata/app/api/preload/route.ts @@ -0,0 +1,7 @@ +export function GET() { + return new Response('console.log("hello from preload")', { + headers: { + 'Content-Type': 'application/javascript; charset=utf-8', + }, + }) +} diff --git a/test/e2e/app-dir/metadata/app/api/route.ts b/test/e2e/app-dir/metadata/app/api/route.ts index d356531de7582..a68a9bc758a54 100644 --- a/test/e2e/app-dir/metadata/app/api/route.ts +++ b/test/e2e/app-dir/metadata/app/api/route.ts @@ -1,5 +1,3 @@ -import { NextResponse } from 'next/server' - export function GET() { - return new NextResponse('hello api route') + return new Response('hello api route') } diff --git a/test/e2e/app-dir/metadata/app/basic-edge/client.tsx b/test/e2e/app-dir/metadata/app/basic-edge/client.tsx index dd27142d7d66c..f23d5e4ff5e04 100644 --- a/test/e2e/app-dir/metadata/app/basic-edge/client.tsx +++ b/test/e2e/app-dir/metadata/app/basic-edge/client.tsx @@ -5,7 +5,7 @@ import ReactDOM from 'react-dom' // NOTE: atm preload/prefetch/prefetchDNS are only supported in the SSR and client, not in RSC yet export default function Client() { // @ts-ignore - ReactDOM.preload('/preload-url', { as: 'script' }) + ReactDOM.preload('/api/preload', { as: 'script' }) // @ts-ignore ReactDOM.preconnect('/preconnect-url', { crossOrigin: 'use-credentials' }) // @ts-ignore diff --git a/test/e2e/app-dir/metadata/app/basic-edge/page.tsx b/test/e2e/app-dir/metadata/app/basic-edge/page.tsx index 550b3413d7e4c..c37d861c55cf7 100644 --- a/test/e2e/app-dir/metadata/app/basic-edge/page.tsx +++ b/test/e2e/app-dir/metadata/app/basic-edge/page.tsx @@ -27,7 +27,7 @@ export const metadata: Metadata = { authors: [{ name: 'huozhi' }, { name: 'tree', url: 'https://tree.com' }], themeColor: { color: 'cyan', media: '(prefers-color-scheme: dark)' }, colorScheme: 'dark', - manifest: 'https://www.google.com/manifest', + manifest: '/api/manifest', viewport: { width: 'device-width', initialScale: 1, diff --git a/test/e2e/app-dir/metadata/app/basic/client.tsx b/test/e2e/app-dir/metadata/app/basic/client.tsx index dd27142d7d66c..f23d5e4ff5e04 100644 --- a/test/e2e/app-dir/metadata/app/basic/client.tsx +++ b/test/e2e/app-dir/metadata/app/basic/client.tsx @@ -5,7 +5,7 @@ import ReactDOM from 'react-dom' // NOTE: atm preload/prefetch/prefetchDNS are only supported in the SSR and client, not in RSC yet export default function Client() { // @ts-ignore - ReactDOM.preload('/preload-url', { as: 'script' }) + ReactDOM.preload('/api/preload', { as: 'script' }) // @ts-ignore ReactDOM.preconnect('/preconnect-url', { crossOrigin: 'use-credentials' }) // @ts-ignore diff --git a/test/e2e/app-dir/metadata/app/basic/page.tsx b/test/e2e/app-dir/metadata/app/basic/page.tsx index 82f9f04e593a8..979ce03ba041f 100644 --- a/test/e2e/app-dir/metadata/app/basic/page.tsx +++ b/test/e2e/app-dir/metadata/app/basic/page.tsx @@ -25,7 +25,7 @@ export const metadata: Metadata = { authors: [{ name: 'huozhi' }, { name: 'tree', url: 'https://tree.com' }], themeColor: { color: 'cyan', media: '(prefers-color-scheme: dark)' }, colorScheme: 'dark', - manifest: 'https://www.google.com/manifest', + manifest: '/api/manifest', viewport: { width: 'device-width', initialScale: 1, diff --git a/test/e2e/app-dir/metadata/app/title-template/extra/inner/page.tsx b/test/e2e/app-dir/metadata/app/title-template/extra/inner/page.tsx index 48aceeac4934f..4524da11cf3d8 100644 --- a/test/e2e/app-dir/metadata/app/title-template/extra/inner/page.tsx +++ b/test/e2e/app-dir/metadata/app/title-template/extra/inner/page.tsx @@ -7,9 +7,9 @@ export default function Page() { to /
- + {/* to /basic - + */} ) } diff --git a/test/e2e/app-dir/metadata/metadata.test.ts b/test/e2e/app-dir/metadata/metadata.test.ts index 1f74967b229f7..417f88d368758 100644 --- a/test/e2e/app-dir/metadata/metadata.test.ts +++ b/test/e2e/app-dir/metadata/metadata.test.ts @@ -217,10 +217,10 @@ createNextDescribe( }) await matchMultiDom('link', 'rel', 'href', { - manifest: 'https://www.google.com/manifest', + manifest: '/api/manifest', author: 'https://tree.com', preconnect: '/preconnect-url', - preload: '/preload-url', + preload: '/api/preload', 'dns-prefetch': '/dns-prefetch-url', }) @@ -251,10 +251,10 @@ createNextDescribe( }) await matchMultiDom('link', 'rel', 'href', { - manifest: 'https://www.google.com/manifest', + manifest: '/api/manifest', author: 'https://tree.com', preconnect: '/preconnect-url', - preload: '/preload-url', + preload: '/api/preload', 'dns-prefetch': '/dns-prefetch-url', })