From 26c438b49dd1797a690cb51af476fcfb0610a620 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 27 Oct 2020 08:46:18 -0500 Subject: [PATCH] Record leveraged configs (#18175) This records new configs being leveraged --- packages/next/build/index.ts | 3 + packages/next/telemetry/events/build.ts | 3 + packages/next/telemetry/events/version.ts | 36 ++++++++ .../telemetry/next.config.custom-routes | 38 ++++++++ .../telemetry/next.config.i18n-images | 24 +++++ test/integration/telemetry/test/index.test.js | 87 +++++++++++++++++++ 6 files changed, 191 insertions(+) create mode 100644 test/integration/telemetry/next.config.custom-routes create mode 100644 test/integration/telemetry/next.config.i18n-images diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index a543f44029b6bb2..86c9db6323b417c 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -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 }) ) diff --git a/packages/next/telemetry/events/build.ts b/packages/next/telemetry/events/build.ts index 6d3676d04234d9d..50931ec2ec6b9cd 100644 --- a/packages/next/telemetry/events/build.ts +++ b/packages/next/telemetry/events/build.ts @@ -45,6 +45,9 @@ type EventBuildOptimized = { hasTestPages: boolean hasStatic404: boolean hasReportWebVitals: boolean + headersCount: number + rewritesCount: number + redirectsCount: number } export function eventBuildOptimize( diff --git a/packages/next/telemetry/events/version.ts b/packages/next/telemetry/events/version.ts index edbd5f1c9cb5a3b..60a9ab67874fbdb 100644 --- a/packages/next/telemetry/events/version.ts +++ b/packages/next/telemetry/events/version.ts @@ -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 { @@ -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. @@ -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, @@ -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 }] } diff --git a/test/integration/telemetry/next.config.custom-routes b/test/integration/telemetry/next.config.custom-routes new file mode 100644 index 000000000000000..d702eaaf756e399 --- /dev/null +++ b/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' + } + ] + } + ] + } + } +} diff --git a/test/integration/telemetry/next.config.i18n-images b/test/integration/telemetry/next.config.i18n-images new file mode 100644 index 000000000000000..61d99bdee5e3f76 --- /dev/null +++ b/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' + } + ] + } + } + } +} diff --git a/test/integration/telemetry/test/index.test.js b/test/integration/telemetry/test/index.test.js index c974fad1279aac0..34e1b94da1b4d13 100644 --- a/test/integration/telemetry/test/index.test.js +++ b/test/integration/telemetry/test/index.test.js @@ -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/) + }) })