From fb39a71278208876b8277759e06bade69c5b6f90 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 23 Jun 2023 17:35:02 +0200 Subject: [PATCH 1/7] Add critical next config value to github info --- packages/next/src/cli/next-info.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/next/src/cli/next-info.ts b/packages/next/src/cli/next-info.ts index f3e2b3a3eb898..72e4ed236040f 100755 --- a/packages/next/src/cli/next-info.ts +++ b/packages/next/src/cli/next-info.ts @@ -1,4 +1,6 @@ #!/usr/bin/env node +import type { NextConfig } from 'next' + import os from 'os' import childProcess from 'child_process' @@ -19,6 +21,19 @@ function getPackageVersion(packageName: string) { } } +function getNextConfig() { + let config: NextConfig = {} + try { + config = require(`${process.cwd()}/next.config.js`) + } catch { + return {} + } + + return { + output: config.output || 'N/A', + } +} + function getBinaryVersion(binaryName: string) { try { return childProcess @@ -67,6 +82,7 @@ const nextInfo: CliCommand = async (argv) => { } const installedRelease = getPackageVersion('next') + const nextConfig = getNextConfig() console.log(` Operating System: @@ -84,6 +100,9 @@ const nextInfo: CliCommand = async (argv) => { react: ${getPackageVersion('react')} react-dom: ${getPackageVersion('react-dom')} typescript: ${getPackageVersion('typescript')} + Next Config: + output: ${nextConfig.output} + `) try { From 10c29da6fd4dd11c9ccc9b5d4c2211ec3a17065e Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 23 Jun 2023 17:37:59 +0200 Subject: [PATCH 2/7] tweak --- packages/next/src/cli/next-info.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/src/cli/next-info.ts b/packages/next/src/cli/next-info.ts index 72e4ed236040f..cffd2837a2cb9 100755 --- a/packages/next/src/cli/next-info.ts +++ b/packages/next/src/cli/next-info.ts @@ -94,13 +94,13 @@ const nextInfo: CliCommand = async (argv) => { npm: ${getBinaryVersion('npm')} Yarn: ${getBinaryVersion('yarn')} pnpm: ${getBinaryVersion('pnpm')} - Relevant packages: + Relevant Packages: next: ${installedRelease} eslint-config-next: ${getPackageVersion('eslint-config-next')} react: ${getPackageVersion('react')} react-dom: ${getPackageVersion('react-dom')} typescript: ${getPackageVersion('typescript')} - Next Config: + Next.js Config: output: ${nextConfig.output} `) From 219618c3b596e4774418f8180db7dd932d0e0fb9 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 23 Jun 2023 17:44:48 +0200 Subject: [PATCH 3/7] rm type --- packages/next/src/cli/next-info.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/src/cli/next-info.ts b/packages/next/src/cli/next-info.ts index cffd2837a2cb9..fee0de02dbcd0 100755 --- a/packages/next/src/cli/next-info.ts +++ b/packages/next/src/cli/next-info.ts @@ -1,5 +1,4 @@ #!/usr/bin/env node -import type { NextConfig } from 'next' import os from 'os' import childProcess from 'child_process' @@ -22,7 +21,8 @@ function getPackageVersion(packageName: string) { } function getNextConfig() { - let config: NextConfig = {} + // Use any here to avoid nextjs types dependency + let config: any = {} try { config = require(`${process.cwd()}/next.config.js`) } catch { From 761479ee8dd89e50ef94bf845c0cecac6317f01f Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 23 Jun 2023 18:47:37 +0200 Subject: [PATCH 4/7] update test --- packages/next/src/cli/next-info.ts | 6 ++---- test/integration/cli/test/index.test.js | 5 ++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/next/src/cli/next-info.ts b/packages/next/src/cli/next-info.ts index fee0de02dbcd0..c84039f3596ea 100755 --- a/packages/next/src/cli/next-info.ts +++ b/packages/next/src/cli/next-info.ts @@ -25,12 +25,10 @@ function getNextConfig() { let config: any = {} try { config = require(`${process.cwd()}/next.config.js`) - } catch { - return {} - } + } catch {} return { - output: config.output || 'N/A', + output: config.output ?? 'N/A', } } diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index 61ded2719cceb..44d539cfcdc1a 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -683,11 +683,14 @@ describe('CLI Usage', () => { npm: .* Yarn: .* pnpm: .* - Relevant packages: + Relevant Packages: next: .* eslint-config-next: .* react: .* react-dom: .* + typescript: .* + Next.js Config: + output: .* `) ) }) From 4fb456b4f7ed5d108052391aaf9669cfe9751f07 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 23 Jun 2023 23:01:03 +0200 Subject: [PATCH 5/7] update test --- packages/next/src/cli/next-info.ts | 7 +- .../cli/{ => basic}/pages/index.js | 0 test/integration/cli/test/index.test.js | 158 +++++++++++------- .../standalone-mode/basic/app/page.js | 3 - 4 files changed, 103 insertions(+), 65 deletions(-) rename test/integration/cli/{ => basic}/pages/index.js (100%) delete mode 100644 test/production/standalone-mode/basic/app/page.js diff --git a/packages/next/src/cli/next-info.ts b/packages/next/src/cli/next-info.ts index c84039f3596ea..14dbba487e5ae 100755 --- a/packages/next/src/cli/next-info.ts +++ b/packages/next/src/cli/next-info.ts @@ -20,11 +20,12 @@ function getPackageVersion(packageName: string) { } } -function getNextConfig() { +async function getNextConfig() { // Use any here to avoid nextjs types dependency let config: any = {} try { - config = require(`${process.cwd()}/next.config.js`) + const nextConfigMod = await import(`${process.cwd()}/next.config`) + config = nextConfigMod.default || nextConfigMod } catch {} return { @@ -80,7 +81,7 @@ const nextInfo: CliCommand = async (argv) => { } const installedRelease = getPackageVersion('next') - const nextConfig = getNextConfig() + const nextConfig = await getNextConfig() console.log(` Operating System: diff --git a/test/integration/cli/pages/index.js b/test/integration/cli/basic/pages/index.js similarity index 100% rename from test/integration/cli/pages/index.js rename to test/integration/cli/basic/pages/index.js diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index 44d539cfcdc1a..e4bd0b549398b 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -15,7 +15,7 @@ import pkg from 'next/package' import http from 'http' import stripAnsi from 'strip-ansi' -const dir = join(__dirname, '..') +const dirBasic = join(__dirname, '../basic') const dirDuplicateSass = join(__dirname, '../duplicate-sass') const testExitSignal = async ( @@ -52,8 +52,8 @@ describe('CLI Usage', () => { describe('start', () => { test('should exit when SIGINT is signalled', async () => { require('console').log('before build') - await fs.remove(join(dir, '.next')) - await nextBuild(dir, undefined, { + await fs.remove(join(dirBasic, '.next')) + await nextBuild(dirBasic, undefined, { onStdout(msg) { console.log(msg) }, @@ -66,13 +66,13 @@ describe('CLI Usage', () => { const port = await findPort() await testExitSignal( 'SIGINT', - ['start', dir, '-p', port], + ['start', dirBasic, '-p', port], /started server on/ ) }) test('should exit when SIGTERM is signalled', async () => { - await fs.remove(join(dir, '.next')) - await nextBuild(dir, undefined, { + await fs.remove(join(dirBasic, '.next')) + await nextBuild(dirBasic, undefined, { onStdout(msg) { console.log(msg) }, @@ -83,7 +83,7 @@ describe('CLI Usage', () => { const port = await findPort() await testExitSignal( 'SIGTERM', - ['start', dir, '-p', port], + ['start', dirBasic, '-p', port], /started server on/ ) }) @@ -299,11 +299,11 @@ describe('CLI Usage', () => { }) test('should exit when SIGINT is signalled', async () => { - await testExitSignal('SIGINT', ['build', dir]) + await testExitSignal('SIGINT', ['build', dirBasic]) }) test('should exit when SIGTERM is signalled', async () => { - await testExitSignal('SIGTERM', ['build', dir]) + await testExitSignal('SIGTERM', ['build', dirBasic]) }) test('invalid directory', async () => { @@ -334,11 +334,15 @@ describe('CLI Usage', () => { test('custom directory', async () => { const port = await findPort() let output = '' - const app = await runNextCommandDev([dir, '--port', port], undefined, { - onStdout(msg) { - output += stripAnsi(msg) - }, - }) + const app = await runNextCommandDev( + [dirBasic, '--port', port], + undefined, + { + onStdout(msg) { + output += stripAnsi(msg) + }, + } + ) try { await check(() => output, /started server/i) } finally { @@ -349,11 +353,15 @@ describe('CLI Usage', () => { test('--port', async () => { const port = await findPort() let output = '' - const app = await runNextCommandDev([dir, '--port', port], undefined, { - onStdout(msg) { - output += stripAnsi(msg) - }, - }) + const app = await runNextCommandDev( + [dirBasic, '--port', port], + undefined, + { + onStdout(msg) { + output += stripAnsi(msg) + }, + } + ) try { await check(() => output, new RegExp(`on 0.0.0.0:${port}`)) await check(() => output, new RegExp(`http://localhost:${port}`)) @@ -365,11 +373,15 @@ describe('CLI Usage', () => { test('--port 0', async () => { const port = await findPort() let output = '' - const app = await runNextCommandDev([dir, '--port', port], undefined, { - onStdout(msg) { - output += stripAnsi(msg) - }, - }) + const app = await runNextCommandDev( + [dirBasic, '--port', port], + undefined, + { + onStdout(msg) { + output += stripAnsi(msg) + }, + } + ) try { await check(() => output, new RegExp(`on 0.0.0.0:${port}`)) await check(() => output, new RegExp(`http://localhost:${port}`)) @@ -387,7 +399,7 @@ describe('CLI Usage', () => { test('PORT=0', async () => { let output = '' - const app = await runNextCommandDev([dir], undefined, { + const app = await runNextCommandDev([dirBasic], undefined, { env: { PORT: 0, }, @@ -411,12 +423,16 @@ describe('CLI Usage', () => { test("NODE_OPTIONS='--inspect'", async () => { const port = await findPort() let output = '' - const app = await runNextCommandDev([dir, '--port', port], undefined, { - onStdout(msg) { - output += stripAnsi(msg) - }, - env: { NODE_OPTIONS: '--inspect' }, - }) + const app = await runNextCommandDev( + [dirBasic, '--port', port], + undefined, + { + onStdout(msg) { + output += stripAnsi(msg) + }, + env: { NODE_OPTIONS: '--inspect' }, + } + ) try { await check(() => output, new RegExp(`on 0.0.0.0:${port}`)) await check(() => output, new RegExp(`http://localhost:${port}`)) @@ -428,7 +444,7 @@ describe('CLI Usage', () => { test('-p', async () => { const port = await findPort() let output = '' - const app = await runNextCommandDev([dir, '-p', port], undefined, { + const app = await runNextCommandDev([dirBasic, '-p', port], undefined, { onStdout(msg) { output += stripAnsi(msg) }, @@ -457,7 +473,7 @@ describe('CLI Usage', () => { }) let stdout = '', stderr = '' - await launchApp(dir, port, { + await launchApp(dirBasic, port, { stdout: true, stderr: true, onStdout(msg) { @@ -479,7 +495,7 @@ describe('CLI Usage', () => { const port = await findPort() let output = '' const app = await runNextCommandDev( - [dir, '--hostname', '0.0.0.0', '--port', port], + [dirBasic, '--hostname', '0.0.0.0', '--port', port], undefined, { onStdout(msg) { @@ -499,7 +515,7 @@ describe('CLI Usage', () => { const port = await findPort() let output = '' const app = await runNextCommandDev( - [dir, '-H', '0.0.0.0', '--port', port], + [dirBasic, '-H', '0.0.0.0', '--port', port], undefined, { onStdout(msg) { @@ -519,7 +535,7 @@ describe('CLI Usage', () => { const port = await findPort() let output = '' const app = await runNextCommandDev( - [dir, '--hostname', '::', '--port', port], + [dirBasic, '--hostname', '::', '--port', port], undefined, { onStdout(msg) { @@ -552,7 +568,7 @@ describe('CLI Usage', () => { const port = await findPort() await testExitSignal( 'SIGINT', - ['dev', dir, '-p', port], + ['dev', dirBasic, '-p', port], /started server on/ ) }) @@ -560,7 +576,7 @@ describe('CLI Usage', () => { const port = await findPort() await testExitSignal( 'SIGTERM', - ['dev', dir, '-p', port], + ['dev', dirBasic, '-p', port], /started server on/ ) }) @@ -647,6 +663,30 @@ describe('CLI Usage', () => { }) describe('info', () => { + function matchInfoOutput(stdout) { + expect(stdout).toMatch( + new RegExp(` + Operating System: + Platform: .* + Arch: .* + Version: .* + Binaries: + Node: .* + npm: .* + Yarn: .* + pnpm: .* + Relevant Packages: + next: .* + eslint-config-next: .* + react: .* + react-dom: .* + typescript: .* + Next.js Config: + output: .* +`) + ) + } + test('--help', async () => { const help = await runNextCommand(['info', '--help'], { stdout: true, @@ -670,29 +710,29 @@ describe('CLI Usage', () => { stdout: true, stderr: true, }) + expect((info.stderr || '').toLowerCase()).not.toContain('error') + matchInfoOutput(info.stdout) + }) - expect(info.stdout).toMatch( - new RegExp(` - Operating System: - Platform: .* - Arch: .* - Version: .* - Binaries: - Node: .* - npm: .* - Yarn: .* - pnpm: .* - Relevant Packages: - next: .* - eslint-config-next: .* - react: .* - react-dom: .* - typescript: .* - Next.js Config: - output: .* -`) - ) + test('should print output with next.config.mjs', async () => { + let info = { stdout: '', stderr: '' } + + try { + await fs.writeFile( + join(dirBasic, 'next.config.mjs'), + `export default { output: 'standalone' }` + ) + info = await runNextCommand(['info'], { + stdout: true, + stderr: true, + }) + } finally { + await fs.remove(join(dirBasic, 'next.config.mjs')) + } + + expect((info.stderr || '').toLowerCase()).not.toContain('error') + matchInfoOutput(info.stdout) }) }) }) diff --git a/test/production/standalone-mode/basic/app/page.js b/test/production/standalone-mode/basic/app/page.js deleted file mode 100644 index 41c1c6b78dffe..0000000000000 --- a/test/production/standalone-mode/basic/app/page.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function page() { - return 'page' -} From 499ab27d7ccccdbf677430500a42695daaaf25ba Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 23 Jun 2023 23:37:10 +0200 Subject: [PATCH 6/7] reuse log config --- packages/next/src/cli/next-info.ts | 11 +++++------ packages/next/src/shared/lib/constants.ts | 1 + test/integration/cli/test/index.test.js | 14 +++++++++++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/next/src/cli/next-info.ts b/packages/next/src/cli/next-info.ts index 14dbba487e5ae..5c86fcd3947ab 100755 --- a/packages/next/src/cli/next-info.ts +++ b/packages/next/src/cli/next-info.ts @@ -11,6 +11,10 @@ const { fetch } = require('next/dist/compiled/undici') as { import { printAndExit } from '../server/lib/utils' import { CliCommand } from '../lib/commands' import isError from '../lib/is-error' +import { PHASE_INFO } from '../shared/lib/constants' +import loadConfig from '../server/config' + +const dir = process.cwd() function getPackageVersion(packageName: string) { try { @@ -21,12 +25,7 @@ function getPackageVersion(packageName: string) { } async function getNextConfig() { - // Use any here to avoid nextjs types dependency - let config: any = {} - try { - const nextConfigMod = await import(`${process.cwd()}/next.config`) - config = nextConfigMod.default || nextConfigMod - } catch {} + const config = await loadConfig(PHASE_INFO, dir, undefined, undefined, true) return { output: config.output ?? 'N/A', diff --git a/packages/next/src/shared/lib/constants.ts b/packages/next/src/shared/lib/constants.ts index fa1fcd0e74507..06eda8a137292 100644 --- a/packages/next/src/shared/lib/constants.ts +++ b/packages/next/src/shared/lib/constants.ts @@ -25,6 +25,7 @@ export const PHASE_PRODUCTION_BUILD = 'phase-production-build' export const PHASE_PRODUCTION_SERVER = 'phase-production-server' export const PHASE_DEVELOPMENT_SERVER = 'phase-development-server' export const PHASE_TEST = 'phase-test' +export const PHASE_INFO = 'phase-info' export const PAGES_MANIFEST = 'pages-manifest.json' export const APP_PATHS_MANIFEST = 'app-paths-manifest.json' export const APP_PATH_ROUTES_MANIFEST = 'app-path-routes-manifest.json' diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index e4bd0b549398b..66aba3464cb90 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -663,7 +663,7 @@ describe('CLI Usage', () => { }) describe('info', () => { - function matchInfoOutput(stdout) { + function matchInfoOutput(stdout, { nextConfigOutput = '.*' } = {}) { expect(stdout).toMatch( new RegExp(` Operating System: @@ -682,7 +682,7 @@ describe('CLI Usage', () => { react-dom: .* typescript: .* Next.js Config: - output: .* + output: ${nextConfigOutput} `) ) } @@ -723,16 +723,24 @@ describe('CLI Usage', () => { join(dirBasic, 'next.config.mjs'), `export default { output: 'standalone' }` ) + await fs.writeFile( + join(dirBasic, 'package.json'), + JSON.stringify({ + type: 'module', + }) + ) info = await runNextCommand(['info'], { + cwd: dirBasic, stdout: true, stderr: true, }) } finally { await fs.remove(join(dirBasic, 'next.config.mjs')) + await fs.remove(join(dirBasic, 'package.json')) } expect((info.stderr || '').toLowerCase()).not.toContain('error') - matchInfoOutput(info.stdout) + matchInfoOutput(info.stdout, { nextConfigOutput: 'standalone' }) }) }) }) From 80f611c64e57a5f3f44b41bda8cd37f04534a98f Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Sat, 24 Jun 2023 00:27:00 +0200 Subject: [PATCH 7/7] revert --- test/production/standalone-mode/basic/app/page.js | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 test/production/standalone-mode/basic/app/page.js diff --git a/test/production/standalone-mode/basic/app/page.js b/test/production/standalone-mode/basic/app/page.js new file mode 100644 index 0000000000000..41c1c6b78dffe --- /dev/null +++ b/test/production/standalone-mode/basic/app/page.js @@ -0,0 +1,3 @@ +export default function page() { + return 'page' +}