From 4202c334a4c9582ba881aeac63bf8212b35c5e00 Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 14 Oct 2026 10:05:19 -0700 Subject: [PATCH 1/2] fix(cloudflare): keep default exports intact when auto-instrumenting The Vite transform rewrote `export default ` to `const __SENTRY_DEFAULT_EXPORT__ = ` and set the wrapped default export at the end of the module. That broke the module in four ways: - A parenthesized default export, such as `export default (handler);`, became a syntax error. The rewrite replaced everything up to the expression, which dropped the `(` and kept the `)`. - An anonymous class, function or arrow took the name `__SENTRY_DEFAULT_EXPORT__` in place of `default`. Libraries can read `.name`, as #24700 found for named classes. - `export default class Handler {}` lost the `Handler` binding, so other code in the module that used `Handler` threw. - A circular import that read the default export after the original `export default` statement, but before the end of the module, threw. The transform now replaces only the `export default` keywords, keeps a named class or function declaration as it is, and gives an anonymous one the name `default` by way of an object property. The default export is set in two steps, as for `export { handler as default }`. Where the original statement set it, it is bound to the value as-is, so a circular import gets the handler. At the end of the module, it is rebound to the wrapper, so methods added to the handler after `export default` are instrumented too. Co-Authored-By: Claude Opus 5.5 (1M context) --- packages/cloudflare/src/vite/transform.ts | 40 +++++++++- .../test/vite/autoInstrument.test.ts | 10 +-- .../cloudflare/test/vite/transform.test.ts | 77 ++++++++++++++++++- 3 files changed, 116 insertions(+), 11 deletions(-) diff --git a/packages/cloudflare/src/vite/transform.ts b/packages/cloudflare/src/vite/transform.ts index 5307ad48336b..50dadd37068c 100644 --- a/packages/cloudflare/src/vite/transform.ts +++ b/packages/cloudflare/src/vite/transform.ts @@ -393,14 +393,46 @@ function wrapDefaultExport(node: ExportDefaultNode, ctx: TransformContext, state } } - // `export default ` → `const __SENTRY_DEFAULT_EXPORT__ = ` - // MagicString positions are always relative to the original source. - state.ms.overwrite(node.start, decl.start, 'const __SENTRY_DEFAULT_EXPORT__ = '); - state.ms.append(`\nexport default __SENTRY__.withSentry(${state.optionsFn}, __SENTRY_DEFAULT_EXPORT__);\n`); + // MagicString positions are always relative to the original source. Only the `export default` + // keywords are replaced, so parentheses around the expression stay. + const source = state.ms.original; + const keywordsEnd = node.start + source.slice(node.start, decl.start).lastIndexOf('default') + 'default'.length; + const declaredName = + decl.type === 'ClassDeclaration' || decl.type === 'FunctionDeclaration' + ? (decl as ClassDeclarationNode).id?.name + : undefined; + + let wrapped = '__SENTRY_DEFAULT_EXPORT__'; + if (declaredName) { + // `export default class Handler {}`: the declaration stays, so `Handler` stays bound in the module. + state.ms.remove(node.start, decl.start); + wrapped = declaredName; + } else if (isAnonymousFunctionOrClass(decl)) { + // As a property value, the class or function gets the name `default`, as `export default` gives it. + const hasSemicolon = source[node.end - 1] === ';'; + state.ms.overwrite(node.start, keywordsEnd, 'const __SENTRY_DEFAULT_EXPORT__ = { default:'); + state.ms.appendLeft(hasSemicolon ? node.end - 1 : node.end, hasSemicolon ? ' }.default' : ' }.default;'); + } else { + state.ms.overwrite(node.start, keywordsEnd, 'const __SENTRY_DEFAULT_EXPORT__ ='); + } + + // Right after the original statement, so the default export is set where it was before. + state.ms.appendLeft(node.end, `\nexport default __SENTRY__.withSentry(${state.optionsFn}, ${wrapped});`); state.needsImport = true; state.autoWrapped.add(DEFAULT_EXPORT); } +function isAnonymousFunctionOrClass(node: BaseNode): boolean { + if (node.type === 'ArrowFunctionExpression') return true; + const isFunctionOrClass = [ + 'FunctionExpression', + 'FunctionDeclaration', + 'ClassExpression', + 'ClassDeclaration', + ].includes(node.type); + return isFunctionOrClass && !(node as ClassDeclarationNode).id; +} + function handleNamedExport(node: ExportNamedNode, ctx: TransformContext, state: TransformState): void { const decl = node.declaration; diff --git a/packages/cloudflare/test/vite/autoInstrument.test.ts b/packages/cloudflare/test/vite/autoInstrument.test.ts index 9f987f6ea78a..a8e7c4321c1d 100644 --- a/packages/cloudflare/test/vite/autoInstrument.test.ts +++ b/packages/cloudflare/test/vite/autoInstrument.test.ts @@ -77,7 +77,7 @@ describe('sentryCloudflareAutoInstrumentPlugin', () => { expect(result.code).toBe( "import * as __SENTRY__ from '@sentry/nextjs/cloudflare';\n" + 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);\n', + 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ); }); @@ -99,7 +99,7 @@ describe('sentryCloudflareAutoInstrumentPlugin', () => { expect(result.code).toBe( "import * as __SENTRY__ from '@sentry/cloudflare';\n" + 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);\n', + 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ); }); @@ -119,7 +119,7 @@ describe('sentryCloudflareAutoInstrumentPlugin', () => { expect(result.code).toBe( "import * as __SENTRY__ from '@sentry/cloudflare';\n" + 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);\n', + 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ); }); @@ -143,7 +143,7 @@ describe('sentryCloudflareAutoInstrumentPlugin', () => { expect(result.code).toBe( "import * as __SENTRY__ from '@sentry/cloudflare';\n" + 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);\n', + 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ); }); @@ -520,7 +520,6 @@ describe('wranglerConfigPath option', () => { "import * as __SENTRY__ from '@sentry/cloudflare';", 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };', 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', - '', ].join('\n'), ); }); @@ -598,7 +597,6 @@ describe('package specifier as wrangler `main`', () => { "import * as __SENTRY__ from '@sentry/cloudflare';", 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };', 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', - '', ].join('\n'), ); }); diff --git a/packages/cloudflare/test/vite/transform.test.ts b/packages/cloudflare/test/vite/transform.test.ts index 8b3cd2ec207f..278a8ab79850 100644 --- a/packages/cloudflare/test/vite/transform.test.ts +++ b/packages/cloudflare/test/vite/transform.test.ts @@ -286,6 +286,82 @@ describe('default export wrapping', () => { expect(result.code).toContain('tracesSampleRate: 1.0'); }); + /** + * Writes `files` to a temp dir, with `a.mjs` transformed and `withSentry` stubbed to return the + * handler as-is, and returns what `node ` prints. + */ + function runWithEntry(files: Record, entry: string, transformEntry = true): string { + const dir = mkdtempSync(join(tmpdir(), 'sentry-cf-default-')); + try { + for (const [name, code] of Object.entries(files)) { + const out = + name === 'a.mjs' && transformEntry + ? transform(code, ctx)!.code.replace( + "import * as __SENTRY__ from '@sentry/cloudflare';", + 'const __SENTRY__ = { withSentry: (_options, handler) => handler };', + ) + : code; + writeFileSync(join(dir, name), out); + } + return execFileSync(process.execPath, [join(dir, entry)], { encoding: 'utf8' }).trim(); + } finally { + rmSync(dir, { recursive: true, force: true }); + } + } + + it.each([ + 'export default class { fetch() {} }', + 'export default function () {}', + 'export default () => {};', + 'export default (class { fetch() {} });', + 'export default class Handler { fetch() {} }', + 'export default function handler() {}', + ])('keeps the name of the default export of `%s`', code => { + const files = { 'a.mjs': code, 'b.mjs': "import handler from './a.mjs';\nconsole.log(handler.name);" }; + expect(runWithEntry(files, 'b.mjs')).toBe(runWithEntry(files, 'b.mjs', false)); + }); + + it('wraps a parenthesized default export', () => { + const code = ['const handler = { fetch() {} };', 'export default (handler);'].join('\n'); + + expect(transform(code, ctx)!.code).toBe( + [ + "import * as __SENTRY__ from '@sentry/cloudflare';", + 'const handler = { fetch() {} };', + 'const __SENTRY_DEFAULT_EXPORT__ = (handler);', + 'export default __SENTRY__.withSentry((env) => ({}), __SENTRY_DEFAULT_EXPORT__);', + ].join('\n'), + ); + }); + + it('keeps the module binding of a named default class', () => { + const code = ['export default class Handler { fetch() {} }', 'Handler.ready = true;'].join('\n'); + + expect(transform(code, ctx)!.code).toBe( + [ + "import * as __SENTRY__ from '@sentry/cloudflare';", + 'class Handler { fetch() {} }', + 'export default __SENTRY__.withSentry((env) => ({}), Handler);', + 'Handler.ready = true;', + ].join('\n'), + ); + }); + + it('sets the default export where the original statement set it', () => { + // `b` reads the default export of `a` while `a` is still evaluating, after its `export default`. + const files = { + 'a.mjs': [ + "import { readDefault } from './b.mjs';", + 'export default { fetch() {} };', + 'export const seen = readDefault();', + ].join('\n'), + 'b.mjs': "import handler from './a.mjs';\nexport function readDefault() { return typeof handler.fetch; }", + 'main.mjs': "import { seen } from './a.mjs';\nconsole.log(seen);", + }; + + expect(runWithEntry(files, 'main.mjs')).toBe('function'); + }); + it('skips when already wrapped with withSentry', () => { const code = [ "import { withSentry } from '@sentry/cloudflare';", @@ -934,7 +1010,6 @@ describe('agent class wrapping', () => { '', 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() {} };', 'export default __SENTRY__.withSentry((env) => ({ dsn: env.SENTRY_DSN }), __SENTRY_DEFAULT_EXPORT__);', - '', ].join('\n'), ); }); From a37b84a4d737edc581af35feef38ab4f64526e08 Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 14 Oct 2026 11:32:36 -0700 Subject: [PATCH 2/2] fixup! fix(cloudflare): keep default exports intact when auto-instrumenting --- packages/cloudflare/src/vite/transform.ts | 13 ++++--- .../test/vite/autoInstrument.test.ts | 30 +++++++++------ .../cloudflare/test/vite/transform.test.ts | 37 +++++++++++++------ 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/packages/cloudflare/src/vite/transform.ts b/packages/cloudflare/src/vite/transform.ts index 50dadd37068c..273cfb16a766 100644 --- a/packages/cloudflare/src/vite/transform.ts +++ b/packages/cloudflare/src/vite/transform.ts @@ -402,22 +402,25 @@ function wrapDefaultExport(node: ExportDefaultNode, ctx: TransformContext, state ? (decl as ClassDeclarationNode).id?.name : undefined; + // As with `export { handler as default }`, the export is set in two steps: bound as-is where the + // original statement set it, then rebound at the end of the module to the wrapper, which sees + // methods added in between. See `wrapDefaultSpecifier`. let wrapped = '__SENTRY_DEFAULT_EXPORT__'; if (declaredName) { // `export default class Handler {}`: the declaration stays, so `Handler` stays bound in the module. state.ms.remove(node.start, decl.start); + state.ms.appendLeft(node.end, `\nvar __SENTRY_DEFAULT_EXPORT__ = ${declaredName};`); wrapped = declaredName; } else if (isAnonymousFunctionOrClass(decl)) { // As a property value, the class or function gets the name `default`, as `export default` gives it. const hasSemicolon = source[node.end - 1] === ';'; - state.ms.overwrite(node.start, keywordsEnd, 'const __SENTRY_DEFAULT_EXPORT__ = { default:'); + state.ms.overwrite(node.start, keywordsEnd, 'var __SENTRY_DEFAULT_EXPORT__ = { default:'); state.ms.appendLeft(hasSemicolon ? node.end - 1 : node.end, hasSemicolon ? ' }.default' : ' }.default;'); } else { - state.ms.overwrite(node.start, keywordsEnd, 'const __SENTRY_DEFAULT_EXPORT__ ='); + state.ms.overwrite(node.start, keywordsEnd, 'var __SENTRY_DEFAULT_EXPORT__ ='); } - - // Right after the original statement, so the default export is set where it was before. - state.ms.appendLeft(node.end, `\nexport default __SENTRY__.withSentry(${state.optionsFn}, ${wrapped});`); + state.ms.appendLeft(node.end, '\nexport { __SENTRY_DEFAULT_EXPORT__ as default };'); + state.ms.append(`\n__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry(${state.optionsFn}, ${wrapped});`); state.needsImport = true; state.autoWrapped.add(DEFAULT_EXPORT); } diff --git a/packages/cloudflare/test/vite/autoInstrument.test.ts b/packages/cloudflare/test/vite/autoInstrument.test.ts index a8e7c4321c1d..7212a8fe55c8 100644 --- a/packages/cloudflare/test/vite/autoInstrument.test.ts +++ b/packages/cloudflare/test/vite/autoInstrument.test.ts @@ -76,8 +76,9 @@ describe('sentryCloudflareAutoInstrumentPlugin', () => { expect(resolve).toHaveBeenCalledWith('@sentry/nextjs/cloudflare', join(dir, 'src/index.ts')); expect(result.code).toBe( "import * as __SENTRY__ from '@sentry/nextjs/cloudflare';\n" + - 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', + 'var __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + + 'export { __SENTRY_DEFAULT_EXPORT__ as default };\n' + + '__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ); }); @@ -98,8 +99,9 @@ describe('sentryCloudflareAutoInstrumentPlugin', () => { expect(result.code).toBe( "import * as __SENTRY__ from '@sentry/cloudflare';\n" + - 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', + 'var __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + + 'export { __SENTRY_DEFAULT_EXPORT__ as default };\n' + + '__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ); }); @@ -118,8 +120,9 @@ describe('sentryCloudflareAutoInstrumentPlugin', () => { expect(result.code).toBe( "import * as __SENTRY__ from '@sentry/cloudflare';\n" + - 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', + 'var __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + + 'export { __SENTRY_DEFAULT_EXPORT__ as default };\n' + + '__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ); }); @@ -142,8 +145,9 @@ describe('sentryCloudflareAutoInstrumentPlugin', () => { expect(result.code).toBe( "import * as __SENTRY__ from '@sentry/cloudflare';\n" + - 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', + 'var __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' + + 'export { __SENTRY_DEFAULT_EXPORT__ as default };\n' + + '__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ); }); @@ -518,8 +522,9 @@ describe('wranglerConfigPath option', () => { expect(result.code).toBe( [ "import * as __SENTRY__ from '@sentry/cloudflare';", - 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };', - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', + 'var __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };', + 'export { __SENTRY_DEFAULT_EXPORT__ as default };', + '__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ].join('\n'), ); }); @@ -595,8 +600,9 @@ describe('package specifier as wrangler `main`', () => { expect(result.code).toBe( [ "import * as __SENTRY__ from '@sentry/cloudflare';", - 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };', - 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', + 'var __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };', + 'export { __SENTRY_DEFAULT_EXPORT__ as default };', + '__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);', ].join('\n'), ); }); diff --git a/packages/cloudflare/test/vite/transform.test.ts b/packages/cloudflare/test/vite/transform.test.ts index 278a8ab79850..539b66c98961 100644 --- a/packages/cloudflare/test/vite/transform.test.ts +++ b/packages/cloudflare/test/vite/transform.test.ts @@ -52,7 +52,7 @@ describe('default export wrapping', () => { const result = transform(code, ctx)!; expect(result).toBeDefined(); expect(result.code).toContain("import * as __SENTRY__ from '@sentry/cloudflare'"); - expect(result.code).toContain('const __SENTRY_DEFAULT_EXPORT__ = handler'); + expect(result.code).toContain('var __SENTRY_DEFAULT_EXPORT__ = handler'); expect(result.code).toContain('__SENTRY__.withSentry((env) => ({}), __SENTRY_DEFAULT_EXPORT__)'); expect(result.code).not.toContain('export default handler'); expect(result.map).toBeDefined(); @@ -62,7 +62,7 @@ describe('default export wrapping', () => { const code = 'export default { fetch() { return new Response("ok"); } };'; const result = transform(code, ctx)!; expect(result).toBeDefined(); - expect(result.code).toContain('const __SENTRY_DEFAULT_EXPORT__ ='); + expect(result.code).toContain('var __SENTRY_DEFAULT_EXPORT__ ='); expect(result.code).toContain('__SENTRY__.withSentry('); }); @@ -287,8 +287,8 @@ describe('default export wrapping', () => { }); /** - * Writes `files` to a temp dir, with `a.mjs` transformed and `withSentry` stubbed to return the - * handler as-is, and returns what `node ` prints. + * Writes `files` to a temp dir, with `a.mjs` transformed and `withSentry` stubbed to mark each + * method it finds as instrumented, and returns what `node ` prints. */ function runWithEntry(files: Record, entry: string, transformEntry = true): string { const dir = mkdtempSync(join(tmpdir(), 'sentry-cf-default-')); @@ -298,7 +298,7 @@ describe('default export wrapping', () => { name === 'a.mjs' && transformEntry ? transform(code, ctx)!.code.replace( "import * as __SENTRY__ from '@sentry/cloudflare';", - 'const __SENTRY__ = { withSentry: (_options, handler) => handler };', + 'const __SENTRY__ = { withSentry: (_options, handler) => { for (const key of Object.keys(handler)) handler[key].instrumented = true; return handler; } };', ) : code; writeFileSync(join(dir, name), out); @@ -328,8 +328,9 @@ describe('default export wrapping', () => { [ "import * as __SENTRY__ from '@sentry/cloudflare';", 'const handler = { fetch() {} };', - 'const __SENTRY_DEFAULT_EXPORT__ = (handler);', - 'export default __SENTRY__.withSentry((env) => ({}), __SENTRY_DEFAULT_EXPORT__);', + 'var __SENTRY_DEFAULT_EXPORT__ = (handler);', + 'export { __SENTRY_DEFAULT_EXPORT__ as default };', + '__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry((env) => ({}), __SENTRY_DEFAULT_EXPORT__);', ].join('\n'), ); }); @@ -341,12 +342,23 @@ describe('default export wrapping', () => { [ "import * as __SENTRY__ from '@sentry/cloudflare';", 'class Handler { fetch() {} }', - 'export default __SENTRY__.withSentry((env) => ({}), Handler);', + 'var __SENTRY_DEFAULT_EXPORT__ = Handler;', + 'export { __SENTRY_DEFAULT_EXPORT__ as default };', 'Handler.ready = true;', + '__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry((env) => ({}), Handler);', ].join('\n'), ); }); + it('wraps a method added to the default export after `export default`', () => { + const files = { + 'a.mjs': ['const handler = {};', 'export default handler;', 'handler.fetch = function () {};'].join('\n'), + 'main.mjs': "import handler from './a.mjs';\nconsole.log(String(handler.fetch.instrumented));", + }; + + expect(runWithEntry(files, 'main.mjs')).toBe('true'); + }); + it('sets the default export where the original statement set it', () => { // `b` reads the default export of `a` while `a` is still evaluating, after its `export default`. const files = { @@ -1008,8 +1020,9 @@ describe('agent class wrapping', () => { 'const __SENTRY_WRAPPED_MyDO__ = __SENTRY__.instrumentDurableObjectWithSentry((env) => ({ dsn: env.SENTRY_DSN }), MyDO);', 'export { __SENTRY_WRAPPED_MyDO__ as MyDO };', '', - 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() {} };', - 'export default __SENTRY__.withSentry((env) => ({ dsn: env.SENTRY_DSN }), __SENTRY_DEFAULT_EXPORT__);', + 'var __SENTRY_DEFAULT_EXPORT__ = { fetch() {} };', + 'export { __SENTRY_DEFAULT_EXPORT__ as default };', + '__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry((env) => ({ dsn: env.SENTRY_DSN }), __SENTRY_DEFAULT_EXPORT__);', ].join('\n'), ); }); @@ -1119,8 +1132,8 @@ describe('combined transforms', () => { expect(result.code).toContain('export { __SENTRY_WRAPPED_MyDO__ as MyDO };'); // Default export wrapped - expect(result.code).toContain('const __SENTRY_DEFAULT_EXPORT__ ='); - expect(result.code).toContain('export default __SENTRY__.withSentry('); + expect(result.code).toContain('var __SENTRY_DEFAULT_EXPORT__ ='); + expect(result.code).toContain('__SENTRY_DEFAULT_EXPORT__ = __SENTRY__.withSentry('); // Single import const importCount = (result.code.match(/import \* as __SENTRY__/g) ?? []).length;