Turbopack: enable server HMR for app route handlers#91466
Turbopack: enable server HMR for app route handlers#91466wbinnssmith wants to merge 1 commit intocanaryfrom
Conversation
Failing test suitesCommit: c011b8e | About building and testing Next.js
Expand output● twoslash › should annotate twoslash types default ● twoslash › should annotate twoslash types esnext
Expand output● app dir client cache with parallel routes › prefetch={true} › should re-use the cache for the full page, only for 5 mins |
Merging this PR will not alter performance
Comparing Footnotes
|
aeb6fd2 to
abbe1d9
Compare
Stats from current PR🔴 1 regression
📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📝 Changed Files (8 files)Files with changes:
View diffsapp-route-ex..ntime.dev.jsDiff too large to display app-route-ex..time.prod.jsDiff too large to display app-route-tu..ntime.dev.jsDiff too large to display app-route-tu..time.prod.jsDiff too large to display app-route-tu..ntime.dev.jsDiff too large to display app-route-tu..time.prod.jsDiff too large to display app-route.runtime.dev.jsDiff too large to display app-route.ru..time.prod.jsDiff too large to display 📎 Tarball URL |
78ba0d7 to
74c72dc
Compare
App router handlers are already built with the Turbopack runtime, so they can use server HMR. We also already get subscription events for their chunks. However, unlike app pages which use `__next_app__.require()` for dynamic devModuleCache lookup, route handlers capture userland exports statically in AppRouteRouteModule at construction time. This change makes routes behave a lot like pages, dynamically loading the user's code when requests are made. This way, we can freely invalidate and reload it when changes are made without evicting the entire require cache. This change removes the `isAppPage` restriction from `usesServerHmr`, extending server HMR coverage to all App Router entries (pages and route handlers) built with the Node.js runtime. For route handlers, we also clear the entry chunk from Node.js `require.cache` on each rebuild so the next `requirePage()` call re-executes the entry and obtains fresh module exports from `devModuleCache` (which HMR updates in-place). Test Plan: Added an additional e2e test, `with-dep`
74c72dc to
c011b8e
Compare
App router handlers are already built with the Turbopack runtime, so they can use server HMR. We also already get subscription events for their chunks. However, unlike app pages which use
__next_app__.require()for dynamic devModuleCache lookup, route handlers capture userland exports statically in AppRouteRouteModule at construction time. This change makes routes behave a lot like pages, dynamically loading the user's code when requests are made. This way, we can freely invalidate and reload it when changes are made without evicting the entire require cache.Only
next devuses this lazy evaluation, asnext startcontinues to eagerly import route handlers.This change removes the
isAppPagerestriction fromusesServerHmr, extending server HMR coverage to all App Router entries (pages and route handlers) built with the Node.js runtime.For route handlers, we also clear the entry chunk from Node.js
require.cacheon each rebuild so the nextrequirePage()call re-executes the entry and obtains fresh module exports fromdevModuleCache(which HMR updates in-place).Test Plan: Added an additional e2e test,
with-dep