Skip to content

Commit

Permalink
Add type checking events (#24595)
Browse files Browse the repository at this point in the history
Will send events like this:

```
[telemetry] {
  "eventName": "NEXT_TYPE_CHECK_COMPLETED",
  "payload": {
    "durationInSeconds": 2,
    "typescriptVersion": "3.8.3",
    "inputFilesCount": 16,
    "totalFilesCount": 289,
    "incremental": false
  }
}
```

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.

## Documentation / Examples

- [ ] Make sure the linting passes
  • Loading branch information
sokra authored May 4, 2021
1 parent 3e6ce90 commit 3a78ccd
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 17 deletions.
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

0 comments on commit 3a78ccd

Please sign in to comment.