From 5b0a8184e0a1d5bae7c43632020bc674c569411b Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 6 May 2022 17:27:22 +0200 Subject: [PATCH 1/6] Fix leftover todo in loader --- packages/next/build/entries.ts | 5 ----- packages/next/build/index.ts | 3 ++- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/next/build/entries.ts b/packages/next/build/entries.ts index faf8f7224a6e..3adfc98268df 100644 --- a/packages/next/build/entries.ts +++ b/packages/next/build/entries.ts @@ -366,11 +366,6 @@ export async function createEntrypoints(params: CreateEntrypointsParams) { const getEntryHandler = (mappings: Record, isViews: boolean) => async (page: string) => { - // TODO: @timneutkens do not pass layouts to entry here - if (isViews && page.endsWith('/layout')) { - return - } - const bundleFile = normalizePagePath(page) const clientBundlePath = posix.join('pages', bundleFile) const serverBundlePath = posix.join( diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 119a686c0be4..5884545a12ed 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -318,10 +318,11 @@ export default async function build( .traceAsyncFn(() => recursiveReadDir( viewsDir, - new RegExp(`\\.(?:${config.pageExtensions.join('|')})$`) + new RegExp(`page\\.(?:${config.pageExtensions.join('|')})$`) ) ) } + // needed for static exporting since we want to replace with HTML // files From 76435f9dcb32902df79b1c7c349b2fa9e755c0a5 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 7 May 2022 13:15:18 +0200 Subject: [PATCH 2/6] Leverage pageExtensions for resolving in loader --- packages/next/build/entries.ts | 26 +++++++++++++------ packages/next/build/index.ts | 1 + .../build/webpack/loaders/next-view-loader.ts | 26 ++++++++----------- packages/next/server/dev/hot-reloader.ts | 2 ++ 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/packages/next/build/entries.ts b/packages/next/build/entries.ts index 3adfc98268df..c93a660e4dd9 100644 --- a/packages/next/build/entries.ts +++ b/packages/next/build/entries.ts @@ -245,6 +245,7 @@ interface CreateEntrypointsParams { target: 'server' | 'serverless' | 'experimental-serverless-trace' viewsDir?: string viewPaths?: Record + pageExtensions: string[] } export function getEdgeServerEntry(opts: { @@ -285,13 +286,12 @@ export function getEdgeServerEntry(opts: { return `next-middleware-ssr-loader?${stringify(loaderParams)}!` } -export function getViewsEntry(opts: { pagePath: string; viewsDir: string }) { - const loaderParams = { - pagePath: opts.pagePath, - viewsDir: opts.viewsDir, - } - - return `next-view-loader?${stringify(loaderParams)}!` +export function getViewsEntry(opts: { + pagePath: string + viewsDir: string + pageExtensions: string[] +}) { + return `next-view-loader?${stringify(opts)}!` } export function getServerlessEntry(opts: { @@ -358,7 +358,16 @@ export function getClientEntry(opts: { } export async function createEntrypoints(params: CreateEntrypointsParams) { - const { config, pages, pagesDir, isDev, target, viewsDir, viewPaths } = params + const { + config, + pages, + pagesDir, + isDev, + target, + viewsDir, + viewPaths, + pageExtensions, + } = params const edgeServer: webpack5.EntryObject = {} const server: webpack5.EntryObject = {} const client: webpack5.EntryObject = {} @@ -401,6 +410,7 @@ export async function createEntrypoints(params: CreateEntrypointsParams) { server[serverBundlePath] = getViewsEntry({ pagePath: mappings[page], viewsDir, + pageExtensions, }) } else if (isTargetLikeServerless(target)) { if (page !== '/_app' && page !== '/_document') { diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 5884545a12ed..187ac67d8218 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -376,6 +376,7 @@ export default async function build( target, viewsDir, viewPaths: mappedViewPaths, + pageExtensions: config.pageExtensions, }) ) diff --git a/packages/next/build/webpack/loaders/next-view-loader.ts b/packages/next/build/webpack/loaders/next-view-loader.ts index 6085337c49b9..1f4ca331584f 100644 --- a/packages/next/build/webpack/loaders/next-view-loader.ts +++ b/packages/next/build/webpack/loaders/next-view-loader.ts @@ -37,26 +37,22 @@ async function resolveLayoutPathsByPage({ return layoutPaths } -const extensions = [ - ...NODE_RESOLVE_OPTIONS.extensions, - ...NODE_RESOLVE_OPTIONS.extensions.map((ext) => `.server${ext}`), - ...NODE_RESOLVE_OPTIONS.extensions.map((ext) => `.client${ext}`), -] -const resolveOptions: any = { - ...NODE_RESOLVE_OPTIONS, - extensions, -} - const nextViewLoader: webpack.LoaderDefinitionFunction<{ pagePath: string viewsDir: string + pageExtensions: string[] }> = async function nextViewLoader() { - const loaderOptions = this.getOptions() || {} + const { viewsDir, pagePath, pageExtensions } = this.getOptions() || {} + + const extensions = pageExtensions.map((extension) => `.${extension}`) + const resolveOptions: any = { + ...NODE_RESOLVE_OPTIONS, + extensions, + } const resolve = this.getResolve(resolveOptions) - const viewsDir = loaderOptions.viewsDir const layoutPaths = await resolveLayoutPathsByPage({ - pagePath: loaderOptions.pagePath, + pagePath: pagePath, resolve: async (pathname) => { try { return await resolve(this.rootContext, pathname) @@ -87,11 +83,11 @@ const nextViewLoader: webpack.LoaderDefinitionFunction<{ // Add page itself to the list of components componentsCode.push( - `'${pathToUrlPath(loaderOptions.pagePath).replace( + `'${pathToUrlPath(pagePath).replace( new RegExp(`/page\\.+(${extensions.join('|')})$`), '' // use require so that we can bust the require cache - )}': () => require('${loaderOptions.pagePath}')` + )}': () => require('${pagePath}')` ) const result = ` diff --git a/packages/next/server/dev/hot-reloader.ts b/packages/next/server/dev/hot-reloader.ts index 2fa7844e8f09..f011da65314d 100644 --- a/packages/next/server/dev/hot-reloader.ts +++ b/packages/next/server/dev/hot-reloader.ts @@ -421,6 +421,7 @@ export default class HotReloader { pagesDir: this.pagesDir, previewMode: this.previewProps, target: 'server', + pageExtensions: this.config.pageExtensions, }) ) @@ -488,6 +489,7 @@ export default class HotReloader { pagesDir: this.pagesDir, previewMode: this.previewProps, target: 'server', + pageExtensions: this.config.pageExtensions, }) ).client, hasReactRoot: this.hasReactRoot, From 24a717d4fabd8b525f874036bf7f1a0f7b68d58f Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 7 May 2022 13:27:49 +0200 Subject: [PATCH 3/6] Fix dev --- packages/next/server/dev/hot-reloader.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/next/server/dev/hot-reloader.ts b/packages/next/server/dev/hot-reloader.ts index f011da65314d..8d8e7651f76a 100644 --- a/packages/next/server/dev/hot-reloader.ts +++ b/packages/next/server/dev/hot-reloader.ts @@ -607,6 +607,7 @@ export default class HotReloader { relative(this.viewsDir!, absolutePagePath) ), viewsDir: this.viewsDir!, + pageExtensions: this.config.pageExtensions, }) : request, }) From 52e56fa34284a6b5b54fc4286f7967f436c19f6a Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sun, 8 May 2022 17:10:29 +0200 Subject: [PATCH 4/6] Add flight render starting point --- packages/next/server/view-render.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/next/server/view-render.tsx b/packages/next/server/view-render.tsx index 827e1a2a92e0..c55bb1e58b10 100644 --- a/packages/next/server/view-render.tsx +++ b/packages/next/server/view-render.tsx @@ -217,13 +217,25 @@ export async function renderToHTML( const hasConcurrentFeatures = !!runtime const pageIsDynamic = isDynamicRoute(pathname) const components = Object.keys(ComponentMod.components) + .filter((path) => { + const { __flight__, __flight_router_path__: routerPath } = query + // Rendering part of the page is only allowed for flight data + if (__flight__ !== undefined && routerPath) { + // TODO: check the actual path + const pathLength = path.length + return pathLength >= routerPath.length + } + return true + }) .sort() - .map((key) => { - const mod = ComponentMod.components[key]() + .map((path) => { + const mod = ComponentMod.components[path]() mod.Component = mod.default || mod return mod }) + console.log({ components }) + // Reads of this are cached on the `req` object, so this should resolve // instantly. There's no need to pass this data down from a previous // invoke, where we'd have to consider server & serverless. From b4360c3586076c9bd57bf6ebe87364f74501598e Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sun, 8 May 2022 17:34:55 +0200 Subject: [PATCH 5/6] Update packages/next/server/view-render.tsx Co-authored-by: JJ Kasper --- packages/next/server/view-render.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/next/server/view-render.tsx b/packages/next/server/view-render.tsx index 9afed28ba8d1..c3d5ee7094c1 100644 --- a/packages/next/server/view-render.tsx +++ b/packages/next/server/view-render.tsx @@ -236,7 +236,6 @@ export async function renderToHTML( return mod }) - console.log({ components }) // Reads of this are cached on the `req` object, so this should resolve // instantly. There's no need to pass this data down from a previous From 515638dfd4cd9ee5f2ac433cafb6c366909d1122 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sun, 8 May 2022 18:18:03 +0200 Subject: [PATCH 6/6] Run prettier --- packages/next/server/view-render.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/next/server/view-render.tsx b/packages/next/server/view-render.tsx index c3d5ee7094c1..fbbac3d3151e 100644 --- a/packages/next/server/view-render.tsx +++ b/packages/next/server/view-render.tsx @@ -236,7 +236,6 @@ export async function renderToHTML( return mod }) - // Reads of this are cached on the `req` object, so this should resolve // instantly. There's no need to pass this data down from a previous // invoke, where we'd have to consider server & serverless.