Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix duplicated error logging when start server #55328

Merged
merged 16 commits into from
Sep 13, 2023
8 changes: 1 addition & 7 deletions packages/next-swc/crates/next-core/js/src/entry/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,7 @@ async function getResolveRoute(
dir: string,
serverInfo: ServerInfo
): Promise<Resolver> {
const nextConfig = await loadConfig(
PHASE_DEVELOPMENT_SERVER,
process.cwd(),
undefined,
undefined,
true
)
const nextConfig = await loadConfig(PHASE_DEVELOPMENT_SERVER, process.cwd())
const middlewareCfg = {
files: middlewareChunkGroup.filter((f) => /\.[mc]?js$/.test(f)),
matcher: middlewareConfig.matcher,
Expand Down
5 changes: 4 additions & 1 deletion packages/next/src/bin/next.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ async function main() {
// un-necessarily
const config = await loadConfig(
command === 'dev' ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER,
dir
dir,
{
silent: false,
}
)
let dirsResult: ReturnType<typeof findPagesDir> | undefined = undefined

Expand Down
7 changes: 6 additions & 1 deletion packages/next/src/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,12 @@ export default async function build(

const config: NextConfigComplete = await nextBuildSpan
.traceChild('load-next-config')
.traceAsyncFn(() => loadConfig(PHASE_PRODUCTION_BUILD, dir))
.traceAsyncFn(() =>
loadConfig(PHASE_PRODUCTION_BUILD, dir, {
// Log for next.config loading process
silent: false,
})
)
NextBuildContext.config = config

let configOutDir = 'out'
Expand Down
9 changes: 6 additions & 3 deletions packages/next/src/build/output/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ export function watchCompilers(
if (
!status.loading &&
!buildStore.getState().server.loading &&
!buildStore.getState().edgeServer.loading
!buildStore.getState().edgeServer.loading &&
status.totalModulesCount > 0
) {
buildStore.setState({
client: status,
Expand All @@ -281,7 +282,8 @@ export function watchCompilers(
if (
!status.loading &&
!buildStore.getState().client.loading &&
!buildStore.getState().edgeServer.loading
!buildStore.getState().edgeServer.loading &&
status.totalModulesCount > 0
) {
buildStore.setState({
server: status,
Expand All @@ -297,7 +299,8 @@ export function watchCompilers(
if (
!status.loading &&
!buildStore.getState().client.loading &&
!buildStore.getState().server.loading
!buildStore.getState().server.loading &&
status.totalModulesCount > 0
) {
buildStore.setState({
edgeServer: status,
Expand Down
7 changes: 5 additions & 2 deletions packages/next/src/build/output/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,15 @@ store.subscribe((state) => {

if (trigger === 'initial') {
trigger = ''
} else if (trigger) {
} else {
if (loadingLogTimer) {
clearTimeout(loadingLogTimer)
loadingLogTimer = null
}
Log.event(`Compiled ${trigger}${timeMessage}${modulesMessage}`)
Log.event(
`Compiled${trigger ? ' ' + trigger : ''}${timeMessage}${modulesMessage}`
)
trigger = ''
}

// Ensure traces are flushed after each compile in development mode
Expand Down
5 changes: 1 addition & 4 deletions packages/next/src/build/webpack-build/impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,7 @@ export async function workerMain(workerData: {
/// load the config because it's not serializable
NextBuildContext.config = await loadConfig(
PHASE_PRODUCTION_BUILD,
NextBuildContext.dir!,
undefined,
undefined,
true
NextBuildContext.dir!
)
NextBuildContext.nextBuildSpan = trace('next-build')

Expand Down
23 changes: 5 additions & 18 deletions packages/next/src/cli/next-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,7 @@ const handleSessionStop = async () => {
const { eventCliSessionStopped } =
require('../telemetry/events/session-stopped') as typeof import('../telemetry/events/session-stopped')

config =
config ||
(await loadConfig(
PHASE_DEVELOPMENT_SERVER,
dir,
undefined,
undefined,
true
))
config = config || (await loadConfig(PHASE_DEVELOPMENT_SERVER, dir))

let telemetry =
(traceGlobals.get('telemetry') as InstanceType<
Expand Down Expand Up @@ -188,21 +180,16 @@ const nextDev: CliCommand = async (args) => {
const { loadedEnvFiles } = loadEnvConfig(dir, true, console, false)

let expFeatureInfo: string[] = []
config = await loadConfig(
PHASE_DEVELOPMENT_SERVER,
dir,
undefined,
undefined,
undefined,
(userConfig) => {
config = await loadConfig(PHASE_DEVELOPMENT_SERVER, dir, {
onLoadUserConfig(userConfig) {
const userNextConfigExperimental = getEnabledExperimentalFeatures(
userConfig.experimental
)
expFeatureInfo = userNextConfigExperimental.sort(
(a, b) => a.length - b.length
)
}
)
},
})

let envInfo: string[] = []
if (loadedEnvFiles.length > 0) {
Expand Down
2 changes: 1 addition & 1 deletion packages/next/src/cli/next-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function getPackageVersion(packageName: string) {
}

async function getNextConfig() {
const config = await loadConfig(PHASE_INFO, dir, undefined, undefined, true)
const config = await loadConfig(PHASE_INFO, dir)

return {
output: config.output ?? 'N/A',
Expand Down
4 changes: 3 additions & 1 deletion packages/next/src/lib/turbopack-warning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ export async function validateTurboNextConfig({

try {
rawNextConfig = interopDefault(
await loadConfig(PHASE_DEVELOPMENT_SERVER, dir, undefined, true)
await loadConfig(PHASE_DEVELOPMENT_SERVER, dir, {
rawConfig: true,
})
) as NextConfig

if (typeof rawNextConfig === 'function') {
Expand Down
33 changes: 20 additions & 13 deletions packages/next/src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { existsSync } from 'fs'
import { basename, extname, join, relative, isAbsolute, resolve } from 'path'
import { pathToFileURL } from 'url'
import findUp from 'next/dist/compiled/find-up'
import chalk from '../lib/chalk'
import * as Log from '../build/output/log'
import { CONFIG_FILES, PHASE_DEVELOPMENT_SERVER } from '../shared/lib/constants'
import {
Expand All @@ -28,7 +27,7 @@ export function warnOptionHasBeenMovedOutOfExperimental(
oldKey: string,
newKey: string,
configFileName: string,
silent = false
silent: boolean
) {
if (config.experimental && oldKey in config.experimental) {
if (!silent) {
Expand All @@ -55,14 +54,15 @@ export function warnOptionHasBeenMovedOutOfExperimental(
function assignDefaults(
dir: string,
userConfig: { [key: string]: any },
silent = false
silent: boolean
) {
const configFileName = userConfig.configFileName
if (!silent && typeof userConfig.exportTrailingSlash !== 'undefined') {
console.warn(
chalk.yellow.bold('Warning: ') +
if (typeof userConfig.exportTrailingSlash !== 'undefined') {
if (!silent) {
Log.warn(
`The "exportTrailingSlash" option has been renamed to "trailingSlash". Please update your ${configFileName}.`
)
)
}
if (typeof userConfig.trailingSlash === 'undefined') {
userConfig.trailingSlash = userConfig.exportTrailingSlash
}
Expand Down Expand Up @@ -701,10 +701,17 @@ function assignDefaults(
export default async function loadConfig(
phase: string,
dir: string,
customConfig?: object | null,
rawConfig?: boolean,
silent?: boolean,
onLoadUserConfig?: (conf: NextConfig) => void
{
customConfig,
rawConfig,
silent = true,
onLoadUserConfig,
}: {
customConfig?: object | null
rawConfig?: boolean
silent?: boolean
onLoadUserConfig?: (conf: NextConfig) => void
} = {}
): Promise<NextConfigComplete> {
if (!process.env.__NEXT_PRIVATE_RENDER_WORKER) {
try {
Expand Down Expand Up @@ -802,7 +809,7 @@ export default async function loadConfig(

const validateResult = validateConfig(userConfig)

if (!silent && validateResult.errors) {
if (validateResult.errors) {
// Only load @segment/ajv-human-errors when invalid config is detected
const { AggregateAjvError } =
require('next/dist/compiled/@segment/ajv-human-errors') as typeof import('next/dist/compiled/@segment/ajv-human-errors')
Expand All @@ -811,7 +818,7 @@ export default async function loadConfig(
})

let shouldExit = false
let messages = [`Invalid ${configFileName} options detected: `]
const messages = [`Invalid ${configFileName} options detected: `]

for (const error of aggregatedAjvErrors) {
messages.push(` ${error.message}`)
Expand Down
7 changes: 4 additions & 3 deletions packages/next/src/server/next.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,10 @@ export class NextServer {
loadConfig(
this.options.dev ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER,
resolve(this.options.dir || '.'),
this.options.conf,
undefined,
!!this.options._renderWorker
{
customConfig: this.options.conf,
silent: !!this.options._renderWorker,
}
)
)
}
Expand Down
8 changes: 1 addition & 7 deletions packages/next/src/telemetry/detached-flush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,7 @@ import { PHASE_DEVELOPMENT_SERVER } from '../shared/lib/constants'
}
dir = getProjectDir(dir)

const config = await loadConfig(
PHASE_DEVELOPMENT_SERVER,
dir,
undefined,
undefined,
true
)
const config = await loadConfig(PHASE_DEVELOPMENT_SERVER, dir)
const distDir = path.join(dir, config.distDir || '.next')
const eventsPath = path.join(distDir, '_events.json')

Expand Down
1 change: 0 additions & 1 deletion test/development/basic/hmr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,6 @@ describe.each([[''], ['/docs']])(
...compileTimeStr.match(/Compiled.*? in ([\d.]{1,})\s?(?:s|ms)/i),
]
const [, compileTime, timeUnit] = matches
console.log('compileTime, timeUnit', compileTime, timeUnit)

let compileTimeMs = parseFloat(compileTime[1])
if (timeUnit === 's') {
Expand Down
58 changes: 58 additions & 0 deletions test/e2e/config-schema-check/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import stripAnsi from 'strip-ansi'
import { createNextDescribe } from 'e2e-utils'

createNextDescribe(
'next.config.js schema validating - defaultConfig',
{
files: {
'pages/index.js': `
export default function Page() {
return <p>hello world</p>
}
`,
'next.config.js': `
module.exports = (phase, { defaultConfig }) => {
return defaultConfig
}
`,
},
},
({ next }) => {
it('should validate against defaultConfig', async () => {
const output = stripAnsi(next.cliOutput)

expect(output).not.toContain('Invalid next.config.js options detected')
})
}
)

createNextDescribe(
'next.config.js schema validating - invalid config',
{
files: {
'pages/index.js': `
export default function Page() {
return <p>hello world</p>
}
`,
'next.config.js': `
module.exports = {
experimental: {
badKey: 'badValue'
}
}
`,
},
},
({ next }) => {
it('should warn the invalid next config', async () => {
await next.fetch('/')
const output = stripAnsi(next.cliOutput)
const warningTimes = /badKey/.exec(output)?.length
ijjk marked this conversation as resolved.
Show resolved Hide resolved

expect(output).toContain('Invalid next.config.js options detected')
expect(output).toContain('badKey')
expect(warningTimes).toBe(1)
})
}
)
3 changes: 0 additions & 3 deletions test/integration/config-schema-check/next.config.js

This file was deleted.

3 changes: 0 additions & 3 deletions test/integration/config-schema-check/pages/index.js

This file was deleted.

20 changes: 0 additions & 20 deletions test/integration/config-schema-check/test/index.test.js

This file was deleted.