rsnext/packages/next/telemetry/events/build.ts
JJ Kasper 3a22e9768b
Track page counts during builds (#42766)
Ensures we keep track of page counts during builds. 

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see `contributing.md`

## 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.
- [ ] Errors have a helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
2022-11-10 17:47:33 -08:00

199 lines
5.6 KiB
TypeScript

import { TelemetryPlugin } from '../../build/webpack/plugins/telemetry-plugin'
import type { SWC_TARGET_TRIPLE } from '../../build/webpack/plugins/telemetry-plugin'
const REGEXP_DIRECTORY_DUNDER =
/[\\/]__[^\\/]+(?<![\\/]__(?:tests|mocks))__[\\/]/i
const REGEXP_DIRECTORY_TESTS = /[\\/]__(tests|mocks)__[\\/]/i
const REGEXP_FILE_TEST = /\.(?:spec|test)\.[^.]+$/i
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_LINT_CHECK_COMPLETED = 'NEXT_LINT_CHECK_COMPLETED'
export type EventLintCheckCompleted = {
durationInSeconds: number
eslintVersion: string | null
lintedFilesCount?: number
lintFix?: boolean
buildLint?: boolean
nextEslintPluginVersion?: string | null
nextEslintPluginErrorsCount?: number
nextEslintPluginWarningsCount?: number
nextRulesEnabled: {
[ruleName: `@next/next/${string}`]: 'off' | 'warn' | 'error'
}
}
export function eventLintCheckCompleted(event: EventLintCheckCompleted): {
eventName: string
payload: EventLintCheckCompleted
} {
return {
eventName: EVENT_LINT_CHECK_COMPLETED,
payload: event,
}
}
const EVENT_BUILD_COMPLETED = 'NEXT_BUILD_COMPLETED'
type EventBuildCompleted = {
durationInSeconds: number
totalPageCount: number
hasDunderPages: boolean
hasTestPages: boolean
totalAppPagesCount?: number
}
export function eventBuildCompleted(
pagePaths: string[],
event: Omit<
EventBuildCompleted,
'totalPageCount' | 'hasDunderPages' | 'hasTestPages'
>
): { eventName: string; payload: EventBuildCompleted } {
return {
eventName: EVENT_BUILD_COMPLETED,
payload: {
...event,
totalPageCount: pagePaths.length,
hasDunderPages: pagePaths.some((path) =>
REGEXP_DIRECTORY_DUNDER.test(path)
),
hasTestPages: pagePaths.some(
(path) =>
REGEXP_DIRECTORY_TESTS.test(path) || REGEXP_FILE_TEST.test(path)
),
totalAppPagesCount: event.totalAppPagesCount,
},
}
}
const EVENT_BUILD_OPTIMIZED = 'NEXT_BUILD_OPTIMIZED'
type EventBuildOptimized = {
durationInSeconds: number
totalPageCount: number
staticPageCount: number
staticPropsPageCount: number
serverPropsPageCount: number
ssrPageCount: number
hasDunderPages: boolean
hasTestPages: boolean
hasStatic404: boolean
hasReportWebVitals: boolean
headersCount: number
rewritesCount: number
redirectsCount: number
headersWithHasCount: number
rewritesWithHasCount: number
redirectsWithHasCount: number
middlewareCount: number
totalAppPagesCount?: number
staticAppPagesCount?: number
serverAppPagesCount?: number
edgeRuntimeAppCount?: number
edgeRuntimePagesCount?: number
}
export function eventBuildOptimize(
pagePaths: string[],
event: Omit<
EventBuildOptimized,
'totalPageCount' | 'hasDunderPages' | 'hasTestPages'
>
): { eventName: string; payload: EventBuildOptimized } {
return {
eventName: EVENT_BUILD_OPTIMIZED,
payload: {
...event,
totalPageCount: pagePaths.length,
hasDunderPages: pagePaths.some((path) =>
REGEXP_DIRECTORY_DUNDER.test(path)
),
hasTestPages: pagePaths.some(
(path) =>
REGEXP_DIRECTORY_TESTS.test(path) || REGEXP_FILE_TEST.test(path)
),
totalAppPagesCount: event.totalAppPagesCount,
staticAppPagesCount: event.staticAppPagesCount,
serverAppPagesCount: event.serverAppPagesCount,
edgeRuntimeAppCount: event.edgeRuntimeAppCount,
edgeRuntimePagesCount: event.edgeRuntimePagesCount,
},
}
}
export const EVENT_BUILD_FEATURE_USAGE = 'NEXT_BUILD_FEATURE_USAGE'
export type EventBuildFeatureUsage = {
// NOTE: If you are adding features, make sure to update the `enum` field
// for `featureName` in https://github.com/vercel/next-telemetry/blob/master/events/v1/featureUsage.ts
// *before* you make changes here.
featureName:
| 'next/image'
| 'next/legacy/image'
| 'next/future/image'
| 'next/script'
| 'next/dynamic'
| '@next/font/google'
| '@next/font/local'
| 'experimental/optimizeCss'
| 'experimental/nextScriptWorkers'
| 'optimizeFonts'
| 'swcLoader'
| 'swcMinify'
| 'swcRelay'
| 'swcStyledComponents'
| 'swcReactRemoveProperties'
| 'swcExperimentalDecorators'
| 'swcRemoveConsole'
| 'swcImportSource'
| 'swcEmotion'
| `swc/target/${SWC_TARGET_TRIPLE}`
| 'turbotrace'
| 'build-lint'
| 'vercelImageGeneration'
invocationCount: number
}
export function eventBuildFeatureUsage(
telemetryPlugin: TelemetryPlugin
): Array<{ eventName: string; payload: EventBuildFeatureUsage }> {
return telemetryPlugin.usages().map(({ featureName, invocationCount }) => ({
eventName: EVENT_BUILD_FEATURE_USAGE,
payload: {
featureName,
invocationCount,
},
}))
}
export const EVENT_NAME_PACKAGE_USED_IN_GET_SERVER_SIDE_PROPS =
'NEXT_PACKAGE_USED_IN_GET_SERVER_SIDE_PROPS'
export type EventPackageUsedInGetServerSideProps = {
package: string
}
export function eventPackageUsedInGetServerSideProps(
telemetryPlugin: TelemetryPlugin
): Array<{ eventName: string; payload: EventPackageUsedInGetServerSideProps }> {
return telemetryPlugin.packagesUsedInServerSideProps().map((packageName) => ({
eventName: EVENT_NAME_PACKAGE_USED_IN_GET_SERVER_SIDE_PROPS,
payload: {
package: packageName,
},
}))
}