Skip to content

Commit f612acf

Browse files
authored
Add test case for image generation (#42693)
This PR adds a basic test case to ensure Next.js and Edge Runtime changes don't break the image generation feature, as well as record the usage. ## 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` - [x] Integration tests added - [ ] Documentation added - [x] 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)
1 parent 9d30e77 commit f612acf

File tree

8 files changed

+176
-5
lines changed

8 files changed

+176
-5
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
"@typescript-eslint/eslint-plugin": "4.29.1",
9191
"@typescript-eslint/parser": "4.29.1",
9292
"@vercel/fetch": "6.1.1",
93+
"@vercel/og": "0.0.20",
9394
"@webassemblyjs/ast": "1.11.1",
9495
"@webassemblyjs/floating-point-hex-parser": "1.11.1",
9596
"@webassemblyjs/helper-api-error": "1.11.1",

packages/next/build/webpack/plugins/middleware-plugin.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
} from '../../analysis/get-page-static-info'
2828
import { Telemetry } from '../../../telemetry/storage'
2929
import { traceGlobals } from '../../../trace/shared'
30+
import { EVENT_BUILD_FEATURE_USAGE } from '../../../telemetry/events'
3031

3132
export interface EdgeFunctionDefinition {
3233
env: string[]
@@ -686,6 +687,25 @@ function getExtractMetadata(params: {
686687
for (const module of modules) {
687688
const buildInfo = getModuleBuildInfo(module)
688689

690+
/**
691+
* Check if it uses the image generation feature.
692+
*/
693+
if (!dev) {
694+
const resource = module.resource
695+
const hasOGImageGeneration =
696+
resource &&
697+
/[\\/]node_modules[\\/]@vercel[\\/]og[\\/]dist[\\/]index.js$/.test(
698+
resource
699+
)
700+
telemetry.record({
701+
eventName: EVENT_BUILD_FEATURE_USAGE,
702+
payload: {
703+
featureName: 'vercelImageGeneration',
704+
invocationCount: hasOGImageGeneration ? 1 : 0,
705+
},
706+
})
707+
}
708+
689709
/**
690710
* When building for production checks if the module is using `eval`
691711
* and in such case produces a compilation error. The module has to

packages/next/telemetry/events/build.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ export type EventBuildFeatureUsage = {
153153
| `swc/target/${SWC_TARGET_TRIPLE}`
154154
| 'turbotrace'
155155
| 'build-lint'
156+
| 'vercelImageGeneration'
156157
invocationCount: number
157158
}
158159
export function eventBuildFeatureUsage(

pnpm-lock.yaml

Lines changed: 77 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { ImageResponse } from '@vercel/og'
2+
3+
export default async () => {
4+
return new ImageResponse(<div tw="w-full h-full text-5xl">hello</div>)
5+
}
6+
7+
export const config = {
8+
runtime: 'experimental-edge',
9+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* eslint-env jest */
2+
import {
3+
fetchViaHTTP,
4+
findPort,
5+
killApp,
6+
nextBuild,
7+
nextStart,
8+
} from 'next-test-utils'
9+
import { join } from 'path'
10+
11+
const appDir = join(__dirname, '../app')
12+
13+
describe('Image Generation', () => {
14+
describe('Prod', () => {
15+
let app
16+
let appPort
17+
18+
beforeAll(async () => {
19+
await nextBuild(appDir)
20+
appPort = await findPort()
21+
app = await nextStart(appDir, appPort)
22+
})
23+
afterAll(async () => {
24+
await killApp(app)
25+
})
26+
27+
it('should generate the image without errors', async () => {
28+
const res = await fetchViaHTTP(appPort, '/api/image')
29+
expect(res.status).toBe(200)
30+
expect(res.headers.get('Content-Type')).toBe('image/png')
31+
32+
const buffer = await res.buffer()
33+
34+
// It should be a PNG
35+
expect(
36+
[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a].every(
37+
(b, i) => buffer[i] === b
38+
)
39+
).toBeTrue()
40+
})
41+
})
42+
})
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { ImageResponse } from '@vercel/og'
2+
3+
export default async () => {
4+
return new ImageResponse(<div tw="w-full h-full text-5xl">hello</div>)
5+
}
6+
7+
export const config = {
8+
runtime: 'experimental-edge',
9+
}

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,9 @@ describe('Telemetry CLI', () => {
331331
const event1 = /NEXT_BUILD_OPTIMIZED[\s\S]+?{([\s\S]+?)}/.exec(stderr).pop()
332332
expect(event1).toMatch(/"staticPropsPageCount": 2/)
333333
expect(event1).toMatch(/"serverPropsPageCount": 2/)
334-
expect(event1).toMatch(/"ssrPageCount": 1/)
334+
expect(event1).toMatch(/"ssrPageCount": 2/)
335335
expect(event1).toMatch(/"staticPageCount": 4/)
336-
expect(event1).toMatch(/"totalPageCount": 9/)
336+
expect(event1).toMatch(/"totalPageCount": 10/)
337337
})
338338

339339
it('detects isSrcDir dir correctly for `next dev`', async () => {
@@ -970,4 +970,19 @@ describe('Telemetry CLI', () => {
970970
invocationCount: 1,
971971
})
972972
})
973+
974+
it('emits telemetry for usage of @vercel/og', async () => {
975+
const { stderr } = await nextBuild(appDir, [], {
976+
stderr: true,
977+
env: { NEXT_TELEMETRY_DEBUG: 1 },
978+
})
979+
const featureUsageEvents = findAllTelemetryEvents(
980+
stderr,
981+
'NEXT_BUILD_FEATURE_USAGE'
982+
)
983+
expect(featureUsageEvents).toContainEqual({
984+
featureName: 'vercelImageGeneration',
985+
invocationCount: 1,
986+
})
987+
})
973988
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy