diff --git a/packages/bundler-plugin-core/.eslintrc.js b/packages/bundler-plugin-core/.eslintrc.js index ede7139e..34addfe7 100644 --- a/packages/bundler-plugin-core/.eslintrc.js +++ b/packages/bundler-plugin-core/.eslintrc.js @@ -11,6 +11,7 @@ module.exports = { "rollup.config.js", "test/fixtures/**/*", "sentry-release-injection-file.js", + "sentry-esbuild-debugid-injection-file.js", ], parserOptions: { tsconfigRootDir: __dirname, diff --git a/packages/bundler-plugin-core/package.json b/packages/bundler-plugin-core/package.json index 0f72efff..8242724a 100644 --- a/packages/bundler-plugin-core/package.json +++ b/packages/bundler-plugin-core/package.json @@ -11,7 +11,8 @@ }, "files": [ "dist", - "sentry-release-injection-file.js" + "sentry-release-injection-file.js", + "sentry-esbuild-debugid-injection-file.js" ], "main": "dist/cjs/index.js", "module": "dist/esm/index.mjs", @@ -71,5 +72,9 @@ }, "engines": { "node": ">= 10" - } + }, + "sideEffects": [ + "./sentry-release-injection-file.js", + "./sentry-esbuild-debugid-injection-file.js" + ] } diff --git a/packages/bundler-plugin-core/sentry-esbuild-debugid-injection-file.js b/packages/bundler-plugin-core/sentry-esbuild-debugid-injection-file.js new file mode 100644 index 00000000..b3cdf857 --- /dev/null +++ b/packages/bundler-plugin-core/sentry-esbuild-debugid-injection-file.js @@ -0,0 +1,18 @@ +try { + var globalObject = + "undefined" != typeof window + ? window + : "undefined" != typeof global + ? global + : "undefined" != typeof self + ? self + : {}; + + var stack = new Error().stack; + + if (stack) { + globalObject._sentryDebugIds = globalObject._sentryDebugIds || {}; + globalObject._sentryDebugIds[stack] = "__SENTRY_DEBUG_ID__"; + globalObject._sentryDebugIdIdentifier = "sentry-dbid-__SENTRY_DEBUG_ID__"; + } +} catch (e) {} diff --git a/packages/bundler-plugin-core/src/index.ts b/packages/bundler-plugin-core/src/index.ts index 3064dc4f..e1300289 100644 --- a/packages/bundler-plugin-core/src/index.ts +++ b/packages/bundler-plugin-core/src/index.ts @@ -1,4 +1,4 @@ -import { createUnplugin } from "unplugin"; +import { createUnplugin, UnpluginOptions } from "unplugin"; import MagicString from "magic-string"; import { Options, BuildContext } from "./types"; import { @@ -26,8 +26,8 @@ import { makeMain } from "@sentry/node"; import os from "os"; import path from "path"; import fs from "fs"; -import util from "util"; -import { getDependencies, getPackageJson, parseMajorVersion } from "./utils"; +import { promisify } from "util"; +import { getDependencies, getPackageJson, parseMajorVersion, stringToUUID } from "./utils"; import { glob } from "glob"; import { injectDebugIdSnippetIntoChunk, prepareBundleForDebugIdUpload } from "./debug-id"; import { SourceMapSource } from "webpack-sources"; @@ -39,6 +39,10 @@ const releaseInjectionFilePath = require.resolve( "@sentry/bundler-plugin-core/sentry-release-injection-file" ); +const esbuildDebugIdInjectionFilePath = require.resolve( + "@sentry/bundler-plugin-core/sentry-esbuild-debugid-injection-file" +); + /** * The sentry bundler plugin concerns itself with two things: * - Release injection @@ -66,7 +70,7 @@ const releaseInjectionFilePath = require.resolve( * * This release creation pipeline relies on Sentry CLI to execute the different steps. */ -const unplugin = createUnplugin((options, unpluginMetaContext) => { +const unplugin = createUnplugin((options, unpluginMetaContext) => { const internalOptions = normalizeUserOptions(options); const allowedToSendTelemetryPromise = shouldSendTelemetry(internalOptions); @@ -113,7 +117,9 @@ const unplugin = createUnplugin((options, unpluginMetaContext) => { let transaction: Transaction | undefined; let releaseInjectionSpan: Span | undefined; - return { + const plugins: UnpluginOptions[] = []; + + plugins.push({ name: "sentry-plugin", enforce: "pre", // needed for Vite to call resolveId hook @@ -317,7 +323,31 @@ const unplugin = createUnplugin((options, unpluginMetaContext) => { }) ).filter((p) => p.endsWith(".js") || p.endsWith(".mjs")); - const sourceFileUploadFolderPromise = util.promisify(fs.mkdtemp)( + if (unpluginMetaContext.framework === "esbuild") { + await Promise.all( + debugIdChunkFilePaths.map(async (debugIdChunkFilePath) => { + const chunkFileContents = await promisify(fs.readFile)( + debugIdChunkFilePath, + "utf-8" + ); + + const debugId = stringToUUID(chunkFileContents); + + const newChunkFileContents = chunkFileContents.replace( + /__SENTRY_DEBUG_ID__/g, + debugId + ); + + await promisify(fs.writeFile)( + debugIdChunkFilePath, + newChunkFileContents, + "utf-8" + ); + }) + ); + } + + const sourceFileUploadFolderPromise = promisify(fs.mkdtemp)( path.join(os.tmpdir(), "sentry-bundler-plugin-upload-") ); @@ -455,7 +485,23 @@ const unplugin = createUnplugin((options, unpluginMetaContext) => { }); } }, - }; + }); + + if (unpluginMetaContext.framework === "esbuild") { + if (internalOptions._experiments.debugIdUpload) { + plugins.push({ + name: "sentry-esbuild-debug-id-plugin", + esbuild: { + setup({ initialOptions }) { + initialOptions.inject = initialOptions.inject || []; + initialOptions.inject.push(esbuildDebugIdInjectionFilePath); + }, + }, + }); + } + } + + return plugins; }); function handleError(