From 698217619f058de78310c6292bee415436697ecd Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Fri, 23 Jan 2026 13:22:37 +0100 Subject: [PATCH] feat: Combine injection snippets --- packages/bundler-plugin-core/src/index.ts | 33 +++++----- packages/bundler-plugin-core/src/utils.ts | 61 ++++++++++++++----- .../test/__snapshots__/utils.test.ts.snap | 4 +- .../bundler-plugin-core/test/index.test.ts | 29 +++++---- .../bundler-plugin-core/test/utils.test.ts | 8 +-- packages/esbuild-plugin/src/index.ts | 2 +- packages/rollup-plugin/src/index.ts | 3 +- packages/vite-plugin/src/index.ts | 3 +- packages/webpack-plugin/src/webpack4and5.ts | 13 ++-- 9 files changed, 99 insertions(+), 57 deletions(-) diff --git a/packages/bundler-plugin-core/src/index.ts b/packages/bundler-plugin-core/src/index.ts index 555de622..9b4175fe 100644 --- a/packages/bundler-plugin-core/src/index.ts +++ b/packages/bundler-plugin-core/src/index.ts @@ -12,6 +12,7 @@ import { createDebugIdUploadFunction } from "./debug-id-upload"; import { Logger } from "./logger"; import { Options, SentrySDKBuildFlags } from "./types"; import { + CodeInjection, containsOnlyImports, generateGlobalInjectorCode, generateModuleMetadataInjectorCode, @@ -21,7 +22,7 @@ import { } from "./utils"; type InjectionPlugin = ( - injectionCode: string, + injectionCode: CodeInjection, debugIds: boolean, logger: Logger ) => UnpluginOptions; @@ -101,7 +102,7 @@ export function sentryUnpluginFactory({ plugins.push(bundleSizeOptimizationsPlugin(bundleSizeOptimizationReplacementValues)); } - let injectionCode = ""; + const injectionCode = new CodeInjection(); if (!options.release.inject) { logger.debug( @@ -117,24 +118,24 @@ export function sentryUnpluginFactory({ injectBuildInformation: options._experiments.injectBuildInformation || false, }); if (typeof injectionPlugin !== "function") { - plugins.push(injectionPlugin.releaseInjectionPlugin(code)); + plugins.push(injectionPlugin.releaseInjectionPlugin(code.code())); } else { - injectionCode += code; + injectionCode.append(code); } } if (Object.keys(sentryBuildPluginManager.bundleMetadata).length > 0) { const code = generateModuleMetadataInjectorCode(sentryBuildPluginManager.bundleMetadata); if (typeof injectionPlugin !== "function") { - plugins.push(injectionPlugin.moduleMetadataInjectionPlugin(code)); + plugins.push(injectionPlugin.moduleMetadataInjectionPlugin(code.code())); } else { - injectionCode += code; + injectionCode.append(code); } } if ( typeof injectionPlugin === "function" && - (injectionCode !== "" || options.sourcemaps?.disable !== true) + (!injectionCode.isEmpty() || options.sourcemaps?.disable !== true) ) { plugins.push(injectionPlugin(injectionCode, options.sourcemaps?.disable !== true, logger)); } @@ -286,7 +287,7 @@ export function createRollupBundleSizeOptimizationHooks(replacementValues: Sentr } export function createRollupInjectionHooks( - injectionCode: string, + injectionCode: CodeInjection, debugIds: boolean ): { renderChunk: RenderChunkHook; @@ -302,7 +303,7 @@ export function createRollupInjectionHooks( return null; } - let codeToInject = injectionCode; + const codeToInject = injectionCode.clone(); if (debugIds) { // Check if a debug ID has already been injected to avoid duplicate injection (e.g. by another plugin or Sentry CLI) @@ -316,7 +317,7 @@ export function createRollupInjectionHooks( ) ) { const debugId = stringToUUID(code); // generate a deterministic debug ID - codeToInject += getDebugIdSnippet(debugId); + codeToInject.append(getDebugIdSnippet(debugId)); } } @@ -325,12 +326,12 @@ export function createRollupInjectionHooks( if (match) { // Add injected code after any comments or "use strict" at the beginning of the bundle. - ms.appendLeft(match.length, codeToInject); + ms.appendLeft(match.length, codeToInject.code()); } else { // ms.replace() doesn't work when there is an empty string match (which happens if // there is neither, a comment, nor a "use strict" at the top of the chunk) so we // need this special case here. - ms.prepend(codeToInject); + ms.prepend(codeToInject.code()); } return { @@ -447,11 +448,13 @@ export function createComponentNameAnnotateHooks(ignoredComponents?: string[]): }; } -export function getDebugIdSnippet(debugId: string): string { - return `;{try{(function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="${debugId}",e._sentryDebugIdIdentifier="sentry-dbid-${debugId}");})();}catch(e){}};`; +export function getDebugIdSnippet(debugId: string): CodeInjection { + return new CodeInjection( + `var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="${debugId}",e._sentryDebugIdIdentifier="sentry-dbid-${debugId}");` + ); } export type { Logger } from "./logger"; export type { Options, SentrySDKBuildFlags } from "./types"; -export { replaceBooleanFlagsInCode, stringToUUID } from "./utils"; +export { CodeInjection, replaceBooleanFlagsInCode, stringToUUID } from "./utils"; export { createSentryBuildPluginManager } from "./build-plugin-manager"; diff --git a/packages/bundler-plugin-core/src/utils.ts b/packages/bundler-plugin-core/src/utils.ts index 925d83f6..9726895e 100644 --- a/packages/bundler-plugin-core/src/utils.ts +++ b/packages/bundler-plugin-core/src/utils.ts @@ -311,12 +311,8 @@ export function generateGlobalInjectorCode({ }: { release: string; injectBuildInformation: boolean; -}): string { - // The code below is mostly ternary operators because it saves bundle size. - // The checks are to support as many environments as possible. (Node.js, Browser, webworkers, etc.) - let code = `!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};`; - - code += `e.SENTRY_RELEASE={id:${JSON.stringify(release)}};`; +}): CodeInjection { + let code = `e.SENTRY_RELEASE={id:${JSON.stringify(release)}};`; if (injectBuildInformation) { const buildInfo = getBuildInformation(); @@ -324,20 +320,18 @@ export function generateGlobalInjectorCode({ code += `e.SENTRY_BUILD_INFO=${JSON.stringify(buildInfo)};`; } - code += "}catch(e){}}();"; - - return code; + return new CodeInjection(code); } // eslint-disable-next-line @typescript-eslint/no-explicit-any -export function generateModuleMetadataInjectorCode(metadata: any): string { - // The code below is mostly ternary operators because it saves bundle size. - // The checks are to support as many environments as possible. (Node.js, Browser, webworkers, etc.) +export function generateModuleMetadataInjectorCode(metadata: any): CodeInjection { // We are merging the metadata objects in case modules are bundled twice with the plugin // Use try-catch to avoid issues when bundlers rename global variables like 'window' to 'k' - return `!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};e._sentryModuleMetadata=e._sentryModuleMetadata||{},e._sentryModuleMetadata[(new e.Error).stack]=function(e){for(var n=1;n { it("returns the debugId injection snippet for a passed debugId", () => { const snippet = getDebugIdSnippet("1234"); - expect(snippet).toMatchInlineSnapshot( - `";{try{(function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"1234\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-1234\\");})();}catch(e){}};"` + expect(snippet.code()).toMatchInlineSnapshot( + `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"1234\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-1234\\");}catch(e){}}();"` ); }); }); @@ -143,7 +143,12 @@ app.mount('#app'); }); describe("createRollupInjectionHooks", () => { - const hooks = createRollupInjectionHooks("", true); + const inject = new CodeInjection(); + const hooks = createRollupInjectionHooks(inject, true); + + beforeEach(() => { + inject.clear(); + }); describe("renderChunk", () => { it("should inject debug ID into clean JavaScript files", () => { @@ -152,7 +157,7 @@ describe("createRollupInjectionHooks", () => { expect(result).not.toBeNull(); expect(result?.code).toMatchInlineSnapshot( - `";{try{(function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"d4309f93-5358-4ae1-bcf0-3813aa590eb5\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-d4309f93-5358-4ae1-bcf0-3813aa590eb5\\");})();}catch(e){}};console.log(\\"Hello world\\");"` + `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"d4309f93-5358-4ae1-bcf0-3813aa590eb5\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-d4309f93-5358-4ae1-bcf0-3813aa590eb5\\");}catch(e){}}();console.log(\\"Hello world\\");"` ); }); @@ -162,7 +167,7 @@ describe("createRollupInjectionHooks", () => { expect(result).not.toBeNull(); expect(result?.code).toMatchInlineSnapshot(` - "\\"use strict\\";;{try{(function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"79a86c07-8ecc-4367-82b0-88cf822f2d41\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-79a86c07-8ecc-4367-82b0-88cf822f2d41\\");})();}catch(e){}}; + "\\"use strict\\";!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"79a86c07-8ecc-4367-82b0-88cf822f2d41\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-79a86c07-8ecc-4367-82b0-88cf822f2d41\\");}catch(e){}}(); console.log(\\"Hello world\\");" `); }); @@ -179,7 +184,7 @@ describe("createRollupInjectionHooks", () => { expect(result).not.toBeNull(); expect(result?.code).toMatchInlineSnapshot( - `";{try{(function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"b80112c0-6818-486d-96f0-185c023439b4\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-b80112c0-6818-486d-96f0-185c023439b4\\");})();}catch(e){}};console.log(\\"test\\");"` + `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"b80112c0-6818-486d-96f0-185c023439b4\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-b80112c0-6818-486d-96f0-185c023439b4\\");}catch(e){}}();console.log(\\"test\\");"` ); }); @@ -263,7 +268,7 @@ export * from './moduleC.js';`, }); expect(result).not.toBeNull(); expect(result?.code).toMatchInlineSnapshot( - `";{try{(function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"c4c89e04-3658-4874-b25b-07e638185091\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-c4c89e04-3658-4874-b25b-07e638185091\\");})();}catch(e){}};function main() { console.log(\\"hello\\"); }"` + `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"c4c89e04-3658-4874-b25b-07e638185091\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-c4c89e04-3658-4874-b25b-07e638185091\\");}catch(e){}}();function main() { console.log(\\"hello\\"); }"` ); }); @@ -274,7 +279,7 @@ export * from './moduleC.js';`, }); expect(result).not.toBeNull(); expect(result?.code).toMatchInlineSnapshot( - `";{try{(function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"43e69766-1963-49f2-a291-ff8de60cc652\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-43e69766-1963-49f2-a291-ff8de60cc652\\");})();}catch(e){}};const x = 42;"` + `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"43e69766-1963-49f2-a291-ff8de60cc652\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-43e69766-1963-49f2-a291-ff8de60cc652\\");}catch(e){}}();const x = 42;"` ); }); @@ -294,7 +299,7 @@ bootstrap();`; }); expect(result).not.toBeNull(); expect(result?.code).toMatchInlineSnapshot(` - ";{try{(function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"d0c4524b-496e-45a4-9852-7558d043ba3c\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-d0c4524b-496e-45a4-9852-7558d043ba3c\\");})();}catch(e){}};import { initApp } from './app.js'; + "!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"d0c4524b-496e-45a4-9852-7558d043ba3c\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-d0c4524b-496e-45a4-9852-7558d043ba3c\\");}catch(e){}}();import { initApp } from './app.js'; const config = { debug: true }; @@ -313,7 +318,7 @@ bootstrap();`; ); expect(result).not.toBeNull(); expect(result?.code).toMatchInlineSnapshot(` - ";{try{(function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"28f0bbaa-9aeb-40c4-98c9-4e44f1d4e175\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-28f0bbaa-9aeb-40c4-98c9-4e44f1d4e175\\");})();}catch(e){}};import './polyfills.js'; + "!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"28f0bbaa-9aeb-40c4-98c9-4e44f1d4e175\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-28f0bbaa-9aeb-40c4-98c9-4e44f1d4e175\\");}catch(e){}}();import './polyfills.js'; import { init } from './app.js'; init();" @@ -324,7 +329,7 @@ bootstrap();`; const result = hooks.renderChunk(`console.log("Hello");`, { fileName: "bundle.js" }); expect(result).not.toBeNull(); expect(result?.code).toMatchInlineSnapshot( - `";{try{(function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"79f18a7f-ca16-4168-9797-906c82058367\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-79f18a7f-ca16-4168-9797-906c82058367\\");})();}catch(e){}};console.log(\\"Hello\\");"` + `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"79f18a7f-ca16-4168-9797-906c82058367\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-79f18a7f-ca16-4168-9797-906c82058367\\");}catch(e){}}();console.log(\\"Hello\\");"` ); }); }); diff --git a/packages/bundler-plugin-core/test/utils.test.ts b/packages/bundler-plugin-core/test/utils.test.ts index bcb5e4cc..5cd1ef4e 100644 --- a/packages/bundler-plugin-core/test/utils.test.ts +++ b/packages/bundler-plugin-core/test/utils.test.ts @@ -228,7 +228,7 @@ describe("generateGlobalInjectorCode", () => { injectBuildInformation: false, }); - expect(generatedCode).toMatchSnapshot(); + expect(generatedCode.code()).toMatchSnapshot(); }); it("generates code with release and build information", () => { @@ -249,14 +249,14 @@ describe("generateGlobalInjectorCode", () => { injectBuildInformation: true, }); - expect(generatedCode).toMatchSnapshot(); + expect(generatedCode.code()).toMatchSnapshot(); }); }); describe("generateModuleMetadataInjectorCode", () => { it("generates code with empty metadata object", () => { const generatedCode = generateModuleMetadataInjectorCode({}); - expect(generatedCode).toMatchSnapshot(); + expect(generatedCode.code()).toMatchSnapshot(); }); it("generates code with metadata object", () => { @@ -268,7 +268,7 @@ describe("generateModuleMetadataInjectorCode", () => { bar: "baz", }, }); - expect(generatedCode).toMatchSnapshot(); + expect(generatedCode.code()).toMatchSnapshot(); }); }); diff --git a/packages/esbuild-plugin/src/index.ts b/packages/esbuild-plugin/src/index.ts index 4b2e8270..58ab0d81 100644 --- a/packages/esbuild-plugin/src/index.ts +++ b/packages/esbuild-plugin/src/index.ts @@ -167,7 +167,7 @@ function esbuildDebugIdInjectionPlugin(logger: Logger): UnpluginOptions { return { loader: "js", pluginName, - contents: getDebugIdSnippet(uuidv4()), + contents: getDebugIdSnippet(uuidv4()).code(), }; }); }, diff --git a/packages/rollup-plugin/src/index.ts b/packages/rollup-plugin/src/index.ts index 30ad55fd..c6b97594 100644 --- a/packages/rollup-plugin/src/index.ts +++ b/packages/rollup-plugin/src/index.ts @@ -1,4 +1,5 @@ import { + CodeInjection, sentryUnpluginFactory, Options, createRollupInjectionHooks, @@ -17,7 +18,7 @@ function rollupComponentNameAnnotatePlugin(ignoredComponents?: string[]): Unplug }; } -function rollupInjectionPlugin(injectionCode: string, debugIds: boolean): UnpluginOptions { +function rollupInjectionPlugin(injectionCode: CodeInjection, debugIds: boolean): UnpluginOptions { return { name: "sentry-rollup-injection-plugin", rollup: createRollupInjectionHooks(injectionCode, debugIds), diff --git a/packages/vite-plugin/src/index.ts b/packages/vite-plugin/src/index.ts index a6bc4ac7..b378fa9a 100644 --- a/packages/vite-plugin/src/index.ts +++ b/packages/vite-plugin/src/index.ts @@ -1,4 +1,5 @@ import { + CodeInjection, sentryUnpluginFactory, Options, createRollupInjectionHooks, @@ -10,7 +11,7 @@ import { } from "@sentry/bundler-plugin-core"; import { UnpluginOptions, VitePlugin } from "unplugin"; -function viteInjectionPlugin(injectionCode: string, debugIds: boolean): UnpluginOptions { +function viteInjectionPlugin(injectionCode: CodeInjection, debugIds: boolean): UnpluginOptions { return { name: "sentry-vite-injection-plugin", // run `post` to avoid tripping up @rollup/plugin-commonjs when cjs is used diff --git a/packages/webpack-plugin/src/webpack4and5.ts b/packages/webpack-plugin/src/webpack4and5.ts index aaf8bf5f..48ddf1e9 100644 --- a/packages/webpack-plugin/src/webpack4and5.ts +++ b/packages/webpack-plugin/src/webpack4and5.ts @@ -1,11 +1,12 @@ import { - getDebugIdSnippet, Options, sentryUnpluginFactory, stringToUUID, SentrySDKBuildFlags, createComponentNameAnnotateHooks, Logger, + CodeInjection, + getDebugIdSnippet, } from "@sentry/bundler-plugin-core"; import * as path from "path"; import { UnpluginOptions } from "unplugin"; @@ -35,8 +36,8 @@ type UnsafeDefinePlugin = { function webpackInjectionPlugin( UnsafeBannerPlugin: UnsafeBannerPlugin | undefined -): (injectionCode: string, debugIds: boolean) => UnpluginOptions { - return (injectionCode: string, debugIds: boolean): UnpluginOptions => ({ +): (injectionCode: CodeInjection, debugIds: boolean) => UnpluginOptions { + return (injectionCode: CodeInjection, debugIds: boolean): UnpluginOptions => ({ name: "sentry-webpack-injection-plugin", webpack(compiler) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -55,13 +56,13 @@ function webpackInjectionPlugin( raw: true, include: /\.(js|ts|jsx|tsx|mjs|cjs)(\?[^?]*)?(#[^#]*)?$/, banner: (arg?: BannerPluginCallbackArg) => { - let codeToInject = injectionCode; + const codeToInject = injectionCode.clone(); if (debugIds) { const hash = arg?.chunk?.contentHash?.javascript ?? arg?.chunk?.hash; const debugId = hash ? stringToUUID(hash) : uuidv4(); - codeToInject += getDebugIdSnippet(debugId); + codeToInject.append(getDebugIdSnippet(debugId)); } - return codeToInject; + return codeToInject.code(); }, }) );