From d0e771ef5ee56ac14989166993f8e7992dd36a8b Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 17 Mar 2022 10:50:04 +0100 Subject: [PATCH 1/3] Update terminal tree view for switchable runtime --- packages/next/build/index.ts | 6 ++- packages/next/build/utils.ts | 5 +- .../test/switchable-runtime.test.js | 50 +++++++++++-------- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 3e0584d68b43..bd5ed9fb7ea2 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -969,7 +969,7 @@ export default async function build( join(pagesDir, pagePath), config.experimental.runtime ) - : null + : undefined if ( !isMiddlewareRoute && @@ -1092,6 +1092,10 @@ export default async function build( isHybridAmp, ssgPageRoutes, initialRevalidateSeconds: false, + runtime: + !isReservedPage(page) && !isCustomErrorPage(page) + ? pageRuntime + : undefined, pageDuration: undefined, ssgPageDurations: undefined, }) diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index 618a826307de..dfc597f7cb19 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -82,6 +82,7 @@ export interface PageInfo { initialRevalidateSeconds: number | false pageDuration: number | undefined ssgPageDurations: number[] | undefined + runtime: 'nodejs' | 'edge' | undefined } export async function printTreeView( @@ -195,12 +196,12 @@ export async function printTreeView( ? ' ' : item.endsWith('/_middleware') ? 'ƒ' - : pageInfo?.isWebSsr - ? 'ℇ' : pageInfo?.static ? '○' : pageInfo?.isSsg ? '●' + : pageInfo?.runtime === 'edge' + ? 'ℇ' : 'λ' usedSymbols.add(symbol) diff --git a/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js b/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js index 62ebdcadf426..6756545e7035 100644 --- a/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js +++ b/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js @@ -2,33 +2,20 @@ import { join } from 'path' import { - // File, nextBuild as _nextBuild, nextStart as _nextStart, } from 'next-test-utils' import { findPort, killApp, renderViaHTTP } from 'next-test-utils' - -const nodeArgs = ['-r', join(__dirname, '../../react-18/test/require-hook.js')] +import { nextBuild, nextStart } from './utils' const appDir = join(__dirname, '../switchable-runtime') -// const nextConfig = new File(join(appDir, 'next.config.js')) - -async function nextBuild(dir, options) { - return await _nextBuild(dir, [], { - ...options, - stdout: true, - stderr: true, - nodeArgs, - }) -} -async function nextStart(dir, port) { - return await _nextStart(dir, port, { - stdout: true, - stderr: true, - nodeArgs, - }) +function splitLines(text) { + return text + .split(/\r?\n/g) + .map((str) => str.trim()) + .filter(Boolean) } async function testRoute(appPort, url, { isStatic, isEdge }) { @@ -54,7 +41,8 @@ describe('Without global runtime configuration', () => { beforeAll(async () => { context.appPort = await findPort() - const { stderr } = await nextBuild(context.appDir) + const { stdout, stderr } = await nextBuild(context.appDir) + context.stdout = stdout context.stderr = stderr context.server = await nextStart(context.appDir, context.appPort) }) @@ -124,4 +112,26 @@ describe('Without global runtime configuration', () => { isEdge: true, }) }) + + it('should display correct tree view with page types in terminal', async () => { + const stdoutLines = splitLines(context.stdout).filter((line) => + /^[┌├└/]/.test(line) + ) + const expectedOutputLines = splitLines(` + ┌ λ /404 + ├ ℇ /edge + ├ ℇ /edge-rsc + ├ ○ /node + ├ ○ /node-rsc + ├ ● /node-rsc-ssg + ├ λ /node-rsc-ssr + ├ ● /node-ssg + ├ λ /node-ssr + └ ○ /static + `) + const isMatched = expectedOutputLines.every((line, index) => + stdoutLines[index].startsWith(line) + ) + expect(isMatched).toBe(true) + }) }) From c0a7a2febe2efada7531d3c283a2accc15a26207 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 17 Mar 2022 11:08:26 +0100 Subject: [PATCH 2/3] share PageRuntime type --- packages/next/build/entries.ts | 13 +++++-------- packages/next/build/index.ts | 5 ----- packages/next/build/utils.ts | 6 +++--- packages/next/server/config-shared.ts | 4 +++- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/packages/next/build/entries.ts b/packages/next/build/entries.ts index c6a57df897a0..85e39d25cfc0 100644 --- a/packages/next/build/entries.ts +++ b/packages/next/build/entries.ts @@ -1,3 +1,5 @@ +import type { PageRuntime, NextConfigComplete } from '../server/config-shared' +import type { webpack5 } from 'next/dist/compiled/webpack/webpack' import fs from 'fs' import chalk from 'next/dist/compiled/chalk' import { posix, join } from 'path' @@ -12,11 +14,9 @@ import { MiddlewareLoaderOptions } from './webpack/loaders/next-middleware-loade import { ClientPagesLoaderOptions } from './webpack/loaders/next-client-pages-loader' import { ServerlessLoaderQuery } from './webpack/loaders/next-serverless-loader' import { LoadedEnvFiles } from '@next/env' -import { NextConfigComplete } from '../server/config-shared' import { parse } from '../build/swc' import { isCustomErrorPage, isFlightPage, isReservedPage } from './utils' import { ssrEntries } from './webpack/plugins/middleware-plugin' -import type { webpack5 } from 'next/dist/compiled/webpack/webpack' import { MIDDLEWARE_RUNTIME_WEBPACK, MIDDLEWARE_SSR_RUNTIME_WEBPACK, @@ -99,17 +99,14 @@ type Entrypoints = { edgeServer: webpack5.EntryObject } -const cachedPageRuntimeConfig = new Map< - string, - [number, 'nodejs' | 'edge' | undefined] ->() +const cachedPageRuntimeConfig = new Map() // @TODO: We should limit the maximum concurrency of this function as there // could be thousands of pages existing. export async function getPageRuntime( pageFilePath: string, globalRuntimeFallback?: 'nodejs' | 'edge' -): Promise<'nodejs' | 'edge' | undefined> { +): Promise { const cached = cachedPageRuntimeConfig.get(pageFilePath) if (cached) { return cached[1] @@ -129,7 +126,7 @@ export async function getPageRuntime( // discussion: // https://github.com/vercel/next.js/discussions/34179 let isRuntimeRequired: boolean = false - let pageRuntime: 'nodejs' | 'edge' | undefined = undefined + let pageRuntime: PageRuntime = undefined // Since these configurations should always be static analyzable, we can // skip these cases that "runtime" and "gSP", "gSSP" are not included in the diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index bd5ed9fb7ea2..30a0d4a7fd6b 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -1084,11 +1084,6 @@ export default async function build( totalSize: allSize, static: isStatic, isSsg, - isWebSsr: - hasConcurrentFeatures && - !isMiddlewareRoute && - !isReservedPage(page) && - !isCustomErrorPage(page), isHybridAmp, ssgPageRoutes, initialRevalidateSeconds: false, diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index dfc597f7cb19..58ee1e05ee43 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -1,3 +1,5 @@ +import type { NextConfigComplete, PageRuntime } from '../server/config-shared' + import '../server/node-polyfill-fetch' import chalk from 'next/dist/compiled/chalk' import getGzipSize from 'next/dist/compiled/gzip-size' @@ -37,7 +39,6 @@ import * as Log from './output/log' import { loadComponents } from '../server/load-components' import { trace } from '../trace' import { setHttpAgentOptions } from '../server/config' -import { NextConfigComplete } from '../server/config-shared' import isError from '../lib/is-error' import { recursiveDelete } from '../lib/recursive-delete' import { Sema } from 'next/dist/compiled/async-sema' @@ -77,12 +78,11 @@ export interface PageInfo { totalSize: number static: boolean isSsg: boolean - isWebSsr: boolean ssgPageRoutes: string[] | null initialRevalidateSeconds: number | false pageDuration: number | undefined ssgPageDurations: number[] | undefined - runtime: 'nodejs' | 'edge' | undefined + runtime: PageRuntime } export async function printTreeView( diff --git a/packages/next/server/config-shared.ts b/packages/next/server/config-shared.ts index 0e8c6d5a53cb..2c055abbc952 100644 --- a/packages/next/server/config-shared.ts +++ b/packages/next/server/config-shared.ts @@ -7,6 +7,8 @@ import { imageConfigDefault, } from '../shared/lib/image-config' +export type PageRuntime = 'nodejs' | 'edge' | undefined + export type NextConfigComplete = Required & { images: Required typescript: Required @@ -101,7 +103,7 @@ export interface ExperimentalConfig { craCompat?: boolean esmExternals?: boolean | 'loose' isrMemoryCacheSize?: number - runtime?: 'nodejs' | 'edge' + runtime?: Exclude serverComponents?: boolean fullySpecified?: boolean urlImports?: NonNullable['buildHttp'] From 962238894d7b4d3d5d4038b1ba3ac4eda6baa042 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 17 Mar 2022 13:30:11 +0100 Subject: [PATCH 3/3] fix lint --- .../test/switchable-runtime.test.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js b/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js index 6756545e7035..d5cabd5f9a4e 100644 --- a/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js +++ b/test/integration/react-streaming-and-server-components/test/switchable-runtime.test.js @@ -1,11 +1,6 @@ /* eslint-env jest */ import { join } from 'path' -import { - nextBuild as _nextBuild, - nextStart as _nextStart, -} from 'next-test-utils' - import { findPort, killApp, renderViaHTTP } from 'next-test-utils' import { nextBuild, nextStart } from './utils'