diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index b3dd4ddbe173a..1c9d1e8f19b20 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -66,6 +66,7 @@ import { eventBuildOptimize, eventCliSession, eventNextPlugins, + eventTypeCheckCompleted, } from '../telemetry/events' import { Telemetry } from '../telemetry/storage' import { CompilerResult, runCompiler } from './compiler' @@ -158,10 +159,6 @@ export default async function build( } } - const typeCheckingSpinner = createSpinner({ - prefixText: `${Log.prefixes.info} Checking validity of types`, - }) - const telemetry = new Telemetry({ distDir }) setGlobal('telemetry', telemetry) @@ -184,12 +181,29 @@ export default async function build( ) const ignoreTypeScriptErrors = Boolean(config.typescript?.ignoreBuildErrors) - await nextBuildSpan + const typeCheckStart = process.hrtime() + const typeCheckingSpinner = createSpinner({ + prefixText: `${Log.prefixes.info} Checking validity of types`, + }) + + const verifyResult = await nextBuildSpan .traceChild('verify-typescript-setup') .traceAsyncFn(() => verifyTypeScriptSetup(dir, pagesDir, !ignoreTypeScriptErrors) ) + const typeCheckEnd = process.hrtime(typeCheckStart) + + telemetry.record( + eventTypeCheckCompleted({ + durationInSeconds: typeCheckEnd[0], + typescriptVersion: verifyResult.version, + inputFilesCount: verifyResult.result?.inputFilesCount, + totalFilesCount: verifyResult.result?.totalFilesCount, + incremental: verifyResult.result?.incremental, + }) + ) + if (typeCheckingSpinner) { typeCheckingSpinner.stopAndPersist() } diff --git a/packages/next/export/worker.ts b/packages/next/export/worker.ts index 30885bea8af90..68f03b80f4ba6 100644 --- a/packages/next/export/worker.ts +++ b/packages/next/export/worker.ts @@ -50,7 +50,7 @@ interface ExportPageInput { subFolders?: boolean serverless: boolean optimizeFonts: boolean - optimizeImages: boolean + optimizeImages?: boolean optimizeCss: any parentSpanId: any } diff --git a/packages/next/lib/typescript/runTypeCheck.ts b/packages/next/lib/typescript/runTypeCheck.ts index 90fc6bee4bde7..510fad4a43c77 100644 --- a/packages/next/lib/typescript/runTypeCheck.ts +++ b/packages/next/lib/typescript/runTypeCheck.ts @@ -10,6 +10,9 @@ import { CompileError } from '../compile-error' export interface TypeCheckResult { hasWarnings: boolean warnings?: string[] + inputFilesCount: number + totalFilesCount: number + incremental: boolean } export async function runTypeCheck( @@ -23,7 +26,12 @@ export async function runTypeCheck( ) if (effectiveConfiguration.fileNames.length < 1) { - return { hasWarnings: false } + return { + hasWarnings: false, + inputFilesCount: 0, + totalFilesCount: 0, + incremental: false, + } } const requiredConfig = getRequiredConfiguration(ts) @@ -66,5 +74,11 @@ export async function runTypeCheck( .filter((d) => d.category === DiagnosticCategory.Warning) .map((d) => getFormattedDiagnostic(ts, baseDir, d)) ) - return { hasWarnings: true, warnings } + return { + hasWarnings: true, + warnings, + inputFilesCount: effectiveConfiguration.fileNames.length, + totalFilesCount: program.getSourceFiles().length, + incremental: false, + } } diff --git a/packages/next/lib/verifyTypeScriptSetup.ts b/packages/next/lib/verifyTypeScriptSetup.ts index 8687086b1bc7c..6f10375cb3743 100644 --- a/packages/next/lib/verifyTypeScriptSetup.ts +++ b/packages/next/lib/verifyTypeScriptSetup.ts @@ -16,14 +16,14 @@ export async function verifyTypeScriptSetup( dir: string, pagesDir: string, typeCheckPreflight: boolean -): Promise { +): Promise<{ result?: TypeCheckResult; version: string | null }> { const tsConfigPath = path.join(dir, 'tsconfig.json') try { // Check if the project uses TypeScript: const intent = await getTypeScriptIntent(dir, pagesDir) if (!intent) { - return false + return { version: null } } const firstTimeSetup = intent.firstTimeSetup @@ -43,13 +43,14 @@ export async function verifyTypeScriptSetup( // Next.js' types: await writeAppTypeDeclarations(dir) + let result if (typeCheckPreflight) { const { runTypeCheck } = require('./typescript/runTypeCheck') // Verify the project passes type-checking before we go to webpack phase: - return await runTypeCheck(ts, dir, tsConfigPath) + result = await runTypeCheck(ts, dir, tsConfigPath) } - return true + return { result, version: ts.version } } catch (err) { // These are special errors that should not show a stack trace: if (err instanceof CompileError) { diff --git a/packages/next/telemetry/events/build.ts b/packages/next/telemetry/events/build.ts index 8a1a6dd95fb62..4ad75df441166 100644 --- a/packages/next/telemetry/events/build.ts +++ b/packages/next/telemetry/events/build.ts @@ -2,7 +2,25 @@ const REGEXP_DIRECTORY_DUNDER = /[\\/]__[^\\/]+(? ): { eventName: string; payload: EventBuildCompleted } { return { - eventName: EVENT_BUILD_DURATION, + eventName: EVENT_BUILD_COMPLETED, payload: { ...event, totalPageCount: pagePaths.length, @@ -33,7 +51,7 @@ export function eventBuildCompleted( } } -const EVENT_BUILD_OPTIMIZE = 'NEXT_BUILD_OPTIMIZED' +const EVENT_BUILD_OPTIMIZED = 'NEXT_BUILD_OPTIMIZED' type EventBuildOptimized = { durationInSeconds: number totalPageCount: number @@ -61,7 +79,7 @@ export function eventBuildOptimize( > ): { eventName: string; payload: EventBuildOptimized } { return { - eventName: EVENT_BUILD_OPTIMIZE, + eventName: EVENT_BUILD_OPTIMIZED, payload: { ...event, totalPageCount: pagePaths.length, diff --git a/packages/next/telemetry/trace/trace.ts b/packages/next/telemetry/trace/trace.ts index d122de81fb226..5874dda8ea935 100644 --- a/packages/next/telemetry/trace/trace.ts +++ b/packages/next/telemetry/trace/trace.ts @@ -71,7 +71,7 @@ export class Span { } } - async traceAsyncFn(fn: any) { + async traceAsyncFn(fn: () => T | Promise): Promise { try { return await fn() } finally {