diff --git a/package.json b/package.json index 62a78b6e..85e45b91 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,6 @@ }, "volta": { "node": "18.20.8", - "yarn": "1.22.19" + "yarn": "1.22.22" } } diff --git a/packages/bundler-plugin-core/src/build-plugin-manager.ts b/packages/bundler-plugin-core/src/build-plugin-manager.ts index 4ae62419..a014a934 100644 --- a/packages/bundler-plugin-core/src/build-plugin-manager.ts +++ b/packages/bundler-plugin-core/src/build-plugin-manager.ts @@ -124,6 +124,10 @@ export function createSentryBuildPluginManager( * E.g. `webpack` or `nextjs` or `turbopack` */ buildTool: string; + /** + * E.g. `5` for webpack v5 or `4` for Rollup v4 + */ + buildToolMajorVersion?: string; /** * E.g. `[sentry-webpack-plugin]` or `[@sentry/nextjs]` */ @@ -195,7 +199,8 @@ export function createSentryBuildPluginManager( const { sentryScope, sentryClient } = createSentryInstance( options, shouldSendTelemetry, - bundlerPluginMetaContext.buildTool + bundlerPluginMetaContext.buildTool, + bundlerPluginMetaContext.buildToolMajorVersion ); const { release, environment = DEFAULT_ENVIRONMENT } = sentryClient.getOptions(); diff --git a/packages/bundler-plugin-core/src/index.ts b/packages/bundler-plugin-core/src/index.ts index a31e4215..aeeffe44 100644 --- a/packages/bundler-plugin-core/src/index.ts +++ b/packages/bundler-plugin-core/src/index.ts @@ -47,6 +47,7 @@ interface SentryUnpluginFactoryOptions { webpack_forceExitOnBuildComplete?: boolean ) => UnpluginOptions; bundleSizeOptimizationsPlugin: (buildFlags: SentrySDKBuildFlags) => UnpluginOptions; + getBundlerMajorVersion?: () => string | undefined; } /** @@ -57,6 +58,7 @@ export function sentryUnpluginFactory({ componentNameAnnotatePlugin, debugIdUploadPlugin, bundleSizeOptimizationsPlugin, + getBundlerMajorVersion, }: SentryUnpluginFactoryOptions): UnpluginInstance { return createUnplugin((userOptions = {}, unpluginMetaContext) => { const sentryBuildPluginManager = createSentryBuildPluginManager(userOptions, { @@ -64,6 +66,7 @@ export function sentryUnpluginFactory({ userOptions._metaOptions?.loggerPrefixOverride ?? `[sentry-${unpluginMetaContext.framework}-plugin]`, buildTool: unpluginMetaContext.framework, + buildToolMajorVersion: getBundlerMajorVersion?.(), }); const { diff --git a/packages/bundler-plugin-core/src/options-mapping.ts b/packages/bundler-plugin-core/src/options-mapping.ts index 762720df..c7096f1d 100644 --- a/packages/bundler-plugin-core/src/options-mapping.ts +++ b/packages/bundler-plugin-core/src/options-mapping.ts @@ -76,7 +76,6 @@ export type NormalizedOptions = { _metaOptions: { telemetry: { metaFramework: string | undefined; - bundlerMajorVersion: string | undefined; }; }; applicationKey: string | undefined; diff --git a/packages/bundler-plugin-core/src/sentry/telemetry.ts b/packages/bundler-plugin-core/src/sentry/telemetry.ts index 7f48ec4a..e0d0e046 100644 --- a/packages/bundler-plugin-core/src/sentry/telemetry.ts +++ b/packages/bundler-plugin-core/src/sentry/telemetry.ts @@ -14,7 +14,8 @@ const stackParser = createStackParser(nodeStackLineParser()); export function createSentryInstance( options: NormalizedOptions, shouldSendTelemetry: Promise, - buildTool: string + buildTool: string, + buildToolMajorVersion: string | undefined ): { sentryScope: Scope; sentryClient: Client } { const clientOptions: ServerRuntimeClientOptions = { platform: "node", @@ -56,7 +57,7 @@ export function createSentryInstance( const scope = new Scope(); scope.setClient(client); - setTelemetryDataOnScope(options, scope, buildTool); + setTelemetryDataOnScope(options, scope, buildTool, buildToolMajorVersion); return { sentryScope: scope, sentryClient: client }; } @@ -64,7 +65,8 @@ export function createSentryInstance( export function setTelemetryDataOnScope( options: NormalizedOptions, scope: Scope, - buildTool: string + buildTool: string, + buildToolMajorVersion?: string ): void { const { org, project, release, errorHandler, sourcemaps, reactComponentAnnotation } = options; @@ -111,7 +113,9 @@ export function setTelemetryDataOnScope( bundler: buildTool, }); - scope.setTag("bundler-major-version", options._metaOptions.telemetry.bundlerMajorVersion); + if (buildToolMajorVersion) { + scope.setTag("bundler-major-version", buildToolMajorVersion); + } scope.setUser({ id: org }); } diff --git a/packages/integration-tests/fixtures/telemetry/telemetry.test.ts b/packages/integration-tests/fixtures/telemetry/telemetry.test.ts index 3f6d8963..2eaee9ca 100644 --- a/packages/integration-tests/fixtures/telemetry/telemetry.test.ts +++ b/packages/integration-tests/fixtures/telemetry/telemetry.test.ts @@ -112,6 +112,7 @@ test("rollup bundle telemetry", async () => { "react-annotate": false, "meta-framework": "none", "application-key-set": false, + "bundler-major-version": "2", bundler: "rollup", }), sdk: expect.objectContaining({ diff --git a/packages/integration-tests/jest.config.js b/packages/integration-tests/jest.config.js index 160178bb..73ed904f 100644 --- a/packages/integration-tests/jest.config.js +++ b/packages/integration-tests/jest.config.js @@ -3,4 +3,5 @@ module.exports = { transform: { "^.+\\.(t|j)sx?$": ["@swc/jest"], }, + transformIgnorePatterns: ["!node_modules/"], }; diff --git a/packages/rollup-plugin/src/index.ts b/packages/rollup-plugin/src/index.ts index f29ac5f0..802451bc 100644 --- a/packages/rollup-plugin/src/index.ts +++ b/packages/rollup-plugin/src/index.ts @@ -9,6 +9,7 @@ import { createComponentNameAnnotateHooks, Logger, } from "@sentry/bundler-plugin-core"; +import { createRequire } from "node:module"; import type { UnpluginOptions } from "unplugin"; function rollupComponentNameAnnotatePlugin( @@ -48,11 +49,26 @@ function rollupBundleSizeOptimizationsPlugin( }; } +function getRollupMajorVersion(): string | undefined { + try { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - Rollup already transpiles this for us + const req = createRequire(import.meta.url); + const rollup = req("rollup") as { VERSION?: string }; + return rollup.VERSION?.split(".")[0]; + } catch (err) { + // do nothing, we'll just not report a version + } + + return undefined; +} + const sentryUnplugin = sentryUnpluginFactory({ injectionPlugin: rollupInjectionPlugin, componentNameAnnotatePlugin: rollupComponentNameAnnotatePlugin, debugIdUploadPlugin: rollupDebugIdUploadPlugin, bundleSizeOptimizationsPlugin: rollupBundleSizeOptimizationsPlugin, + getBundlerMajorVersion: getRollupMajorVersion, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/vite-plugin/src/index.ts b/packages/vite-plugin/src/index.ts index 51a79602..8b7f323a 100644 --- a/packages/vite-plugin/src/index.ts +++ b/packages/vite-plugin/src/index.ts @@ -9,6 +9,7 @@ import { createComponentNameAnnotateHooks, Logger, } from "@sentry/bundler-plugin-core"; +import { createRequire } from "node:module"; import { UnpluginOptions, VitePlugin } from "unplugin"; function viteInjectionPlugin(injectionCode: CodeInjection, debugIds: boolean): UnpluginOptions { @@ -52,11 +53,26 @@ function viteBundleSizeOptimizationsPlugin( }; } +function getViteMajorVersion(): string | undefined { + try { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - Rollup already transpiles this for us + const req = createRequire(import.meta.url); + const vite = req("vite") as { version?: string }; + return vite.version?.split(".")[0]; + } catch (err) { + // do nothing, we'll just not report a version + } + + return undefined; +} + const sentryUnplugin = sentryUnpluginFactory({ injectionPlugin: viteInjectionPlugin, componentNameAnnotatePlugin: viteComponentNameAnnotatePlugin, debugIdUploadPlugin: viteDebugIdUploadPlugin, bundleSizeOptimizationsPlugin: viteBundleSizeOptimizationsPlugin, + getBundlerMajorVersion: getViteMajorVersion, }); export const sentryVitePlugin = (options?: Options): VitePlugin[] => { diff --git a/packages/webpack-plugin/src/index.ts b/packages/webpack-plugin/src/index.ts index cb4683e1..9b1bfa24 100644 --- a/packages/webpack-plugin/src/index.ts +++ b/packages/webpack-plugin/src/index.ts @@ -8,42 +8,14 @@ const BannerPlugin = webpack4or5?.BannerPlugin || webpack4or5?.default?.BannerPl const DefinePlugin = webpack4or5?.DefinePlugin || webpack4or5?.default?.DefinePlugin; -// Detect webpack major version for telemetry (helps differentiate webpack 4 vs 5 usage) -function getWebpackMajorVersion(): string | undefined { - try { - const webpack = webpack4or5 as unknown as - | { version?: string; default?: { version?: string } } - | undefined; - const version = webpack?.version ?? webpack?.default?.version; - const webpackMajorVersion = version?.split(".")[0]; // "4" or "5" - return webpackMajorVersion; - } catch (error) { - return undefined; - } -} - -const webpackMajorVersion = getWebpackMajorVersion(); - const sentryUnplugin = sentryWebpackUnpluginFactory({ BannerPlugin, DefinePlugin, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any -export const sentryWebpackPlugin: (options?: SentryWebpackPluginOptions) => any = (options) => { - const enhancedOptions: SentryWebpackPluginOptions = { - ...options, - _metaOptions: { - ...options?._metaOptions, - telemetry: { - ...options?._metaOptions?.telemetry, - bundlerMajorVersion: - options?._metaOptions?.telemetry?.bundlerMajorVersion ?? webpackMajorVersion, - }, - }, - }; - return sentryUnplugin.webpack(enhancedOptions); -}; +export const sentryWebpackPlugin: (options?: SentryWebpackPluginOptions) => any = + sentryUnplugin.webpack; export { sentryCliBinaryExists } from "@sentry/bundler-plugin-core"; diff --git a/packages/webpack-plugin/src/webpack4and5.ts b/packages/webpack-plugin/src/webpack4and5.ts index f8054590..5ad81eaa 100644 --- a/packages/webpack-plugin/src/webpack4and5.ts +++ b/packages/webpack-plugin/src/webpack4and5.ts @@ -8,6 +8,7 @@ import { CodeInjection, getDebugIdSnippet, } from "@sentry/bundler-plugin-core"; +import { createRequire } from "node:module"; import * as path from "path"; import { UnpluginOptions } from "unplugin"; import { v4 as uuidv4 } from "uuid"; @@ -150,6 +151,21 @@ function webpackDebugIdUploadPlugin( }; } +// Detect webpack major version for telemetry (helps differentiate webpack 4 vs 5 usage) +function getWebpackMajorVersion(): string | undefined { + try { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - Rollup already transpiles this for us + const req = createRequire(import.meta.url); + const webpack = req("webpack") as { version?: string; default?: { version?: string } }; + const version = webpack?.version ?? webpack?.default?.version; + const webpackMajorVersion = version?.split(".")[0]; // "4" or "5" + return webpackMajorVersion; + } catch (error) { + return undefined; + } +} + /** * The factory function accepts BannerPlugin and DefinePlugin classes in * order to avoid direct dependencies on webpack. @@ -170,6 +186,7 @@ export function sentryWebpackUnpluginFactory({ componentNameAnnotatePlugin: webpackComponentNameAnnotatePlugin(), debugIdUploadPlugin: webpackDebugIdUploadPlugin, bundleSizeOptimizationsPlugin: webpackBundleSizeOptimizationsPlugin(DefinePlugin), + getBundlerMajorVersion: getWebpackMajorVersion, }); }