From e78c42c91b1d6cf985a58317b53c98c05d383f9f Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 6 May 2022 18:11:11 +0200 Subject: [PATCH 1/5] Fix leftover todo in loader (#36734) --- 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 49910ea9ac0e18b03f34d9b16ea67037e2f11bf7 Mon Sep 17 00:00:00 2001 From: Rich Haines Date: Sat, 7 May 2022 02:24:39 +0200 Subject: [PATCH 2/5] Updated the middleware api docs env section to remove dev and prod (#36739) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …rding due to customer confusion This PR updates the middleware (edge functions) api docs environment section to remove the dev and prod wording due to customer confusion ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `yarn lint` --- docs/api-reference/edge-runtime.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-reference/edge-runtime.md b/docs/api-reference/edge-runtime.md index 3c722513acac..5958f6d2dcd7 100644 --- a/docs/api-reference/edge-runtime.md +++ b/docs/api-reference/edge-runtime.md @@ -26,7 +26,7 @@ The Next.js Edge Runtime is based on standard Web APIs, which is used by [Middle ### Environment -- `process.env`: Holds an object with all environment variables for both production and development in the exact same way as any other page or API in Next.js +- `process.env`: Holds an object with all environment variables for both `next dev` and `next build` in the exact same way as any other page or API in Next.js ### Fetch From 51d962d60f19056eab4f1d6be44310b8f7aeaddd Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 7 May 2022 15:37:14 +0200 Subject: [PATCH 3/5] Leverage pageExtensions for resolving in loader (#36747) ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `yarn lint` --- 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 | 3 +++ 4 files changed, 33 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..8d8e7651f76a 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, @@ -605,6 +607,7 @@ export default class HotReloader { relative(this.viewsDir!, absolutePagePath) ), viewsDir: this.viewsDir!, + pageExtensions: this.config.pageExtensions, }) : request, }) From a84672e63e1ffac0b0e9e04c6fe45628a88949d2 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Sat, 7 May 2022 20:45:40 +0200 Subject: [PATCH 4/5] Use react dom server node api to detect react root is enabled (#36749) x-ref: https://github.com/vercel/next.js/pull/36552#issuecomment-1120128946 x-ref: https://github.com/preactjs/next-plugin-preact/pull/59 `preact/compat` doesn't have `/server.browser` exports, to make it work with latest of next.js: * use `react-dom/server` to detect if it could opt-in streaming rendering by checking react 18 `renderToPipeableStream` API in short time fix. In long term `preact/compat`should support `/server.browser` that same with react 17. * Also filed a PR to `next-plugin-preact` to skip chunk-prepending to pages in edge compiler --- packages/next/bin/next.ts | 3 +-- packages/next/server/next.ts | 4 ++-- packages/next/server/view-render.tsx | 6 ++++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/next/bin/next.ts b/packages/next/bin/next.ts index bb99c8ad6471..ad8597d91797 100755 --- a/packages/next/bin/next.ts +++ b/packages/next/bin/next.ts @@ -43,8 +43,7 @@ const args = arg( ) // Detect if react-dom is enabled streaming rendering mode -const shouldUseReactRoot = !!require('react-dom/server.browser') - .renderToReadableStream +const shouldUseReactRoot = !!require('react-dom/server').renderToPipeableStream // Version is inlined into the file using taskr build pipeline if (args['--version']) { diff --git a/packages/next/server/next.ts b/packages/next/server/next.ts index f2d46252a9a6..8469bf1b8bc1 100644 --- a/packages/next/server/next.ts +++ b/packages/next/server/next.ts @@ -185,8 +185,8 @@ function createServer(options: NextServerOptions): NextServer { // Make sure env of custom server is overridden. // Use dynamic require to make sure it's executed in it's own context. - const ReactDOMServer = require('react-dom/server.browser') - const shouldUseReactRoot = !!ReactDOMServer.renderToReadableStream + const ReactDOMServer = require('react-dom/server') + const shouldUseReactRoot = !!ReactDOMServer.renderToPipeableStream if (shouldUseReactRoot) { ;(process.env as any).__NEXT_REACT_ROOT = 'true' } diff --git a/packages/next/server/view-render.tsx b/packages/next/server/view-render.tsx index 827e1a2a92e0..ad8f2b1f52ff 100644 --- a/packages/next/server/view-render.tsx +++ b/packages/next/server/view-render.tsx @@ -17,12 +17,14 @@ import { continueFromInitialStream, } from './node-web-streams-helper' import { FlushEffectsContext } from '../shared/lib/flush-effects' -// @ts-ignore react-dom/client exists when using React 18 -import ReactDOMServer from 'react-dom/server.browser' import { isDynamicRoute } from '../shared/lib/router/utils' import { tryGetPreviewData } from './api-utils/node' import DefaultRootLayout from '../lib/views-layout' +const ReactDOMServer = process.env.__NEXT_REACT_ROOT + ? require('react-dom/server.browser') + : require('react-dom/server') + export type RenderOptsPartial = { err?: Error | null dev?: boolean From 3fd1168504151495e7b1be81bc48d4097107ed9a Mon Sep 17 00:00:00 2001 From: Steven Tey Date: Sat, 7 May 2022 13:50:31 -0700 Subject: [PATCH 5/5] Fixed typo (#36753) ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `yarn lint` --- docs/basic-features/data-fetching/client-side.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/basic-features/data-fetching/client-side.md b/docs/basic-features/data-fetching/client-side.md index 6b1768a6e901..d738cbd2d742 100644 --- a/docs/basic-features/data-fetching/client-side.md +++ b/docs/basic-features/data-fetching/client-side.md @@ -21,7 +21,7 @@ function Profile() { useEffect(() => { setLoading(true) - fetch('api/profile-data') + fetch('/api/profile-data') .then((res) => res.json()) .then((data) => { setData(data)