@@ -24,13 +24,6 @@ type Sorcery = {
2424 load ( filepath : string ) : Promise < Chain > ;
2525} ;
2626
27- type GlobalWithSourceMapSetting = typeof globalThis & {
28- _sentry_sourceMapSetting ?: {
29- updatedSourceMapSetting ?: boolean | 'inline' | 'hidden' ;
30- previousSourceMapSetting ?: UserSourceMapSetting ;
31- } ;
32- } ;
33-
3427// storing this in the module scope because `makeCustomSentryVitePlugin` is called multiple times
3528// and we only want to generate a uuid once in case we have to fall back to it.
3629const releaseName = detectSentryRelease ( ) ;
@@ -57,8 +50,6 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
5750 const usedAdapter = options ?. adapter || 'other' ;
5851 const adapterOutputDir = await getAdapterOutputDir ( svelteConfig , usedAdapter ) ;
5952
60- const globalWithSourceMapSetting = globalThis as GlobalWithSourceMapSetting ;
61-
6253 const defaultPluginOptions : SentryVitePluginOptions = {
6354 release : {
6455 name : releaseName ,
@@ -70,61 +61,8 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
7061 } ,
7162 } ;
7263
73- // Including all hidden (`.*`) directories by default so that folders like .vercel,
74- // .netlify, etc are also cleaned up. Additionally, we include the adapter output
75- // dir which could be a non-hidden directory, like `build` for the Node adapter.
76- const defaultFileDeletionGlob = [ './.*/**/*.map' , `./${ adapterOutputDir } /**/*.map` ] ;
77-
78- if ( ! globalWithSourceMapSetting . _sentry_sourceMapSetting ) {
79- let configFile : {
80- path : string ;
81- config : UserConfig ;
82- dependencies : string [ ] ;
83- } | null = null ;
84-
85- try {
86- // @ts -expect-error - the dynamic import here works fine
87- const Vite = await import ( 'vite' ) ;
88- configFile = await Vite . loadConfigFromFile ( { command : 'build' , mode : 'production' } ) ;
89- } catch {
90- if ( options ?. debug ) {
91- consoleSandbox ( ( ) => {
92- // eslint-disable-next-line no-console
93- console . warn (
94- '[Sentry] Could not import Vite to load your vite config. Please set `build.sourcemap` to `true` or `hidden` to enable source map generation.' ,
95- ) ;
96- } ) ;
97- }
98- }
99-
100- if ( configFile ) {
101- globalWithSourceMapSetting . _sentry_sourceMapSetting = getUpdatedSourceMapSetting ( configFile . config ) ;
102- } else {
103- if ( options ?. debug ) {
104- consoleSandbox ( ( ) => {
105- // eslint-disable-next-line no-console
106- console . warn (
107- '[Sentry] Could not load Vite config with Vite "production" mode. This is needed for Sentry to automatically update source map settings.' ,
108- ) ;
109- } ) ;
110- }
111- }
112-
113- if ( options ?. debug && globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'unset' ) {
114- consoleSandbox ( ( ) => {
115- // eslint-disable-next-line no-console
116- console . warn (
117- `[Sentry] Automatically setting \`sourceMapsUploadOptions.sourcemaps.filesToDeleteAfterUpload: [${ defaultFileDeletionGlob
118- . map ( file => `"${ file } "` )
119- . join ( ', ' ) } ]\` to delete generated source maps after they were uploaded to Sentry.`,
120- ) ;
121- } ) ;
122- }
123- }
124-
125- const shouldDeleteDefaultSourceMaps =
126- globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'unset' &&
127- ! options ?. sourcemaps ?. filesToDeleteAfterUpload ;
64+ const { promise : filesToDeleteAfterUpload , resolve : reportFilesToDeleteAfterUpload } =
65+ createFilesToDeleteAfterUploadPromise ( ) ;
12866
12967 const mergedOptions = {
13068 ...defaultPluginOptions ,
@@ -135,9 +73,7 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
13573 } ,
13674 sourcemaps : {
13775 ...options ?. sourcemaps ,
138- filesToDeleteAfterUpload : shouldDeleteDefaultSourceMaps
139- ? defaultFileDeletionGlob
140- : options ?. sourcemaps ?. filesToDeleteAfterUpload ,
76+ filesToDeleteAfterUpload,
14177 } ,
14278 } ;
14379
@@ -208,24 +144,44 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
208144 config : ( config : UserConfig ) => {
209145 const settingKey = 'build.sourcemap' ;
210146
211- if ( globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'unset' ) {
147+ const { updatedSourceMapSetting, previousSourceMapSetting } = getUpdatedSourceMapSetting ( config ) ;
148+
149+ if ( previousSourceMapSetting === 'unset' ) {
212150 consoleSandbox ( ( ) => {
213151 // eslint-disable-next-line no-console
214152 console . log ( `[Sentry] Enabled source map generation in the build options with \`${ settingKey } : "hidden"\`.` ) ;
215153 } ) ;
216154
155+ // Including all hidden (`.*`) directories by default so that folders like .vercel,
156+ // .netlify, etc are also cleaned up. Additionally, we include the adapter output
157+ // dir which could be a non-hidden directory, like `build` for the Node adapter.
158+ const defaultFileDeletionGlob = [ './.*/**/*.map' , `./${ adapterOutputDir } /**/*.map` ] ;
159+
160+ consoleSandbox ( ( ) => {
161+ // eslint-disable-next-line no-console
162+ console . warn (
163+ `[Sentry] Automatically setting \`sourceMapsUploadOptions.sourcemaps.filesToDeleteAfterUpload: [${ defaultFileDeletionGlob
164+ . map ( file => `"${ file } "` )
165+ . join ( ', ' ) } ]\` to delete generated source maps after they were uploaded to Sentry.`,
166+ ) ;
167+ } ) ;
168+
169+ // In case we enabled source map, we also want to delete them.
170+ // So either use the glob(s) that users specified, or the default one!
171+ reportFilesToDeleteAfterUpload ( options ?. sourcemaps ?. filesToDeleteAfterUpload ?? defaultFileDeletionGlob ) ;
172+
217173 return {
218174 ...config ,
219- build : { ...config . build , sourcemap : 'hidden' } ,
175+ build : { ...config . build , sourcemap : updatedSourceMapSetting } ,
220176 } ;
221- } else if ( globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'disabled' ) {
177+ } else if ( previousSourceMapSetting === 'disabled' ) {
222178 consoleSandbox ( ( ) => {
223179 // eslint-disable-next-line no-console
224180 console . warn (
225181 `[Sentry] Parts of source map generation are currently disabled in your Vite configuration (\`${ settingKey } : false\`). This setting is either a default setting or was explicitly set in your configuration. Sentry won't override this setting. Without source maps, code snippets on the Sentry Issues page will remain minified. To show unminified code, enable source maps in \`${ settingKey } \` (e.g. by setting them to \`hidden\`).` ,
226182 ) ;
227183 } ) ;
228- } else if ( globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'enabled' ) {
184+ } else if ( previousSourceMapSetting === 'enabled' ) {
229185 if ( mergedOptions ?. debug ) {
230186 consoleSandbox ( ( ) => {
231187 // eslint-disable-next-line no-console
@@ -236,6 +192,8 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
236192 }
237193 }
238194
195+ reportFilesToDeleteAfterUpload ( options ?. sourcemaps ?. filesToDeleteAfterUpload ) ;
196+
239197 return config ;
240198 } ,
241199 } ;
@@ -387,7 +345,7 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
387345 const outDir = path . resolve ( process . cwd ( ) , adapterOutputDir ) ;
388346 try {
389347 // @ts -expect-error - the writeBundle hook expects two args we can't pass in here (they're only available in `writeBundle`)
390- await writeBundleFn ( { dir : outDir } ) ;
348+ await writeBundleFn ( { dir : outDir , _sentryFilesToDelete } ) ;
391349 } catch ( e ) {
392350 // eslint-disable-next-line no-console
393351 console . warn ( 'Failed to delete source maps:' , e ) ;
@@ -499,3 +457,22 @@ function detectSentryRelease(): string {
499457
500458 return release ;
501459}
460+
461+ /**
462+ * Creates a deferred promise that can be resolved/rejected by calling the
463+ * `resolve` or `reject` function.
464+ * Inspired by: https://stackoverflow.com/a/69027809
465+ */
466+ function createFilesToDeleteAfterUploadPromise ( ) : {
467+ promise : Promise < string | string [ ] | undefined > ;
468+ resolve : ( value : string | string [ ] | undefined ) => void ;
469+ reject : ( reason ?: unknown ) => void ;
470+ } {
471+ let resolve ! : ( value : string | string [ ] | undefined ) => void ;
472+ let reject ! : ( reason ?: unknown ) => void ;
473+ const promise = new Promise < string | string [ ] | undefined > ( ( res , rej ) => {
474+ resolve = res ;
475+ reject = rej ;
476+ } ) ;
477+ return { resolve, reject, promise } ;
478+ }
0 commit comments