Skip to content

Commit

Permalink
telemetry: collect feature usage for linting during build (#32022)
Browse files Browse the repository at this point in the history
Currently, we have telemetry to measure how ESLint is invoked,
but we do not have telemetry that tells us how many users have
disabled ESLint during build.

This commit adds a new feature, `build lint` to track this metric.



## Bug

- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have 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 helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`
  • Loading branch information
kyliau committed Dec 7, 2021
1 parent db773c4 commit 53e52fe
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
11 changes: 10 additions & 1 deletion packages/next/build/index.ts
Expand Up @@ -243,7 +243,8 @@ export default async function build(

const ignoreESLint = Boolean(config.eslint.ignoreDuringBuilds)
const eslintCacheDir = path.join(cacheDir, 'eslint/')
if (!ignoreESLint && runLint) {
const shouldLint = !ignoreESLint && runLint
if (shouldLint) {
await nextBuildSpan
.traceChild('verify-and-lint')
.traceAsyncFn(async () => {
Expand All @@ -257,6 +258,14 @@ export default async function build(
)
})
}
const buildLintEvent: EventBuildFeatureUsage = {
featureName: 'build-lint',
invocationCount: shouldLint ? 1 : 0,
}
telemetry.record({
eventName: EVENT_BUILD_FEATURE_USAGE,
payload: buildLintEvent,
})

const buildSpinner = createSpinner({
prefixText: `${Log.prefixes.info} Creating an optimized production build`,
Expand Down
1 change: 1 addition & 0 deletions packages/next/telemetry/events/build.ts
Expand Up @@ -134,6 +134,7 @@ export type EventBuildFeatureUsage = {
| 'optimizeFonts'
| 'swcLoader'
| 'swcMinify'
| 'build-lint'
invocationCount: number
}
export function eventBuildFeatureUsage(
Expand Down
42 changes: 42 additions & 0 deletions test/integration/telemetry/test/index.test.js
Expand Up @@ -541,6 +541,46 @@ describe('Telemetry CLI', () => {
expect(event1).toMatch(/"nextEslintPluginVersion": ".*?\..*?\..*?"/)
expect(event1).toMatch(/"nextEslintPluginErrorsCount": \d{1,}/)
expect(event1).toMatch(/"nextEslintPluginWarningsCount": \d{1,}/)

const event2 = /NEXT_BUILD_FEATURE_USAGE[\s\S]+?{([\s\S]+?)}/
.exec(stderr)
.pop()
expect(event2).toContain(`"featureName": "build-lint"`)
expect(event2).toContain(`"invocationCount": 1`)
})

it(`emits telemetry for lint during build when '--no-lint' is specified`, async () => {
const { stderr } = await nextBuild(appDir, ['--no-lint'], {
stderr: true,
env: { NEXT_TELEMETRY_DEBUG: 1 },
})

const event1 = /NEXT_BUILD_FEATURE_USAGE[\s\S]+?{([\s\S]+?)}/
.exec(stderr)
.pop()

expect(event1).toContain(`"featureName": "build-lint"`)
expect(event1).toContain(`"invocationCount": 0`)
})

it(`emits telemetry for lint during build when 'ignoreDuringBuilds' is specified`, async () => {
const nextConfig = path.join(appDir, 'next.config.js')
await fs.writeFile(
nextConfig,
`module.exports = { eslint: { ignoreDuringBuilds: true } }`
)
const { stderr } = await nextBuild(appDir, [], {
stderr: true,
env: { NEXT_TELEMETRY_DEBUG: 1 },
})
await fs.remove(nextConfig)

const event1 = /NEXT_BUILD_FEATURE_USAGE[\s\S]+?{([\s\S]+?)}/
.exec(stderr)
.pop()

expect(event1).toContain(`"featureName": "build-lint"`)
expect(event1).toContain(`"invocationCount": 0`)
})

it('emits telemetry for `next lint`', async () => {
Expand Down Expand Up @@ -575,6 +615,7 @@ describe('Telemetry CLI', () => {
})
const regex = /NEXT_BUILD_FEATURE_USAGE[\s\S]+?{([\s\S]+?)}/g
regex.exec(stderr).pop() // optimizeCss
regex.exec(stderr).pop() // build-lint
const optimizeFonts = regex.exec(stderr).pop()
expect(optimizeFonts).toContain(`"featureName": "optimizeFonts"`)
expect(optimizeFonts).toContain(`"invocationCount": 1`)
Expand Down Expand Up @@ -612,6 +653,7 @@ describe('Telemetry CLI', () => {
)

const regex = /NEXT_BUILD_FEATURE_USAGE[\s\S]+?{([\s\S]+?)}/g
regex.exec(stderr).pop() // build-lint
const optimizeCss = regex.exec(stderr).pop()
expect(optimizeCss).toContain(`"featureName": "experimental/optimizeCss"`)
expect(optimizeCss).toContain(`"invocationCount": 1`)
Expand Down

0 comments on commit 53e52fe

Please sign in to comment.