Skip to content

Commit

Permalink
Update terminal tree view for switchable runtime (#35394)
Browse files Browse the repository at this point in the history
* Update terminal tree view for switchable runtime

* share PageRuntime type

* fix lint
  • Loading branch information
huozhi committed Mar 26, 2022
1 parent 4f6bb5e commit d41f8a5
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 44 deletions.
13 changes: 5 additions & 8 deletions 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'
Expand All @@ -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,
Expand Down Expand Up @@ -99,17 +99,14 @@ type Entrypoints = {
edgeServer: webpack5.EntryObject
}

const cachedPageRuntimeConfig = new Map<
string,
[number, 'nodejs' | 'edge' | undefined]
>()
const cachedPageRuntimeConfig = new Map<string, [number, PageRuntime]>()

// @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<PageRuntime> {
const cached = cachedPageRuntimeConfig.get(pageFilePath)
if (cached) {
return cached[1]
Expand All @@ -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
Expand Down
11 changes: 5 additions & 6 deletions packages/next/build/index.ts
Expand Up @@ -969,7 +969,7 @@ export default async function build(
join(pagesDir, pagePath),
config.experimental.runtime
)
: null
: undefined

if (
!isMiddlewareRoute &&
Expand Down Expand Up @@ -1084,14 +1084,13 @@ export default async function build(
totalSize: allSize,
static: isStatic,
isSsg,
isWebSsr:
hasConcurrentFeatures &&
!isMiddlewareRoute &&
!isReservedPage(page) &&
!isCustomErrorPage(page),
isHybridAmp,
ssgPageRoutes,
initialRevalidateSeconds: false,
runtime:
!isReservedPage(page) && !isCustomErrorPage(page)
? pageRuntime
: undefined,
pageDuration: undefined,
ssgPageDurations: undefined,
})
Expand Down
9 changes: 5 additions & 4 deletions 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'
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -77,11 +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: PageRuntime
}

export async function printTreeView(
Expand Down Expand Up @@ -195,12 +196,12 @@ export async function printTreeView(
? ' '
: item.endsWith('/_middleware')
? 'ƒ'
: pageInfo?.isWebSsr
? 'ℇ'
: pageInfo?.static
? '○'
: pageInfo?.isSsg
? '●'
: pageInfo?.runtime === 'edge'
? 'ℇ'
: 'λ'

usedSymbols.add(symbol)
Expand Down
4 changes: 3 additions & 1 deletion packages/next/server/config-shared.ts
Expand Up @@ -7,6 +7,8 @@ import {
imageConfigDefault,
} from '../shared/lib/image-config'

export type PageRuntime = 'nodejs' | 'edge' | undefined

export type NextConfigComplete = Required<NextConfig> & {
images: Required<ImageConfigComplete>
typescript: Required<TypeScriptConfig>
Expand Down Expand Up @@ -101,7 +103,7 @@ export interface ExperimentalConfig {
craCompat?: boolean
esmExternals?: boolean | 'loose'
isrMemoryCacheSize?: number
runtime?: 'nodejs' | 'edge'
runtime?: Exclude<PageRuntime, undefined>
serverComponents?: boolean
fullySpecified?: boolean
urlImports?: NonNullable<webpack5.Configuration['experiments']>['buildHttp']
Expand Down
@@ -1,34 +1,16 @@
/* eslint-env jest */

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 }) {
Expand All @@ -54,7 +36,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)
})
Expand Down Expand Up @@ -124,4 +107,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)
})
})

0 comments on commit d41f8a5

Please sign in to comment.