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

Record leveraged configs #18175

Merged
merged 3 commits into from Oct 27, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/next/build/index.ts
Expand Up @@ -1048,6 +1048,9 @@ export default async function build(
(staticPages.size + ssgPages.size + serverPropsPages.size),
hasStatic404: useStatic404,
hasReportWebVitals: namedExports?.includes('reportWebVitals') ?? false,
rewritesCount: rewrites.length,
headersCount: headers.length,
redirectsCount: redirects.length - 1, // reduce one for trailing slash
})
)

Expand Down
3 changes: 3 additions & 0 deletions packages/next/telemetry/events/build.ts
Expand Up @@ -45,6 +45,9 @@ type EventBuildOptimized = {
hasTestPages: boolean
hasStatic404: boolean
hasReportWebVitals: boolean
headersCount: number
rewritesCount: number
redirectsCount: number
}

export function eventBuildOptimize(
Expand Down
36 changes: 36 additions & 0 deletions packages/next/telemetry/events/version.ts
Expand Up @@ -21,6 +21,17 @@ type EventCliSessionStarted = {
buildTarget: string
hasWebpackConfig: boolean
hasBabelConfig: boolean
basePathEnabled: boolean
i18nEnabled: boolean
imageEnabled: boolean
locales: string | null
localeDomainsCount: number | null
localeDetectionEnabled: boolean | null
imageDomainsCount: number | null
imageSizes: string | null
imageLoader: string | null
trailingSlashEnabled: boolean
reactStrictMode: boolean
}

function hasBabelConfig(dir: string): boolean {
Expand Down Expand Up @@ -83,6 +94,17 @@ export function eventCliSession(
| 'buildTarget'
| 'hasWebpackConfig'
| 'hasBabelConfig'
| 'basePathEnabled'
| 'i18nEnabled'
| 'imageEnabled'
| 'locales'
| 'localeDomainsCount'
| 'localeDetectionEnabled'
| 'imageDomainsCount'
| 'imageSizes'
| 'imageLoader'
| 'trailingSlashEnabled'
| 'reactStrictMode'
>
): { eventName: string; payload: EventCliSessionStarted }[] {
// This should be an invariant, if it fails our build tooling is broken.
Expand All @@ -92,6 +114,9 @@ export function eventCliSession(

const userConfiguration = getNextConfig(phase, dir)

const { images, experimental } = userConfiguration || {}
const { i18n } = experimental || {}

const payload: EventCliSessionStarted = {
nextVersion: process.env.__NEXT_VERSION,
nodeVersion: process.version,
Expand All @@ -103,6 +128,17 @@ export function eventCliSession(
buildTarget: userConfiguration?.target ?? 'default',
hasWebpackConfig: typeof userConfiguration?.webpack === 'function',
hasBabelConfig: hasBabelConfig(dir),
imageEnabled: !!images,
basePathEnabled: !!userConfiguration?.basePath,
i18nEnabled: !!i18n,
locales: i18n?.locales ? i18n.locales.join(',') : null,
localeDomainsCount: i18n?.domains ? i18n.domains.length : null,
localeDetectionEnabled: !i18n ? null : i18n.localeDetection !== false,
imageDomainsCount: images?.domains ? images.domains.length : null,
imageSizes: images?.sizes ? images.sizes.join(',') : null,
imageLoader: images?.loader,
trailingSlashEnabled: !!userConfiguration?.trailingSlash,
reactStrictMode: !!userConfiguration?.reactStrictMode,
}
return [{ eventName: EVENT_VERSION, payload }]
}
38 changes: 38 additions & 0 deletions test/integration/telemetry/next.config.custom-routes
@@ -0,0 +1,38 @@
module.exports = phase => {
return {
rewrites() {
return [
{
source: '/hello-1',
destination: '/world'
},
{
source: '/hello-2',
destination: '/world'
},
]
},
redirects() {
return [
{
source: '/hello-3',
destination: '/world',
permanent: false
}
]
},
headers() {
return [
{
source: '/hello-4',
headers: [
{
key: 'x-path',
value: 'hello-4'
}
]
}
]
}
}
}
24 changes: 24 additions & 0 deletions test/integration/telemetry/next.config.i18n-images
@@ -0,0 +1,24 @@
module.exports = phase => {
return {
images: {
sizes: [64, 128, 256, 512, 1024],
domains: ['example.com'],
},
experimental: {
i18n: {
locales: ['en','nl','fr'],
defaultLocale: 'en',
domains: [
{
domain: 'example.com',
defaultLocale: 'en'
},
{
domain: 'example.fr',
defaultLocale: 'fr'
}
]
}
}
}
}
87 changes: 87 additions & 0 deletions test/integration/telemetry/test/index.test.js
Expand Up @@ -420,4 +420,91 @@ describe('Telemetry CLI', () => {
event1 = /NEXT_BUILD_OPTIMIZED[\s\S]+?{([\s\S]+?)}/.exec(build.stderr).pop()
expect(event1).toMatch(/hasReportWebVitals.*?false/)
})

it('detects rewrites, headers, and redirects for next build', async () => {
await fs.rename(
path.join(appDir, 'next.config.custom-routes'),
path.join(appDir, 'next.config.js')
)

const { stderr } = await nextBuild(appDir, [], {
stderr: true,
env: { NEXT_TELEMETRY_DEBUG: 1 },
})

await fs.rename(
path.join(appDir, 'next.config.js'),
path.join(appDir, 'next.config.custom-routes')
)

const event1 = /NEXT_BUILD_OPTIMIZED[\s\S]+?{([\s\S]+?)}/.exec(stderr).pop()
expect(event1).toMatch(/"headersCount": 1/)
expect(event1).toMatch(/"rewritesCount": 2/)
expect(event1).toMatch(/"redirectsCount": 1/)
})

it('detects i18n and image configs for session start', async () => {
await fs.rename(
path.join(appDir, 'next.config.i18n-images'),
path.join(appDir, 'next.config.js')
)

const { stderr } = await nextBuild(appDir, [], {
stderr: true,
env: { NEXT_TELEMETRY_DEBUG: 1 },
})

await fs.rename(
path.join(appDir, 'next.config.js'),
path.join(appDir, 'next.config.i18n-images')
)

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

expect(event1).toMatch(/"i18nEnabled": true/)
expect(event1).toMatch(/"locales": "en,nl,fr"/)
expect(event1).toMatch(/"localeDomainsCount": 2/)
expect(event1).toMatch(/"localeDetectionEnabled": true/)
expect(event1).toMatch(/"imageDomainsCount": 1/)
expect(event1).toMatch(/"imageSizes": "64,128,256,512,1024"/)
expect(event1).toMatch(/"trailingSlashEnabled": false/)
expect(event1).toMatch(/"reactStrictMode": false/)

await fs.rename(
path.join(appDir, 'next.config.i18n-images'),
path.join(appDir, 'next.config.js')
)

let stderr2 = ''

let app = await launchApp(appDir, await findPort(), {
onStderr(msg) {
stderr2 += msg || ''
},
env: {
NEXT_TELEMETRY_DEBUG: 1,
},
})
await waitFor(1000)
await killApp(app)

await fs.rename(
path.join(appDir, 'next.config.js'),
path.join(appDir, 'next.config.i18n-images')
)

const event2 = /NEXT_CLI_SESSION_STARTED[\s\S]+?{([\s\S]+?)}/
.exec(stderr2)
.pop()
expect(event2).toMatch(/"i18nEnabled": true/)
expect(event2).toMatch(/"locales": "en,nl,fr"/)
expect(event2).toMatch(/"localeDomainsCount": 2/)
expect(event2).toMatch(/"localeDetectionEnabled": true/)
expect(event2).toMatch(/"imageDomainsCount": 1/)
expect(event2).toMatch(/"imageSizes": "64,128,256,512,1024"/)
expect(event2).toMatch(/"trailingSlashEnabled": false/)
expect(event2).toMatch(/"reactStrictMode": false/)
})
})