-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
test(e2e): Verify bundler plugins instrument a bundled graphql at runtime #23670
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
Open
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
93 changes: 59 additions & 34 deletions
93
dev-packages/e2e-tests/test-applications/node-esbuild/assert.mjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 31 additions & 22 deletions
53
dev-packages/e2e-tests/test-applications/node-esbuild/build.mjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,41 +1,50 @@ | ||
| // Bundles the entrypoint with esbuild twice: | ||
| // - `plain`: no Sentry plugin. | ||
| // - `plugin`: with `sentryEsbuildPlugin` (build-time instrumentation). | ||
| // Only the `plugin` build runs the orchestrion code transform, which prepends the "bundler ran" | ||
| // banner to the entry chunk. Kept unminified so the banner keeps its identifiers (a minifier would | ||
| // rename them); assert.mjs matches it whitespace-insensitively. | ||
| // Bundles the entrypoint with esbuild four ways, each a directly-runnable CJS bundle: | ||
| // - `plain` / `plugin`: graphql inlined. Only `plugin` (with `sentryEsbuildPlugin`) | ||
| // build-time instruments it. Run without `--import`. | ||
| // - `plain-external` / `plugin-external`: graphql kept external so the runtime `--import` hook can | ||
| // intercept it at load time. Run with `--import`. | ||
| // esbuild emits CJS (not ESM): its ESM output can't perform the CJS `require('node:async_hooks')` that | ||
| // `@sentry/server-utils` does once inlined, and CJS is the normal esbuild node target. `assert.mjs` | ||
| // runs all four and checks the query works and that exactly one set of graphql spans is emitted in | ||
| // each instrumented scenario. Kept unminified so the injected snippet keeps its identifiers. | ||
| import { rmSync } from 'node:fs'; | ||
| import { dirname, join } from 'node:path'; | ||
| import { fileURLToPath } from 'node:url'; | ||
| import { build } from 'esbuild'; | ||
| import { sentryEsbuildPlugin } from '@sentry/node/esbuild'; | ||
|
|
||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
|
|
||
| function run(name, plugins) { | ||
| rmSync(join(__dirname, 'dist'), { recursive: true, force: true }); | ||
|
|
||
| // No auth/release/telemetry — we only care about the build-time transforms and defines. | ||
| const makeSentryPlugin = () => | ||
| sentryEsbuildPlugin({ | ||
| telemetry: false, | ||
| sourcemaps: { disable: true }, | ||
| release: { create: false, finalize: false, inject: false }, | ||
| }); | ||
|
|
||
| function run(name, { external, plugins }) { | ||
| return build({ | ||
| entryPoints: [join(__dirname, 'src', 'entry.mjs')], | ||
| outdir: join(__dirname, 'dist', name), | ||
| outfile: join(__dirname, 'dist', name, 'main.cjs'), | ||
| bundle: true, | ||
| platform: 'node', | ||
| format: 'esm', | ||
| format: 'cjs', | ||
| // The `*-external` variants keep graphql out of the bundle, so it is resolved from node_modules at | ||
| // runtime and the `--import` hook can transform it as it loads. | ||
| external: external ? ['graphql'] : [], | ||
| minify: false, | ||
| logLevel: 'silent', | ||
| plugins, | ||
| }); | ||
| } | ||
|
|
||
| await run('plain', []); | ||
| await run( | ||
| 'plugin', | ||
| // No auth/release/telemetry — we only care about the build-time transforms and defines. | ||
| [ | ||
| sentryEsbuildPlugin({ | ||
| telemetry: false, | ||
| sourcemaps: { disable: true }, | ||
| release: { create: false, finalize: false, inject: false }, | ||
| }), | ||
| ], | ||
| ); | ||
| await run('plain', { external: false, plugins: [] }); | ||
| await run('plugin', { external: false, plugins: [makeSentryPlugin()] }); | ||
| await run('plain-external', { external: true, plugins: [] }); | ||
| await run('plugin-external', { external: true, plugins: [makeSentryPlugin()] }); | ||
|
|
||
| // eslint-disable-next-line no-console | ||
| console.log('built plain + plugin with esbuild'); | ||
| console.log('built plain + plugin (inlined) and plain-external + plugin-external with esbuild'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 10 additions & 2 deletions
12
dev-packages/e2e-tests/test-applications/node-esbuild/src/app.mjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,10 @@ | ||
| // eslint-disable-next-line no-console | ||
| console.log('this is the application'); | ||
| // The real workload the bundle instruments: a `graphql` query. `graphql` is inlined into the bundle | ||
| // (only node builtins stay external), so the `plugin` build's orchestrion transform can rewrite it. | ||
| // graphql 16.x sits in the supported orchestrion range (`>=14.0.0 <17`). | ||
| import { buildSchema, graphql } from 'graphql'; | ||
|
|
||
| const schema = buildSchema('type Query { hello: String }'); | ||
|
|
||
| export async function runGraphqlQuery() { | ||
| return graphql({ schema, source: '{ hello }', rootValue: { hello: () => 'world' } }); | ||
| } |
45 changes: 39 additions & 6 deletions
45
dev-packages/e2e-tests/test-applications/node-esbuild/src/entry.mjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,42 @@ | ||
| // Bundled entrypoint, run directly with `node` (no `--import` runtime hook). `Sentry.init` runs | ||
| // first so the graphql channel subscriber is ready, then the workload is imported and run. Spans are | ||
| // collected via the `spanEnd` hook (transport- and trace-lifecycle-independent) and printed as a | ||
| // single machine-readable line for `assert.mjs`. | ||
| // | ||
| // The body is an async function rather than top-level await so the same source bundles to both ESM | ||
| // and CommonJS (esbuild emits CJS for a node target, which disallows top-level await). | ||
| import * as Sentry from '@sentry/node'; | ||
|
|
||
| Sentry.init({ | ||
| traceLifecycle: 'static', | ||
| dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
| tracesSampleRate: 1, | ||
| }); | ||
| async function main() { | ||
| Sentry.init({ | ||
| dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
| tracesSampleRate: 1, | ||
| // Isolate the build-time path: with the runtime hook off, the bundler plugin is the only possible | ||
| // injector, so a `plain` (no-plugin) build is a true negative. | ||
| enableRuntimeChannelInjection: false, | ||
| // Hermetic — never hit the network. | ||
| transport: () => ({ send: () => Promise.resolve({}), flush: () => Promise.resolve(true) }), | ||
| }); | ||
|
|
||
| await import('./app.mjs'); | ||
| const spans = []; | ||
| Sentry.getClient()?.on('spanEnd', span => { | ||
| const json = Sentry.spanToJSON(span); | ||
| spans.push({ name: json.name, origin: json.attributes?.['sentry.origin'] }); | ||
| }); | ||
|
|
||
| const { runGraphqlQuery } = await import('./app.mjs'); | ||
|
|
||
| let data; | ||
| await Sentry.startSpan({ name: 'graphql-work' }, async () => { | ||
| const result = await runGraphqlQuery(); | ||
| data = result.data; | ||
| }); | ||
|
|
||
| await Sentry.flush(2000); | ||
|
|
||
| // eslint-disable-next-line no-console | ||
| console.log(`__RESULT__${JSON.stringify({ data, spans })}`); | ||
| process.exit(0); | ||
| } | ||
|
|
||
| void main(); | ||
|
cursor[bot] marked this conversation as resolved.
|
||
93 changes: 59 additions & 34 deletions
93
dev-packages/e2e-tests/test-applications/node-rolldown/assert.mjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.