Skip to content

Commit d0ad09c

Browse files
committed
Use raw requests to detect feature usage in telemetry
This is required for when we start using layers in Pages Router. It's also required to fix telemetry of certain features in App Router which makes extensive usage of layers. That isn't working just yet though a test was kept in place.
1 parent f5f7151 commit d0ad09c

File tree

7 files changed

+171
-196
lines changed

7 files changed

+171
-196
lines changed

packages/next/src/build/webpack/plugins/telemetry-plugin/telemetry-plugin.ts

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,28 +54,20 @@ interface FeatureUsage {
5454
invocationCount: number
5555
}
5656

57-
/**
58-
* A vertex in the module graph.
59-
*/
60-
interface Module {
61-
type: string
62-
identifier(): string
63-
}
64-
6557
/**
6658
* An edge in the module graph.
6759
*/
6860
interface Connection {
6961
originModule: unknown
7062
}
7163

72-
// Map of a feature module to the file it belongs in the next package.
64+
// Map of a feature module to the request it belongs to
7365
const FEATURE_MODULE_MAP: ReadonlyMap<Feature, string> = new Map([
74-
['next/image', '/next/image.js'],
75-
['next/future/image', '/next/future/image.js'],
76-
['next/legacy/image', '/next/legacy/image.js'],
77-
['next/script', '/next/script.js'],
78-
['next/dynamic', '/next/dynamic.js'],
66+
['next/image', 'next/image'],
67+
['next/future/image', 'next/future/image'],
68+
['next/legacy/image', 'next/legacy/image'],
69+
['next/script', 'next/script'],
70+
['next/dynamic', 'next/dynamic'],
7971
])
8072
const FEATURE_MODULE_REGEXP_MAP: ReadonlyMap<Feature, RegExp> = new Map([
8173
['@next/font/google', /\/@next\/font\/google\/target.css?.+$/],
@@ -127,16 +119,16 @@ const useCacheTracker = createUseCacheTracker()
127119
/**
128120
* Determine if there is a feature of interest in the specified 'module'.
129121
*/
130-
function findFeatureInModule(module: Module): Feature | undefined {
122+
function findFeatureInModule(module: webpack.Module): Feature | undefined {
131123
if (module.type !== 'javascript/auto') {
132124
return
133125
}
134-
const normalizedIdentifier = module.identifier().replace(/\\/g, '/')
135-
for (const [feature, path] of FEATURE_MODULE_MAP) {
136-
if (normalizedIdentifier.endsWith(path)) {
126+
for (const [feature, rawRequest] of FEATURE_MODULE_MAP) {
127+
if ((module as webpack.NormalModule).rawRequest === rawRequest) {
137128
return feature
138129
}
139130
}
131+
const normalizedIdentifier = module.identifier().replace(/\\/g, '/')
140132
for (const [feature, regexp] of FEATURE_MODULE_REGEXP_MAP) {
141133
if (regexp.test(normalizedIdentifier)) {
142134
return feature
@@ -151,7 +143,7 @@ function findFeatureInModule(module: Module): Feature | undefined {
151143
*/
152144
function findUniqueOriginModulesInConnections(
153145
connections: Connection[],
154-
originModule: Module
146+
originModule: webpack.Module
155147
): Set<unknown> {
156148
const originModules = new Set()
157149
for (const connection of connections) {
@@ -206,7 +198,7 @@ export class TelemetryPlugin implements webpack.WebpackPluginInstance {
206198
async (compilation: webpack.Compilation, callback: () => void) => {
207199
compilation.hooks.finishModules.tapAsync(
208200
TelemetryPlugin.name,
209-
async (modules: Iterable<Module>, modulesFinish: () => void) => {
201+
async (modules, modulesFinish) => {
210202
for (const module of modules) {
211203
const feature = findFeatureInModule(module)
212204
if (!feature) {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Image from 'next/image'
2+
import LegacyImage from 'next/legacy/image'
3+
import profilePic from '../../public/small.jpg'
4+
5+
function About() {
6+
return (
7+
<>
8+
<h1>My Homepage</h1>
9+
<LegacyImage src={profilePic} alt="Picture of the author" />
10+
<Image src={profilePic} alt="Picture of the author" />
11+
<p>Welcome to my homepage!</p>
12+
</>
13+
)
14+
}
15+
16+
export default About
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Page() {
2+
return 'hello world'
3+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function RootLayout({ children }) {
2+
return (
3+
<html>
4+
<body>{children}</body>
5+
</html>
6+
)
7+
}

test/integration/telemetry/test/config.test.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ describe('config telemetry', () => {
8484
expect(event1).toMatch(/"reactStrictMode": false/)
8585
expect(event1).toMatch(/"turboFlag": false/)
8686
expect(event1).toMatch(/"pagesDir": true/)
87-
expect(event1).toMatch(/"appDir": false/)
87+
expect(event1).toMatch(/"appDir": true/)
8888
} catch (err) {
8989
require('console').error('failing stderr', stderr, err)
9090
throw err
@@ -287,6 +287,7 @@ describe('config telemetry', () => {
287287
expect.arrayContaining([
288288
{
289289
featureName: 'next/image',
290+
// FIXME: Should be +1 from App Router
290291
invocationCount: 2,
291292
},
292293
{
@@ -532,12 +533,14 @@ describe('config telemetry', () => {
532533
)
533534
// eslint-disable-next-line jest/no-standalone-expect
534535
expect(featureUsageEvents).toContainEqual({
536+
// FIXME: Should be +1 from App Router
535537
featureName: 'next/legacy/image',
536538
invocationCount: 2,
537539
})
538540
// eslint-disable-next-line jest/no-standalone-expect
539541
expect(featureUsageEvents).toContainEqual({
540542
featureName: 'next/image',
543+
// FIXME: Should be +1 from App Router
541544
invocationCount: 2,
542545
})
543546
}
@@ -724,6 +727,7 @@ describe('config telemetry', () => {
724727
path.join(appDir, 'next.config.js')
725728
)
726729

730+
await fs.move(path.join(appDir, 'app'), path.join(appDir, '~app'))
727731
await fs.move(path.join(appDir, '_app'), path.join(appDir, 'app'))
728732

729733
const { stderr } = await nextBuild(appDir, [], {
@@ -737,6 +741,7 @@ describe('config telemetry', () => {
737741
)
738742

739743
await fs.move(path.join(appDir, 'app'), path.join(appDir, '_app'))
744+
await fs.move(path.join(appDir, '~app'), path.join(appDir, 'app'))
740745

741746
const featureUsageEvents = findAllTelemetryEvents(
742747
stderr,

test/integration/telemetry/test/index.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,8 @@ describe('Telemetry CLI', () => {
382382
expect(event1).toMatch(/"ssrPageCount": 3/)
383383
expect(event1).toMatch(/"staticPageCount": 5/)
384384
expect(event1).toMatch(/"totalPageCount": 12/)
385-
expect(event1).toMatch(/"totalAppPagesCount": 0/)
386-
expect(event1).toMatch(/"staticAppPagesCount": 0/)
385+
expect(event1).toMatch(/"totalAppPagesCount": 3/)
386+
expect(event1).toMatch(/"staticAppPagesCount": 3/)
387387
expect(event1).toMatch(/"serverAppPagesCount": 0/)
388388
expect(event1).toMatch(/"edgeRuntimeAppCount": 0/)
389389
expect(event1).toMatch(/"edgeRuntimePagesCount": 2/)

0 commit comments

Comments
 (0)