-
Notifications
You must be signed in to change notification settings - Fork 28k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wait for pending Webpack Hot Updates before evaluating JS from RSC responses #67673
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
6b52a18
Current behavior of HMR to page with new bundler runtime
eps1lon 36f7d76
Wait for pending Webpack Hot Updates before evaluating JS from RSC re…
eps1lon 6d38386
Only await Webpack Runtime update outside of prefetches
eps1lon c9be020
Only await Webpack Runtime update when Webpack is used
eps1lon 58a3ff7
Work around existing bugs
eps1lon fe3296d
Update packages/next/src/client/components/router-reducer/fetch-serve…
eps1lon ccf31b9
Revert "Work around existing bugs"
eps1lon 0467756
Revert "Only await Webpack Runtime update outside of prefetches"
eps1lon 3438909
typo
eps1lon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,17 +47,35 @@ let __nextDevClientId = Math.round(Math.random() * 100 + Date.now()) | |
let reloading = false | ||
let startLatency: number | null = null | ||
|
||
function onBeforeFastRefresh(dispatcher: Dispatcher, hasUpdates: boolean) { | ||
let pendingHotUpdateWebpack = Promise.resolve() | ||
let resolvePendingHotUpdateWebpack: () => void = () => {} | ||
function setPendingHotUpdateWebpack() { | ||
pendingHotUpdateWebpack = new Promise((resolve) => { | ||
resolvePendingHotUpdateWebpack = () => { | ||
resolve() | ||
} | ||
}) | ||
} | ||
|
||
export function waitForWebpackRuntimeHotUpdate() { | ||
return pendingHotUpdateWebpack | ||
} | ||
|
||
function handleBeforeHotUpdateWebpack( | ||
dispatcher: Dispatcher, | ||
hasUpdates: boolean | ||
) { | ||
if (hasUpdates) { | ||
dispatcher.onBeforeRefresh() | ||
} | ||
} | ||
|
||
function onFastRefresh( | ||
function handleSuccessfulHotUpdateWebpack( | ||
dispatcher: Dispatcher, | ||
sendMessage: (message: string) => void, | ||
updatedModules: ReadonlyArray<string> | ||
) { | ||
resolvePendingHotUpdateWebpack() | ||
dispatcher.onBuildOk() | ||
reportHmrLatency(sendMessage, updatedModules) | ||
|
||
|
@@ -159,6 +177,7 @@ function tryApplyUpdates( | |
dispatcher: Dispatcher | ||
) { | ||
if (!isUpdateAvailable() || !canApplyUpdates()) { | ||
resolvePendingHotUpdateWebpack() | ||
dispatcher.onBuildOk() | ||
reportHmrLatency(sendMessage, []) | ||
return | ||
|
@@ -281,12 +300,16 @@ function processMessage( | |
} else { | ||
tryApplyUpdates( | ||
function onBeforeHotUpdate(hasUpdates: boolean) { | ||
onBeforeFastRefresh(dispatcher, hasUpdates) | ||
handleBeforeHotUpdateWebpack(dispatcher, hasUpdates) | ||
}, | ||
function onSuccessfulHotUpdate(webpackUpdatedModules: string[]) { | ||
// Only dismiss it when we're sure it's a hot update. | ||
// Otherwise it would flicker right before the reload. | ||
onFastRefresh(dispatcher, sendMessage, webpackUpdatedModules) | ||
handleSuccessfulHotUpdateWebpack( | ||
dispatcher, | ||
sendMessage, | ||
webpackUpdatedModules | ||
) | ||
}, | ||
sendMessage, | ||
dispatcher | ||
|
@@ -320,6 +343,9 @@ function processMessage( | |
} | ||
case HMR_ACTIONS_SENT_TO_BROWSER.BUILDING: { | ||
startLatency = Date.now() | ||
if (!process.env.TURBOPACK) { | ||
setPendingHotUpdateWebpack() | ||
} | ||
Comment on lines
344
to
+348
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The downside here is that we always get a hot update on client-side navigations as far as I can tell. Even if the runtime doesn't get new functionality, it does get updates to "use strict";
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
self["webpackHotUpdate_N_E"]("webpack",{},
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ /* webpack/runtime/getFullHash */
/******/ (() => {
/******/ __webpack_require__.h = () => ("d60fe58ebbed83dc")
/******/ })();
/******/
/******/ }
); |
||
console.log('[Fast Refresh] rebuilding') | ||
break | ||
} | ||
|
@@ -426,6 +452,7 @@ function processMessage( | |
reloading = true | ||
return window.location.reload() | ||
} | ||
resolvePendingHotUpdateWebpack() | ||
startTransition(() => { | ||
router.hmrRefresh() | ||
dispatcher.onRefresh() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
test/development/app-hmr/app/bundler-runtime-changes/new-runtime-functionality/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
'use client' | ||
// requires | ||
import * as React from 'react' | ||
|
||
export default function RuntimeChangesNewRuntimeFunctionalityPage() { | ||
React.useEffect(() => {}, []) | ||
return <div data-testid="new-runtime-functionality-page" /> | ||
} |
9 changes: 9 additions & 0 deletions
9
test/development/app-hmr/app/bundler-runtime-changes/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import Link from 'next/link' | ||
|
||
export default function RuntimeChangesPage() { | ||
return ( | ||
<Link href="/bundler-runtime-changes/new-runtime-functionality"> | ||
Click me | ||
</Link> | ||
) | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "ES2017", | ||
"lib": ["dom", "dom.iterable", "esnext"], | ||
"allowJs": true, | ||
"skipLibCheck": true, | ||
"strict": false, | ||
"noEmit": true, | ||
"incremental": true, | ||
"module": "esnext", | ||
"esModuleInterop": true, | ||
"moduleResolution": "node", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"jsx": "preserve", | ||
"plugins": [ | ||
{ | ||
"name": "next" | ||
} | ||
] | ||
}, | ||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], | ||
"exclude": ["node_modules"] | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drive-by rename. We only call this in Webpack implying there's no Fast Refresh in Turbopack. Fast Refresh is also a React feature that's enabled by HMR so it is a bit confusing to invoke that name at all.