@@ -9,6 +9,7 @@ import { sentryVitePlugin } from '@sentry/vite-plugin';
99import * as sorcery from 'sorcery' ;
1010import type { Plugin } from 'vite' ;
1111
12+ import MagicString from 'magic-string' ;
1213import { WRAPPED_MODULE_SUFFIX } from './autoInstrument' ;
1314import type { SupportedSvelteKitAdapters } from './detectAdapter' ;
1415import type { GlobalSentryValues } from './injectGlobalValues' ;
@@ -24,17 +25,13 @@ type Sorcery = {
2425 load ( filepath : string ) : Promise < Chain > ;
2526} ;
2627
27- type SentryVitePluginOptionsOptionalInclude = Omit < SentryVitePluginOptions , 'include' > & {
28- include ?: SentryVitePluginOptions [ 'include' ] ;
29- } ;
30-
31- type CustomSentryVitePluginOptions = SentryVitePluginOptionsOptionalInclude & {
28+ type CustomSentryVitePluginOptions = SentryVitePluginOptions & {
3229 adapter : SupportedSvelteKitAdapters ;
3330} ;
3431
3532// storing this in the module scope because `makeCustomSentryVitePlugin` is called multiple times
3633// 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 ( ) ;
3835
3936/**
4037 * Creates a new Vite plugin that uses the unplugin-based Sentry Vite plugin to create
@@ -52,28 +49,44 @@ const release = detectSentryRelease();
5249 *
5350 * @returns the custom Sentry Vite plugin
5451 */
55- export async function makeCustomSentryVitePlugin ( options ?: CustomSentryVitePluginOptions ) : Promise < Plugin > {
52+ export async function makeCustomSentryVitePlugins ( options ?: CustomSentryVitePluginOptions ) : Promise < Plugin [ ] > {
5653 const svelteConfig = await loadSvelteConfig ( ) ;
5754
5855 const usedAdapter = options ?. adapter || 'other' ;
5956 const outputDir = await getAdapterOutputDir ( svelteConfig , usedAdapter ) ;
60- const hasSentryProperties = fs . existsSync ( path . resolve ( process . cwd ( ) , 'sentry.properties' ) ) ;
6157
6258 const defaultPluginOptions : SentryVitePluginOptions = {
63- include : [ ` ${ outputDir } /client` , ` ${ outputDir } /server` ] ,
64- configFile : hasSentryProperties ? 'sentry.properties' : undefined ,
65- release ,
59+ release : {
60+ name : releaseName ,
61+ } ,
6662 } ;
6763
6864 const mergedOptions = {
6965 ...defaultPluginOptions ,
7066 ...options ,
67+ release : {
68+ ...defaultPluginOptions . release ,
69+ ...options ?. release ,
70+ } ,
7171 } ;
72+ const { debug } = mergedOptions ;
7273
73- const sentryPlugin : Plugin = sentryVitePlugin ( mergedOptions ) ;
74+ const sentryPlugins : Plugin [ ] = await sentryVitePlugin ( mergedOptions ) ;
7475
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' ) ;
7790
7891 let isSSRBuild = true ;
7992
@@ -88,11 +101,6 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
88101 apply : 'build' , // only apply this plugin at build time
89102 enforce : 'post' , // this needs to be set to post, otherwise we don't pick up the output from the SvelteKit adapter
90103
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-
96104 // Modify the config to generate source maps
97105 config : config => {
98106 // eslint-disable-next-line no-console
@@ -114,8 +122,7 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
114122 moduleSideEffects : true ,
115123 } ;
116124 }
117- // @ts -expect-error - this hook exists on the plugin!
118- return sentryPlugin . resolveId ( id , _importer , _ref ) ;
125+ return null ;
119126 } ,
120127
121128 load : id => {
@@ -138,16 +145,19 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
138145 } ,
139146
140147 transform : async ( code , id ) => {
141- let modifiedCode = code ;
142148 // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- not end user input + escaped anyway
143149 const isServerHooksFile = new RegExp ( `/${ escapeStringForRegex ( serverHooksFile ) } (.(js|ts|mjs|mts))?` ) . test ( id ) ;
144150
145151 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+ } ;
148158 }
149- // @ts -expect-error - this hook exists on the plugin!
150- return sentryPlugin . transform ( modifiedCode , id ) ;
159+
160+ return null ;
151161 } ,
152162
153163 // We need to start uploading source maps later than in the original plugin
@@ -205,8 +215,12 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
205215 }
206216
207217 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.
208222 // @ts -expect-error - this hook exists on the plugin!
209- await sentryPlugin . writeBundle ( ) ;
223+ await sentryViteDebugIdUploadPlugin . writeBundle ( { dir : outDir } ) ;
210224 } catch ( _ ) {
211225 // eslint-disable-next-line no-console
212226 console . warn ( '[Source Maps Plugin] Failed to upload source maps!' ) ;
@@ -222,7 +236,7 @@ export async function makeCustomSentryVitePlugin(options?: CustomSentryVitePlugi
222236 } ,
223237 } ;
224238
225- return customPlugin ;
239+ return [ ... restOfSentryVitePlugins , customPlugin ] ;
226240}
227241
228242function getFiles ( dir : string ) : string [ ] {
0 commit comments