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

Add type checking events #24595

Merged
merged 2 commits into from
May 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import {
eventBuildOptimize,
eventCliSession,
eventNextPlugins,
eventTypeCheckCompleted,
} from '../telemetry/events'
import { Telemetry } from '../telemetry/storage'
import { CompilerResult, runCompiler } from './compiler'
Expand Down Expand Up @@ -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)

Expand All @@ -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()
}
Expand Down
2 changes: 1 addition & 1 deletion packages/next/export/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ interface ExportPageInput {
subFolders?: boolean
serverless: boolean
optimizeFonts: boolean
optimizeImages: boolean
optimizeImages?: boolean
optimizeCss: any
parentSpanId: any
}
Expand Down
18 changes: 16 additions & 2 deletions packages/next/lib/typescript/runTypeCheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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)

Expand Down Expand Up @@ -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,
}
}
9 changes: 5 additions & 4 deletions packages/next/lib/verifyTypeScriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ export async function verifyTypeScriptSetup(
dir: string,
pagesDir: string,
typeCheckPreflight: boolean
): Promise<TypeCheckResult | boolean> {
): 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

Expand All @@ -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) {
Expand Down
26 changes: 22 additions & 4 deletions packages/next/telemetry/events/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,25 @@ const REGEXP_DIRECTORY_DUNDER = /[\\/]__[^\\/]+(?<![\\/]__(?:tests|mocks))__[\\/
const REGEXP_DIRECTORY_TESTS = /[\\/]__(tests|mocks)__[\\/]/i
const REGEXP_FILE_TEST = /\.(?:spec|test)\.[^.]+$/i

const EVENT_BUILD_DURATION = 'NEXT_BUILD_COMPLETED'
const EVENT_TYPE_CHECK_COMPLETED = 'NEXT_TYPE_CHECK_COMPLETED'
type EventTypeCheckCompleted = {
durationInSeconds: number
typescriptVersion: string | null
inputFilesCount?: number
totalFilesCount?: number
incremental?: boolean
}

export function eventTypeCheckCompleted(
event: EventTypeCheckCompleted
): { eventName: string; payload: EventTypeCheckCompleted } {
return {
eventName: EVENT_TYPE_CHECK_COMPLETED,
payload: event,
}
}

const EVENT_BUILD_COMPLETED = 'NEXT_BUILD_COMPLETED'
type EventBuildCompleted = {
durationInSeconds: number
totalPageCount: number
Expand All @@ -18,7 +36,7 @@ export function eventBuildCompleted(
>
): { eventName: string; payload: EventBuildCompleted } {
return {
eventName: EVENT_BUILD_DURATION,
eventName: EVENT_BUILD_COMPLETED,
payload: {
...event,
totalPageCount: pagePaths.length,
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion packages/next/telemetry/trace/trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class Span {
}
}

async traceAsyncFn(fn: any) {
async traceAsyncFn<T>(fn: () => T | Promise<T>): Promise<T> {
try {
return await fn()
} finally {
Expand Down