From 1d88157f10fbc8c61c1e5a6d0e39b556c6584c16 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Tue, 28 Jul 2026 13:45:26 +0200 Subject: [PATCH 1/2] add disable option --- .../buildTimeOptionsBase.ts | 20 +++++ packages/core/src/shared-exports.ts | 1 + packages/node/src/bundler-plugin/esbuild.ts | 13 ++- packages/node/src/bundler-plugin/rollup.ts | 12 ++- packages/node/src/bundler-plugin/vite.ts | 12 ++- packages/node/src/bundler-plugin/webpack.ts | 13 ++- .../bundler-plugin/bundler-plugin.test.ts | 80 +++++++++++++++++++ .../src/orchestrion/bundler/esbuild.ts | 5 ++ .../src/orchestrion/bundler/options.ts | 7 ++ .../src/orchestrion/bundler/rollup.ts | 5 ++ .../src/orchestrion/bundler/vite.ts | 7 ++ .../src/orchestrion/bundler/webpack.ts | 5 ++ .../test/orchestrion/bundler.test.ts | 41 ++++++++++ 13 files changed, 215 insertions(+), 6 deletions(-) create mode 100644 packages/node/test/bundler-plugin/bundler-plugin.test.ts diff --git a/packages/core/src/build-time-plugins/buildTimeOptionsBase.ts b/packages/core/src/build-time-plugins/buildTimeOptionsBase.ts index 91ef3eaced37..7a9fdf25eb04 100644 --- a/packages/core/src/build-time-plugins/buildTimeOptionsBase.ts +++ b/packages/core/src/build-time-plugins/buildTimeOptionsBase.ts @@ -126,6 +126,11 @@ export interface BuildTimeOptionsBase { */ bundleSizeOptimizations?: BundleSizeOptimizationsOptions; + /** + * Options related to automatic build-time instrumentation of server-side dependencies. + */ + buildTimeInstrumentation?: BuildTimeInstrumentationOptions; + /** * A key that is used to identify the application in the Sentry bundler plugins. * This key is used by the `thirdPartyErrorFilterIntegration` to filter out errors @@ -136,6 +141,21 @@ export interface BuildTimeOptionsBase { applicationKey?: string; } +/** + * Options related to automatic instrumentation of server-side dependencies at build time. + * + * @internal Only meant for Sentry-internal SDK usage. + * @hidden + */ +export interface BuildTimeInstrumentationOptions { + /** + * If set to `true`, disables automatic instrumentation of server-side dependencies at build time. + * + * @default false + */ + disable?: boolean; +} + /** * Utility type for adding Vite plugin options to build-time configuration. * Use this type to extend your build-time options with Vite-specific plugin configurations. diff --git a/packages/core/src/shared-exports.ts b/packages/core/src/shared-exports.ts index 700e65d2a974..d5acbb3fe357 100644 --- a/packages/core/src/shared-exports.ts +++ b/packages/core/src/shared-exports.ts @@ -520,6 +520,7 @@ export type { LegacyCSPReport } from './types/csp'; export type { SerializedLog, SerializedLogContainer } from './types/log'; export type { BuildTimeOptionsBase, + BuildTimeInstrumentationOptions, UnstableVitePluginOptions, UnstableRollupPluginOptions, UnstableWebpackPluginOptions, diff --git a/packages/node/src/bundler-plugin/esbuild.ts b/packages/node/src/bundler-plugin/esbuild.ts index b72ac9f0c03b..468c24a8dc44 100644 --- a/packages/node/src/bundler-plugin/esbuild.ts +++ b/packages/node/src/bundler-plugin/esbuild.ts @@ -1,5 +1,6 @@ import { sentryEsbuildPlugin as sentryEsbuildBundlerPlugin } from '@sentry/bundler-plugins/esbuild'; import type { SentryEsbuildPluginOptions as SentryEsbuildPluginOptionsBase } from '@sentry/bundler-plugins/esbuild'; +import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/esbuild'; export type SentryEsbuildPluginOptions = SentryEsbuildPluginOptionsBase & { @@ -7,6 +8,13 @@ export type SentryEsbuildPluginOptions = SentryEsbuildPluginOptionsBase & { * @ignore This is for internal use only when this plugin is consumed by a framework SDK */ instrumentations?: NonNullable[0]>['instrumentations']; + + /** + * Options related to automatic instrumentation of server-side dependencies at build time. + * + * Set `buildTimeInstrumentation.disable` to `true` to turn it off. + */ + buildTimeInstrumentation?: BuildTimeInstrumentationOptions; }; type EsbuildPlugin = ReturnType; @@ -27,13 +35,14 @@ type EsbuildPlugin = ReturnType; */ export function sentryEsbuildPlugin(options?: SentryEsbuildPluginOptions): EsbuildPlugin { const bundlerPlugin = sentryEsbuildBundlerPlugin(options) as EsbuildPlugin; - const orchestrionPlugin = sentryOrchestrionPlugin(options); return { name: 'sentry-node-esbuild', async setup(build): Promise { await bundlerPlugin.setup(build); - await orchestrionPlugin.setup(build); + if (!options?.buildTimeInstrumentation?.disable) { + await sentryOrchestrionPlugin(options).setup(build); + } }, }; } diff --git a/packages/node/src/bundler-plugin/rollup.ts b/packages/node/src/bundler-plugin/rollup.ts index e75ba75fe3f8..bf046938e25c 100644 --- a/packages/node/src/bundler-plugin/rollup.ts +++ b/packages/node/src/bundler-plugin/rollup.ts @@ -1,5 +1,6 @@ import { sentryRollupPlugin as sentryRollupBundlerPlugin } from '@sentry/bundler-plugins/rollup'; import type { SentryRollupPluginOptions as SentryRollupPluginOptionsBase } from '@sentry/bundler-plugins/rollup'; +import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/rollup'; export type SentryRollupPluginOptions = SentryRollupPluginOptionsBase & { @@ -7,6 +8,13 @@ export type SentryRollupPluginOptions = SentryRollupPluginOptionsBase & { * @ignore This is for internal use only when this plugin is consumed by a framework SDK */ instrumentations?: NonNullable[0]>['instrumentations']; + + /** + * Options related to automatic instrumentation of server-side dependencies at build time. + * + * Set `buildTimeInstrumentation.disable` to `true` to turn it off. + */ + buildTimeInstrumentation?: BuildTimeInstrumentationOptions; }; type RollupPlugin = ReturnType; @@ -27,5 +35,7 @@ type RollupPlugin = ReturnType; * ``` */ export function sentryRollupPlugin(options?: SentryRollupPluginOptions): RollupPlugin[] { - return [...sentryRollupBundlerPlugin(options), sentryOrchestrionPlugin(options)]; + const bundlerPlugins = sentryRollupBundlerPlugin(options); + const isOrchestrionDisabled = options?.buildTimeInstrumentation?.disable; + return [...bundlerPlugins, ...(isOrchestrionDisabled ? [] : [sentryOrchestrionPlugin(options)])]; } diff --git a/packages/node/src/bundler-plugin/vite.ts b/packages/node/src/bundler-plugin/vite.ts index a632dfa02f01..9b21ec0c11d1 100644 --- a/packages/node/src/bundler-plugin/vite.ts +++ b/packages/node/src/bundler-plugin/vite.ts @@ -1,5 +1,6 @@ import { sentryVitePlugin as sentryViteBundlerPlugin } from '@sentry/bundler-plugins/vite'; import type { SentryVitePluginOptions as SentryVitePluginOptionsBase } from '@sentry/bundler-plugins/vite'; +import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite'; export type SentryVitePluginOptions = SentryVitePluginOptionsBase & { @@ -7,6 +8,13 @@ export type SentryVitePluginOptions = SentryVitePluginOptionsBase & { * @ignore This is for internal use only when this plugin is consumed by a framework SDK */ instrumentations?: NonNullable[0]>['instrumentations']; + + /** + * Options related to automatic instrumentation of server-side dependencies at build time. + * + * Set `buildTimeInstrumentation.disable` to `true` to turn it off. + */ + buildTimeInstrumentation?: BuildTimeInstrumentationOptions; }; type VitePlugin = ReturnType; @@ -28,5 +36,7 @@ type VitePlugin = ReturnType; * ``` */ export function sentryVitePlugin(options?: SentryVitePluginOptions): VitePlugin[] { - return [...sentryViteBundlerPlugin(options), sentryOrchestrionPlugin(options)]; + const bundlerPlugins = sentryViteBundlerPlugin(options); + const isOrchestrionDisabled = options?.buildTimeInstrumentation?.disable; + return [...bundlerPlugins, ...(isOrchestrionDisabled ? [] : [sentryOrchestrionPlugin(options)])]; } diff --git a/packages/node/src/bundler-plugin/webpack.ts b/packages/node/src/bundler-plugin/webpack.ts index 06bfe6bbaede..1de9c15cf04f 100644 --- a/packages/node/src/bundler-plugin/webpack.ts +++ b/packages/node/src/bundler-plugin/webpack.ts @@ -1,5 +1,6 @@ import { sentryWebpackPlugin as sentryWebpackBundlerPlugin } from '@sentry/bundler-plugins/webpack'; import type { SentryWebpackPluginOptions as SentryWebpackPluginOptionsBase } from '@sentry/bundler-plugins/webpack'; +import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import { sentryOrchestrionWebpackPlugin } from '@sentry/server-utils/orchestrion/webpack'; export type SentryWebpackPluginOptions = SentryWebpackPluginOptionsBase & { @@ -7,6 +8,13 @@ export type SentryWebpackPluginOptions = SentryWebpackPluginOptionsBase & { * @ignore This is for internal use only when this plugin is consumed by a framework SDK */ instrumentations?: NonNullable[0]>['instrumentations']; + + /** + * Options related to automatic instrumentation of server-side dependencies at build time. + * + * Set `buildTimeInstrumentation.disable` to `true` to turn it off. + */ + buildTimeInstrumentation?: BuildTimeInstrumentationOptions; }; type WebpackCompiler = Parameters['apply']>[0]; @@ -29,12 +37,13 @@ export function sentryWebpackPlugin(options?: SentryWebpackPluginOptions): { apply: (compiler: WebpackCompiler) => void; } { const bundlerPlugin = sentryWebpackBundlerPlugin(options) as { apply: (compiler: WebpackCompiler) => void }; - const orchestrionPlugin = sentryOrchestrionWebpackPlugin(options) as { apply: (compiler: WebpackCompiler) => void }; return { apply(compiler: WebpackCompiler): void { bundlerPlugin.apply(compiler); - orchestrionPlugin.apply(compiler); + if (!options?.buildTimeInstrumentation?.disable) { + (sentryOrchestrionWebpackPlugin(options) as { apply: (compiler: WebpackCompiler) => void }).apply(compiler); + } }, }; } diff --git a/packages/node/test/bundler-plugin/bundler-plugin.test.ts b/packages/node/test/bundler-plugin/bundler-plugin.test.ts new file mode 100644 index 000000000000..6225e2764ce9 --- /dev/null +++ b/packages/node/test/bundler-plugin/bundler-plugin.test.ts @@ -0,0 +1,80 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { sentryEsbuildPlugin } from '../../src/bundler-plugin/esbuild'; +import { sentryRollupPlugin } from '../../src/bundler-plugin/rollup'; +import { sentryVitePlugin } from '../../src/bundler-plugin/vite'; +import { sentryWebpackPlugin } from '../../src/bundler-plugin/webpack'; + +const orchestrionVite = vi.fn(() => ({ name: 'sentry-orchestrion-vite' })); +const orchestrionRollup = vi.fn(() => ({ name: 'sentry-orchestrion-rollup' })); +const orchestrionEsbuildSetup = vi.fn(); +const orchestrionWebpackApply = vi.fn(); + +vi.mock('@sentry/bundler-plugins/vite', () => ({ sentryVitePlugin: () => [{ name: 'sentry-vite' }] })); +vi.mock('@sentry/bundler-plugins/rollup', () => ({ sentryRollupPlugin: () => [{ name: 'sentry-rollup' }] })); +vi.mock('@sentry/bundler-plugins/esbuild', () => ({ + sentryEsbuildPlugin: () => ({ name: 'sentry-esbuild', setup: vi.fn() }), +})); +vi.mock('@sentry/bundler-plugins/webpack', () => ({ sentryWebpackPlugin: () => ({ apply: vi.fn() }) })); + +vi.mock('@sentry/server-utils/orchestrion/vite', () => ({ sentryOrchestrionPlugin: () => orchestrionVite() })); +vi.mock('@sentry/server-utils/orchestrion/rollup', () => ({ sentryOrchestrionPlugin: () => orchestrionRollup() })); +vi.mock('@sentry/server-utils/orchestrion/esbuild', () => ({ + sentryOrchestrionPlugin: () => ({ name: 'sentry-orchestrion-esbuild', setup: orchestrionEsbuildSetup }), +})); +vi.mock('@sentry/server-utils/orchestrion/webpack', () => ({ + sentryOrchestrionWebpackPlugin: () => ({ apply: orchestrionWebpackApply }), +})); + +describe('@sentry/node bundler plugins', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + describe('by default (no opt-out)', () => { + it('vite includes the orchestrion plugin', () => { + const plugins = sentryVitePlugin(); + expect(plugins.map(p => p.name)).toContain('sentry-orchestrion-vite'); + }); + + it('rollup includes the orchestrion plugin', () => { + const plugins = sentryRollupPlugin(); + expect(plugins.map(p => p.name)).toContain('sentry-orchestrion-rollup'); + }); + + it('esbuild runs the orchestrion setup', async () => { + await sentryEsbuildPlugin().setup({} as never); + expect(orchestrionEsbuildSetup).toHaveBeenCalledTimes(1); + }); + + it('webpack applies the orchestrion plugin', () => { + sentryWebpackPlugin().apply({} as never); + expect(orchestrionWebpackApply).toHaveBeenCalledTimes(1); + }); + }); + + describe('with buildTimeInstrumentation.disable', () => { + const disabled = { buildTimeInstrumentation: { disable: true } }; + + it('vite omits the orchestrion plugin entirely', () => { + const plugins = sentryVitePlugin(disabled); + expect(plugins.map(p => p.name)).not.toContain('sentry-orchestrion-vite'); + expect(orchestrionVite).not.toHaveBeenCalled(); + }); + + it('rollup omits the orchestrion plugin entirely', () => { + const plugins = sentryRollupPlugin(disabled); + expect(plugins.map(p => p.name)).not.toContain('sentry-orchestrion-rollup'); + expect(orchestrionRollup).not.toHaveBeenCalled(); + }); + + it('esbuild never runs the orchestrion setup', async () => { + await sentryEsbuildPlugin(disabled).setup({} as never); + expect(orchestrionEsbuildSetup).not.toHaveBeenCalled(); + }); + + it('webpack never applies the orchestrion plugin', () => { + sentryWebpackPlugin(disabled).apply({} as never); + expect(orchestrionWebpackApply).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/packages/server-utils/src/orchestrion/bundler/esbuild.ts b/packages/server-utils/src/orchestrion/bundler/esbuild.ts index 7215c48c7f3c..6ebf18bbaa44 100644 --- a/packages/server-utils/src/orchestrion/bundler/esbuild.ts +++ b/packages/server-utils/src/orchestrion/bundler/esbuild.ts @@ -30,6 +30,11 @@ function matchesEsbuildExternal(entry: string, moduleName: string): boolean { * ``` */ export function sentryOrchestrionPlugin(options: PluginOptions = {}): Plugin { + if (options.buildTimeInstrumentation?.disable) { + // Inert plugin — no code transform, so no instrumentation lands in the bundle. + return { name: 'sentry-orchestrion-disabled', setup: () => undefined }; + } + const plugin = codeTransformer(orchestrionTransformOptions(options)); const moduleNames = instrumentedModuleNames(options.instrumentations); const setup = plugin.setup; diff --git a/packages/server-utils/src/orchestrion/bundler/options.ts b/packages/server-utils/src/orchestrion/bundler/options.ts index 6dea85440068..a6a53562d56a 100644 --- a/packages/server-utils/src/orchestrion/bundler/options.ts +++ b/packages/server-utils/src/orchestrion/bundler/options.ts @@ -1,3 +1,4 @@ +import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import type { InstrumentationConfig, CustomTransform } from '..'; import { SENTRY_INSTRUMENTATIONS } from '../config'; import { subscribeInjectionOptions } from './subscribeInjection'; @@ -8,6 +9,12 @@ export type PluginOptions = { * Additional instrumentations to include with the default instrumentation. */ instrumentations?: InstrumentationConfig[]; + /** + * Options related to automatic build-time instrumentation. Set + * `buildTimeInstrumentation.disable` to `true` to make the orchestrion plugin + * inert, so no `diagnostics_channel` instrumentation code is injected. + */ + buildTimeInstrumentation?: BuildTimeInstrumentationOptions; /** * Custom transforms that can be applied using the `transform` option in each `InstrumentationConfig`. */ diff --git a/packages/server-utils/src/orchestrion/bundler/rollup.ts b/packages/server-utils/src/orchestrion/bundler/rollup.ts index f9262d9bd46e..36d882b11b42 100644 --- a/packages/server-utils/src/orchestrion/bundler/rollup.ts +++ b/packages/server-utils/src/orchestrion/bundler/rollup.ts @@ -18,6 +18,11 @@ import { externalizedModulesWarning, orchestrionTransformOptions } from './optio * ``` */ export function sentryOrchestrionPlugin(options: PluginOptions = {}): Plugin { + if (options.buildTimeInstrumentation?.disable) { + // Inert plugin — no code transform, so no instrumentation lands in the bundle. + return { name: 'sentry-orchestrion-disabled' }; + } + const moduleNames = instrumentedModuleNames(options.instrumentations); return { diff --git a/packages/server-utils/src/orchestrion/bundler/vite.ts b/packages/server-utils/src/orchestrion/bundler/vite.ts index dc3426e9ba02..1454e45a3da2 100644 --- a/packages/server-utils/src/orchestrion/bundler/vite.ts +++ b/packages/server-utils/src/orchestrion/bundler/vite.ts @@ -19,6 +19,13 @@ import { externalEntryMatchesModule, externalizedModulesWarning, orchestrionTran * ``` */ export function sentryOrchestrionPlugin(options: PluginOptions = {}): Plugin { + if (options.buildTimeInstrumentation?.disable) { + // Return an inert plugin so SDKs that unconditionally push it into their + // plugin array can still opt out without any code transform, `noExternal` + // force-bundling, or injected diagnostics landing in the build. + return { name: 'sentry-orchestrion-disabled' }; + } + return { ...codeTransformer(orchestrionTransformOptions(options)), applyToEnvironment(environment) { diff --git a/packages/server-utils/src/orchestrion/bundler/webpack.ts b/packages/server-utils/src/orchestrion/bundler/webpack.ts index 01c97e26ffa6..7185bfad9be6 100644 --- a/packages/server-utils/src/orchestrion/bundler/webpack.ts +++ b/packages/server-utils/src/orchestrion/bundler/webpack.ts @@ -112,6 +112,11 @@ function fixupLoaderPath(compiler: Compiler): void { * transform, so a compilation warning is emitted for them. */ export function sentryOrchestrionWebpackPlugin(options: PluginOptions = {}): { apply(compiler: Compiler): void } { + if (options.buildTimeInstrumentation?.disable) { + // Inert plugin — no code transform, so no instrumentation lands in the bundle. + return { apply: () => undefined }; + } + const plugin = codeTransformerWebpack(orchestrionTransformOptions(options)); const moduleNames = instrumentedModuleNames(options.instrumentations); // The upstream plugin is a class instance, so `apply` is overridden in place diff --git a/packages/server-utils/test/orchestrion/bundler.test.ts b/packages/server-utils/test/orchestrion/bundler.test.ts index ee1c746fc6de..c84722fdaa37 100644 --- a/packages/server-utils/test/orchestrion/bundler.test.ts +++ b/packages/server-utils/test/orchestrion/bundler.test.ts @@ -139,6 +139,47 @@ describe('sentryOrchestrionPlugin (vite)', () => { }); }); +describe('buildTimeInstrumentation.disable', () => { + const disabled = { buildTimeInstrumentation: { disable: true } }; + + it('returns an inert vite plugin without the transform hooks', () => { + const plugin = vitePlugin(disabled); + + expect(plugin.name).toBe('sentry-orchestrion-disabled'); + expect(plugin.config).toBeUndefined(); + expect(plugin.configResolved).toBeUndefined(); + expect(plugin.applyToEnvironment).toBeUndefined(); + }); + + it('returns an inert rollup plugin without the transform hooks', () => { + const plugin = rollupPlugin(disabled); + + expect(plugin.name).toBe('sentry-orchestrion-disabled'); + expect(plugin.buildStart).toBeUndefined(); + expect((plugin as { transform?: unknown }).transform).toBeUndefined(); + }); + + it('returns an inert esbuild plugin whose setup is a no-op', () => { + const build = { initialOptions: {}, onStart: vi.fn() } as unknown as PluginBuild; + const plugin = esbuildPlugin(disabled); + + expect(plugin.name).toBe('sentry-orchestrion-disabled'); + expect(plugin.setup(build)).toBeUndefined(); + expect(build.onStart).not.toHaveBeenCalled(); + }); + + it('returns an inert webpack plugin whose apply is a no-op', () => { + const tap = vi.fn(); + const compiler = { + options: { externals: ['mysql'] }, + hooks: { thisCompilation: { tap } }, + } as unknown as Compiler; + + expect(() => sentryOrchestrionWebpackPlugin(disabled).apply(compiler)).not.toThrow(); + expect(tap).not.toHaveBeenCalled(); + }); +}); + describe('resolveOrchestrionRuntimeRequest', () => { it.each([ // Self-references — resolve through this package's own exports map to the CJS build. From 7250195a4c809d98f97ef3d763b87970170d8f0b Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Tue, 28 Jul 2026 16:06:46 +0200 Subject: [PATCH 2/2] simplify --- .../buildTimeOptionsBase.ts | 23 ++------ packages/core/src/shared-exports.ts | 1 - packages/node/src/bundler-plugin/esbuild.ts | 14 ++--- packages/node/src/bundler-plugin/rollup.ts | 12 ++-- packages/node/src/bundler-plugin/vite.ts | 12 ++-- packages/node/src/bundler-plugin/webpack.ts | 14 ++--- .../bundler-plugin/bundler-plugin.test.ts | 59 ++++++------------- .../src/orchestrion/bundler/esbuild.ts | 2 +- .../src/orchestrion/bundler/options.ts | 11 ++-- .../src/orchestrion/bundler/rollup.ts | 2 +- .../src/orchestrion/bundler/vite.ts | 2 +- .../src/orchestrion/bundler/webpack.ts | 2 +- .../test/orchestrion/bundler.test.ts | 4 +- 13 files changed, 61 insertions(+), 97 deletions(-) diff --git a/packages/core/src/build-time-plugins/buildTimeOptionsBase.ts b/packages/core/src/build-time-plugins/buildTimeOptionsBase.ts index 7a9fdf25eb04..eccfc3344f61 100644 --- a/packages/core/src/build-time-plugins/buildTimeOptionsBase.ts +++ b/packages/core/src/build-time-plugins/buildTimeOptionsBase.ts @@ -127,9 +127,13 @@ export interface BuildTimeOptionsBase { bundleSizeOptimizations?: BundleSizeOptimizationsOptions; /** - * Options related to automatic build-time instrumentation of server-side dependencies. + * Automatic instrumentation of server-side dependencies at build time. + * + * Set to `false` to turn it off. + * + * @default true */ - buildTimeInstrumentation?: BuildTimeInstrumentationOptions; + buildTimeInstrumentation?: boolean; /** * A key that is used to identify the application in the Sentry bundler plugins. @@ -141,21 +145,6 @@ export interface BuildTimeOptionsBase { applicationKey?: string; } -/** - * Options related to automatic instrumentation of server-side dependencies at build time. - * - * @internal Only meant for Sentry-internal SDK usage. - * @hidden - */ -export interface BuildTimeInstrumentationOptions { - /** - * If set to `true`, disables automatic instrumentation of server-side dependencies at build time. - * - * @default false - */ - disable?: boolean; -} - /** * Utility type for adding Vite plugin options to build-time configuration. * Use this type to extend your build-time options with Vite-specific plugin configurations. diff --git a/packages/core/src/shared-exports.ts b/packages/core/src/shared-exports.ts index d5acbb3fe357..700e65d2a974 100644 --- a/packages/core/src/shared-exports.ts +++ b/packages/core/src/shared-exports.ts @@ -520,7 +520,6 @@ export type { LegacyCSPReport } from './types/csp'; export type { SerializedLog, SerializedLogContainer } from './types/log'; export type { BuildTimeOptionsBase, - BuildTimeInstrumentationOptions, UnstableVitePluginOptions, UnstableRollupPluginOptions, UnstableWebpackPluginOptions, diff --git a/packages/node/src/bundler-plugin/esbuild.ts b/packages/node/src/bundler-plugin/esbuild.ts index 468c24a8dc44..c58515fa6a20 100644 --- a/packages/node/src/bundler-plugin/esbuild.ts +++ b/packages/node/src/bundler-plugin/esbuild.ts @@ -1,6 +1,5 @@ import { sentryEsbuildPlugin as sentryEsbuildBundlerPlugin } from '@sentry/bundler-plugins/esbuild'; import type { SentryEsbuildPluginOptions as SentryEsbuildPluginOptionsBase } from '@sentry/bundler-plugins/esbuild'; -import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/esbuild'; export type SentryEsbuildPluginOptions = SentryEsbuildPluginOptionsBase & { @@ -10,11 +9,13 @@ export type SentryEsbuildPluginOptions = SentryEsbuildPluginOptionsBase & { instrumentations?: NonNullable[0]>['instrumentations']; /** - * Options related to automatic instrumentation of server-side dependencies at build time. + * Automatic instrumentation of server-side dependencies at build time. * - * Set `buildTimeInstrumentation.disable` to `true` to turn it off. + * Set to `false` to turn it off. + * + * @default true */ - buildTimeInstrumentation?: BuildTimeInstrumentationOptions; + buildTimeInstrumentation?: boolean; }; type EsbuildPlugin = ReturnType; @@ -35,14 +36,13 @@ type EsbuildPlugin = ReturnType; */ export function sentryEsbuildPlugin(options?: SentryEsbuildPluginOptions): EsbuildPlugin { const bundlerPlugin = sentryEsbuildBundlerPlugin(options) as EsbuildPlugin; + const orchestrionPlugin = sentryOrchestrionPlugin(options); return { name: 'sentry-node-esbuild', async setup(build): Promise { await bundlerPlugin.setup(build); - if (!options?.buildTimeInstrumentation?.disable) { - await sentryOrchestrionPlugin(options).setup(build); - } + await orchestrionPlugin.setup(build); }, }; } diff --git a/packages/node/src/bundler-plugin/rollup.ts b/packages/node/src/bundler-plugin/rollup.ts index bf046938e25c..4258252e473c 100644 --- a/packages/node/src/bundler-plugin/rollup.ts +++ b/packages/node/src/bundler-plugin/rollup.ts @@ -1,6 +1,5 @@ import { sentryRollupPlugin as sentryRollupBundlerPlugin } from '@sentry/bundler-plugins/rollup'; import type { SentryRollupPluginOptions as SentryRollupPluginOptionsBase } from '@sentry/bundler-plugins/rollup'; -import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/rollup'; export type SentryRollupPluginOptions = SentryRollupPluginOptionsBase & { @@ -10,11 +9,13 @@ export type SentryRollupPluginOptions = SentryRollupPluginOptionsBase & { instrumentations?: NonNullable[0]>['instrumentations']; /** - * Options related to automatic instrumentation of server-side dependencies at build time. + * Automatic instrumentation of server-side dependencies at build time. * - * Set `buildTimeInstrumentation.disable` to `true` to turn it off. + * Set to `false` to turn it off. + * + * @default true */ - buildTimeInstrumentation?: BuildTimeInstrumentationOptions; + buildTimeInstrumentation?: boolean; }; type RollupPlugin = ReturnType; @@ -36,6 +37,5 @@ type RollupPlugin = ReturnType; */ export function sentryRollupPlugin(options?: SentryRollupPluginOptions): RollupPlugin[] { const bundlerPlugins = sentryRollupBundlerPlugin(options); - const isOrchestrionDisabled = options?.buildTimeInstrumentation?.disable; - return [...bundlerPlugins, ...(isOrchestrionDisabled ? [] : [sentryOrchestrionPlugin(options)])]; + return [...bundlerPlugins, sentryOrchestrionPlugin(options)]; } diff --git a/packages/node/src/bundler-plugin/vite.ts b/packages/node/src/bundler-plugin/vite.ts index 9b21ec0c11d1..81c5ce5f2aa9 100644 --- a/packages/node/src/bundler-plugin/vite.ts +++ b/packages/node/src/bundler-plugin/vite.ts @@ -1,6 +1,5 @@ import { sentryVitePlugin as sentryViteBundlerPlugin } from '@sentry/bundler-plugins/vite'; import type { SentryVitePluginOptions as SentryVitePluginOptionsBase } from '@sentry/bundler-plugins/vite'; -import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite'; export type SentryVitePluginOptions = SentryVitePluginOptionsBase & { @@ -10,11 +9,13 @@ export type SentryVitePluginOptions = SentryVitePluginOptionsBase & { instrumentations?: NonNullable[0]>['instrumentations']; /** - * Options related to automatic instrumentation of server-side dependencies at build time. + * Automatic instrumentation of server-side dependencies at build time. * - * Set `buildTimeInstrumentation.disable` to `true` to turn it off. + * Set to `false` to turn it off. + * + * @default true */ - buildTimeInstrumentation?: BuildTimeInstrumentationOptions; + buildTimeInstrumentation?: boolean; }; type VitePlugin = ReturnType; @@ -37,6 +38,5 @@ type VitePlugin = ReturnType; */ export function sentryVitePlugin(options?: SentryVitePluginOptions): VitePlugin[] { const bundlerPlugins = sentryViteBundlerPlugin(options); - const isOrchestrionDisabled = options?.buildTimeInstrumentation?.disable; - return [...bundlerPlugins, ...(isOrchestrionDisabled ? [] : [sentryOrchestrionPlugin(options)])]; + return [...bundlerPlugins, sentryOrchestrionPlugin(options)]; } diff --git a/packages/node/src/bundler-plugin/webpack.ts b/packages/node/src/bundler-plugin/webpack.ts index 1de9c15cf04f..fec2b4d1b254 100644 --- a/packages/node/src/bundler-plugin/webpack.ts +++ b/packages/node/src/bundler-plugin/webpack.ts @@ -1,6 +1,5 @@ import { sentryWebpackPlugin as sentryWebpackBundlerPlugin } from '@sentry/bundler-plugins/webpack'; import type { SentryWebpackPluginOptions as SentryWebpackPluginOptionsBase } from '@sentry/bundler-plugins/webpack'; -import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import { sentryOrchestrionWebpackPlugin } from '@sentry/server-utils/orchestrion/webpack'; export type SentryWebpackPluginOptions = SentryWebpackPluginOptionsBase & { @@ -10,11 +9,13 @@ export type SentryWebpackPluginOptions = SentryWebpackPluginOptionsBase & { instrumentations?: NonNullable[0]>['instrumentations']; /** - * Options related to automatic instrumentation of server-side dependencies at build time. + * Automatic instrumentation of server-side dependencies at build time. * - * Set `buildTimeInstrumentation.disable` to `true` to turn it off. + * Set to `false` to turn it off. + * + * @default true */ - buildTimeInstrumentation?: BuildTimeInstrumentationOptions; + buildTimeInstrumentation?: boolean; }; type WebpackCompiler = Parameters['apply']>[0]; @@ -37,13 +38,12 @@ export function sentryWebpackPlugin(options?: SentryWebpackPluginOptions): { apply: (compiler: WebpackCompiler) => void; } { const bundlerPlugin = sentryWebpackBundlerPlugin(options) as { apply: (compiler: WebpackCompiler) => void }; + const orchestrionPlugin = sentryOrchestrionWebpackPlugin(options) as { apply: (compiler: WebpackCompiler) => void }; return { apply(compiler: WebpackCompiler): void { bundlerPlugin.apply(compiler); - if (!options?.buildTimeInstrumentation?.disable) { - (sentryOrchestrionWebpackPlugin(options) as { apply: (compiler: WebpackCompiler) => void }).apply(compiler); - } + orchestrionPlugin.apply(compiler); }, }; } diff --git a/packages/node/test/bundler-plugin/bundler-plugin.test.ts b/packages/node/test/bundler-plugin/bundler-plugin.test.ts index 6225e2764ce9..dd50cffca04e 100644 --- a/packages/node/test/bundler-plugin/bundler-plugin.test.ts +++ b/packages/node/test/bundler-plugin/bundler-plugin.test.ts @@ -30,51 +30,26 @@ describe('@sentry/node bundler plugins', () => { vi.clearAllMocks(); }); - describe('by default (no opt-out)', () => { - it('vite includes the orchestrion plugin', () => { - const plugins = sentryVitePlugin(); - expect(plugins.map(p => p.name)).toContain('sentry-orchestrion-vite'); - }); - - it('rollup includes the orchestrion plugin', () => { - const plugins = sentryRollupPlugin(); - expect(plugins.map(p => p.name)).toContain('sentry-orchestrion-rollup'); - }); - - it('esbuild runs the orchestrion setup', async () => { - await sentryEsbuildPlugin().setup({} as never); - expect(orchestrionEsbuildSetup).toHaveBeenCalledTimes(1); - }); - - it('webpack applies the orchestrion plugin', () => { - sentryWebpackPlugin().apply({} as never); - expect(orchestrionWebpackApply).toHaveBeenCalledTimes(1); - }); + // The wrappers always wire in the orchestrion plugin. Opting out via + // `buildTimeInstrumentation: false` is handled inside the orchestrion plugin + // itself (covered in @sentry/server-utils), which returns an inert plugin. + it('vite includes the orchestrion plugin', () => { + const plugins = sentryVitePlugin(); + expect(plugins.map(p => p.name)).toContain('sentry-orchestrion-vite'); }); - describe('with buildTimeInstrumentation.disable', () => { - const disabled = { buildTimeInstrumentation: { disable: true } }; - - it('vite omits the orchestrion plugin entirely', () => { - const plugins = sentryVitePlugin(disabled); - expect(plugins.map(p => p.name)).not.toContain('sentry-orchestrion-vite'); - expect(orchestrionVite).not.toHaveBeenCalled(); - }); - - it('rollup omits the orchestrion plugin entirely', () => { - const plugins = sentryRollupPlugin(disabled); - expect(plugins.map(p => p.name)).not.toContain('sentry-orchestrion-rollup'); - expect(orchestrionRollup).not.toHaveBeenCalled(); - }); + it('rollup includes the orchestrion plugin', () => { + const plugins = sentryRollupPlugin(); + expect(plugins.map(p => p.name)).toContain('sentry-orchestrion-rollup'); + }); - it('esbuild never runs the orchestrion setup', async () => { - await sentryEsbuildPlugin(disabled).setup({} as never); - expect(orchestrionEsbuildSetup).not.toHaveBeenCalled(); - }); + it('esbuild runs the orchestrion setup', async () => { + await sentryEsbuildPlugin().setup({} as never); + expect(orchestrionEsbuildSetup).toHaveBeenCalledTimes(1); + }); - it('webpack never applies the orchestrion plugin', () => { - sentryWebpackPlugin(disabled).apply({} as never); - expect(orchestrionWebpackApply).not.toHaveBeenCalled(); - }); + it('webpack applies the orchestrion plugin', () => { + sentryWebpackPlugin().apply({} as never); + expect(orchestrionWebpackApply).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/server-utils/src/orchestrion/bundler/esbuild.ts b/packages/server-utils/src/orchestrion/bundler/esbuild.ts index 6ebf18bbaa44..a11f1154a111 100644 --- a/packages/server-utils/src/orchestrion/bundler/esbuild.ts +++ b/packages/server-utils/src/orchestrion/bundler/esbuild.ts @@ -30,7 +30,7 @@ function matchesEsbuildExternal(entry: string, moduleName: string): boolean { * ``` */ export function sentryOrchestrionPlugin(options: PluginOptions = {}): Plugin { - if (options.buildTimeInstrumentation?.disable) { + if (options.buildTimeInstrumentation === false) { // Inert plugin — no code transform, so no instrumentation lands in the bundle. return { name: 'sentry-orchestrion-disabled', setup: () => undefined }; } diff --git a/packages/server-utils/src/orchestrion/bundler/options.ts b/packages/server-utils/src/orchestrion/bundler/options.ts index a6a53562d56a..5610b394279e 100644 --- a/packages/server-utils/src/orchestrion/bundler/options.ts +++ b/packages/server-utils/src/orchestrion/bundler/options.ts @@ -1,4 +1,3 @@ -import type { BuildTimeInstrumentationOptions } from '@sentry/core'; import type { InstrumentationConfig, CustomTransform } from '..'; import { SENTRY_INSTRUMENTATIONS } from '../config'; import { subscribeInjectionOptions } from './subscribeInjection'; @@ -10,11 +9,13 @@ export type PluginOptions = { */ instrumentations?: InstrumentationConfig[]; /** - * Options related to automatic build-time instrumentation. Set - * `buildTimeInstrumentation.disable` to `true` to make the orchestrion plugin - * inert, so no `diagnostics_channel` instrumentation code is injected. + * Automatic instrumentation of server-side dependencies at build time. + * + * Set to `false` to make the plugin inert, so no instrumentation code is injected. + * + * @default true */ - buildTimeInstrumentation?: BuildTimeInstrumentationOptions; + buildTimeInstrumentation?: boolean; /** * Custom transforms that can be applied using the `transform` option in each `InstrumentationConfig`. */ diff --git a/packages/server-utils/src/orchestrion/bundler/rollup.ts b/packages/server-utils/src/orchestrion/bundler/rollup.ts index 36d882b11b42..ffa96ce86085 100644 --- a/packages/server-utils/src/orchestrion/bundler/rollup.ts +++ b/packages/server-utils/src/orchestrion/bundler/rollup.ts @@ -18,7 +18,7 @@ import { externalizedModulesWarning, orchestrionTransformOptions } from './optio * ``` */ export function sentryOrchestrionPlugin(options: PluginOptions = {}): Plugin { - if (options.buildTimeInstrumentation?.disable) { + if (options.buildTimeInstrumentation === false) { // Inert plugin — no code transform, so no instrumentation lands in the bundle. return { name: 'sentry-orchestrion-disabled' }; } diff --git a/packages/server-utils/src/orchestrion/bundler/vite.ts b/packages/server-utils/src/orchestrion/bundler/vite.ts index 1454e45a3da2..8c4cca0c5216 100644 --- a/packages/server-utils/src/orchestrion/bundler/vite.ts +++ b/packages/server-utils/src/orchestrion/bundler/vite.ts @@ -19,7 +19,7 @@ import { externalEntryMatchesModule, externalizedModulesWarning, orchestrionTran * ``` */ export function sentryOrchestrionPlugin(options: PluginOptions = {}): Plugin { - if (options.buildTimeInstrumentation?.disable) { + if (options.buildTimeInstrumentation === false) { // Return an inert plugin so SDKs that unconditionally push it into their // plugin array can still opt out without any code transform, `noExternal` // force-bundling, or injected diagnostics landing in the build. diff --git a/packages/server-utils/src/orchestrion/bundler/webpack.ts b/packages/server-utils/src/orchestrion/bundler/webpack.ts index 7185bfad9be6..a44f2ffa5e34 100644 --- a/packages/server-utils/src/orchestrion/bundler/webpack.ts +++ b/packages/server-utils/src/orchestrion/bundler/webpack.ts @@ -112,7 +112,7 @@ function fixupLoaderPath(compiler: Compiler): void { * transform, so a compilation warning is emitted for them. */ export function sentryOrchestrionWebpackPlugin(options: PluginOptions = {}): { apply(compiler: Compiler): void } { - if (options.buildTimeInstrumentation?.disable) { + if (options.buildTimeInstrumentation === false) { // Inert plugin — no code transform, so no instrumentation lands in the bundle. return { apply: () => undefined }; } diff --git a/packages/server-utils/test/orchestrion/bundler.test.ts b/packages/server-utils/test/orchestrion/bundler.test.ts index c84722fdaa37..6fae3f2e92a3 100644 --- a/packages/server-utils/test/orchestrion/bundler.test.ts +++ b/packages/server-utils/test/orchestrion/bundler.test.ts @@ -139,8 +139,8 @@ describe('sentryOrchestrionPlugin (vite)', () => { }); }); -describe('buildTimeInstrumentation.disable', () => { - const disabled = { buildTimeInstrumentation: { disable: true } }; +describe('buildTimeInstrumentation: false', () => { + const disabled = { buildTimeInstrumentation: false }; it('returns an inert vite plugin without the transform hooks', () => { const plugin = vitePlugin(disabled);