@@ -9,6 +9,7 @@ import { sentryVitePlugin } from '@sentry/vite-plugin';
9
9
import * as sorcery from 'sorcery' ;
10
10
import type { Plugin } from 'vite' ;
11
11
12
+ import MagicString from 'magic-string' ;
12
13
import { WRAPPED_MODULE_SUFFIX } from './autoInstrument' ;
13
14
import type { SupportedSvelteKitAdapters } from './detectAdapter' ;
14
15
import type { GlobalSentryValues } from './injectGlobalValues' ;
@@ -24,17 +25,13 @@ type Sorcery = {
24
25
load ( filepath : string ) : Promise < Chain > ;
25
26
} ;
26
27
27
- type SentryVitePluginOptionsOptionalInclude = Omit < SentryVitePluginOptions , 'include' > & {
28
- include ?: SentryVitePluginOptions [ 'include' ] ;
29
- } ;
30
-
31
- type CustomSentryVitePluginOptions = SentryVitePluginOptionsOptionalInclude & {
28
+ type CustomSentryVitePluginOptions = SentryVitePluginOptions & {
32
29
adapter : SupportedSvelteKitAdapters ;
33
30
} ;
34
31
35
32
// storing this in the module scope because `makeCustomSentryVitePlugin` is called multiple times
36
33
// and we only want to generate a uuid once in case we have to fall back to it.
37
- const release = detectSentryRelease ( ) ;
34
+ const releaseName = detectSentryRelease ( ) ;
38
35
39
36
/**
40
37
* Creates a new Vite plugin that uses the unplugin-based Sentry Vite plugin to create
@@ -52,28 +49,44 @@ const release = detectSentryRelease();
52
49
*
53
50
* @returns the custom Sentry Vite plugin
54
51
*/
55
- export async function makeCustomSentryVitePlugin ( options ?: CustomSentryVitePluginOptions ) : Promise < Plugin > {
52
+ export async function makeCustomSentryVitePlugins ( options ?: CustomSentryVitePluginOptions ) : Promise < Plugin [ ] > {
56
53
const svelteConfig = await loadSvelteConfig ( ) ;
57
54
58
55
const usedAdapter = options ?. adapter || 'other' ;
59
56
const outputDir = await getAdapterOutputDir ( svelteConfig , usedAdapter ) ;
60
- const hasSentryProperties = fs . existsSync ( path . resolve ( process . cwd ( ) , 'sentry.properties' ) ) ;
61
57
62
58
const defaultPluginOptions : SentryVitePluginOptions = {
63
- include : [ ` ${ outputDir } /client` , ` ${ outputDir } /server` ] ,
64
- configFile : hasSentryProperties ? 'sentry.properties' : undefined ,
65
- release ,
59
+ release : {
60
+ name : releaseName ,
61
+ } ,
66
62
} ;
67
63
68
64
const mergedOptions = {
69
65
...defaultPluginOptions ,
70
66
...options ,
67
+ release : {
68
+ ...defaultPluginOptions . release ,
69
+ ...options ?. release ,
70
+ } ,
71
71
} ;
72
+ const { debug } = mergedOptions ;
72
73
73
- const sentryPlugin : Plugin = sentryVitePlugin ( mergedOptions ) ;
74
+ const sentryPlugins : Plugin [ ] = await sentryVitePlugin ( mergedOptions ) ;
74
75
75
- const { debug } = mergedOptions ;
76
- const { buildStart, renderChunk } = sentryPlugin ;
76
+ const sentryViteDebugIdUploadPlugin = sentryPlugins . find (
77
+ plugin => plugin . name === 'sentry-vite-debug-id-upload-plugin' ,
78
+ ) ;
79
+
80
+ if ( ! sentryViteDebugIdUploadPlugin ) {
81
+ debug &&
82
+ // eslint-disable-next-line no-console
83
+ console . warn (
84
+ 'sentry-vite-debug-id-upload-plugin not found in sentryPlugins! Cannot modify plugin - returning default Sentry Vite plugins' ,
85
+ ) ;
86
+ return sentryPlugins ;
87
+ }
88
+
89
+ const restOfSentryVitePlugins = sentryPlugins . filter ( plugin => plugin . name !== 'sentry-vite-debug-id-upload-plugin' ) ;
77
90
78
91
let isSSRBuild = true ;
79
92
@@ -88,11 +101,6 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
88
101
apply : 'build' , // only apply this plugin at build time
89
102
enforce : 'post' , // this needs to be set to post, otherwise we don't pick up the output from the SvelteKit adapter
90
103
91
- // These hooks are copied from the original Sentry Vite plugin.
92
- // They're mostly responsible for options parsing and release injection.
93
- buildStart,
94
- renderChunk,
95
-
96
104
// Modify the config to generate source maps
97
105
config : config => {
98
106
// eslint-disable-next-line no-console
@@ -114,8 +122,7 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
114
122
moduleSideEffects : true ,
115
123
} ;
116
124
}
117
- // @ts -expect-error - this hook exists on the plugin!
118
- return sentryPlugin . resolveId ( id , _importer , _ref ) ;
125
+ return null ;
119
126
} ,
120
127
121
128
load : id => {
@@ -138,16 +145,19 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
138
145
} ,
139
146
140
147
transform : async ( code , id ) => {
141
- let modifiedCode = code ;
142
148
// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- not end user input + escaped anyway
143
149
const isServerHooksFile = new RegExp ( `/${ escapeStringForRegex ( serverHooksFile ) } (.(js|ts|mjs|mts))?` ) . test ( id ) ;
144
150
145
151
if ( isServerHooksFile ) {
146
- const globalValuesImport = `; import "${ VIRTUAL_GLOBAL_VALUES_FILE } ";` ;
147
- modifiedCode = `${ code } \n${ globalValuesImport } \n` ;
152
+ const ms = new MagicString ( code ) ;
153
+ ms . append ( `\n; import "${ VIRTUAL_GLOBAL_VALUES_FILE } ";` ) ;
154
+ return {
155
+ code : ms . toString ( ) ,
156
+ map : ms . generateMap ( { hires : true } ) ,
157
+ } ;
148
158
}
149
- // @ts -expect-error - this hook exists on the plugin!
150
- return sentryPlugin . transform ( modifiedCode , id ) ;
159
+
160
+ return null ;
151
161
} ,
152
162
153
163
// We need to start uploading source maps later than in the original plugin
@@ -205,8 +215,12 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
205
215
}
206
216
207
217
try {
218
+ // So here, we're just calling the original plugin's `writeBundle` method to upload the source maps.
219
+ // Our plugin hook expects output options to glob for source maps. We don't have this option in `closeBundle`.
220
+ // So we just pass in the `outDir` we determined earlier.
221
+ // Not pretty but my testing shows that it works.
208
222
// @ts -expect-error - this hook exists on the plugin!
209
- await sentryPlugin . writeBundle ( ) ;
223
+ await sentryViteDebugIdUploadPlugin . writeBundle ( { dir : outDir } ) ;
210
224
} catch ( _ ) {
211
225
// eslint-disable-next-line no-console
212
226
console . warn ( '[Source Maps Plugin] Failed to upload source maps!' ) ;
@@ -222,7 +236,7 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
222
236
} ,
223
237
} ;
224
238
225
- return customPlugin ;
239
+ return [ ... restOfSentryVitePlugins , customPlugin ] ;
226
240
}
227
241
228
242
function getFiles ( dir : string ) : string [ ] {
0 commit comments