Skip to content

Commit d80e27b

Browse files
authored
fix(astro): Adjust Vite plugin config to upload server source maps (#9541)
For some reason our automatic assets detection in the Vite plugin doesn't work well in Astro builds. While client files were picked up and uploaded correctly, server-side source and map files were not uploaded. This fix ensures we search for files to be uploaded in the entire output directory by building an `assets` glob from the output directory stored in the `config` object. Once again Astro's integrations API comes in super handy here as this already gives us a custom output directory if users overwrote the default (`/dist`) one.
1 parent 569e5b5 commit d80e27b

File tree

2 files changed

+56
-15
lines changed

2 files changed

+56
-15
lines changed

packages/astro/src/integration/index.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable no-console */
22
import { sentryVitePlugin } from '@sentry/vite-plugin';
3-
import type { AstroIntegration } from 'astro';
3+
import type { AstroConfig, AstroIntegration } from 'astro';
44
import * as fs from 'fs';
55
import * as path from 'path';
66

@@ -13,7 +13,8 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => {
1313
return {
1414
name: PKG_NAME,
1515
hooks: {
16-
'astro:config:setup': async ({ updateConfig, injectScript }) => {
16+
// eslint-disable-next-line complexity
17+
'astro:config:setup': async ({ updateConfig, injectScript, config }) => {
1718
// The third param here enables loading of all env vars, regardless of prefix
1819
// see: https://main.vitejs.dev/config/#using-environment-variables-in-config
1920

@@ -40,6 +41,10 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => {
4041
project: uploadOptions.project ?? env.SENTRY_PROJECT,
4142
authToken: uploadOptions.authToken ?? env.SENTRY_AUTH_TOKEN,
4243
telemetry: uploadOptions.telemetry ?? true,
44+
sourcemaps: {
45+
assets: [getSourcemapsAssetsGlob(config)],
46+
},
47+
debug: options.debug ?? false,
4348
}),
4449
],
4550
},
@@ -79,3 +84,17 @@ function findDefaultSdkInitFile(type: 'server' | 'client'): string | undefined {
7984
.map(ext => path.resolve(path.join(process.cwd(), `sentry.${type}.config.${ext}`)))
8085
.find(filename => fs.existsSync(filename));
8186
}
87+
88+
function getSourcemapsAssetsGlob(config: AstroConfig): string {
89+
// paths are stored as "file://" URLs
90+
const outDirPathname = config.outDir && path.resolve(config.outDir.pathname);
91+
const rootDirName = path.resolve((config.root && config.root.pathname) || process.cwd());
92+
93+
if (outDirPathname) {
94+
const relativePath = path.relative(rootDirName, outDirPathname);
95+
return `${relativePath}/**/*`;
96+
}
97+
98+
// fallback to default output dir
99+
return 'dist/**/*';
100+
}

packages/astro/test/integration/index.test.ts

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ process.env = {
1414
SENTRY_AUTH_TOKEN: 'my-token',
1515
};
1616

17+
const updateConfig = vi.fn();
18+
const injectScript = vi.fn();
19+
const config = {
20+
root: new URL('file://path/to/project'),
21+
outDir: new URL('file://path/to/project/out'),
22+
};
23+
1724
describe('sentryAstro integration', () => {
1825
afterEach(() => {
1926
vi.clearAllMocks();
@@ -28,12 +35,10 @@ describe('sentryAstro integration', () => {
2835
const integration = sentryAstro({
2936
sourceMapsUploadOptions: { enabled: true, org: 'my-org', project: 'my-project', telemetry: false },
3037
});
31-
const updateConfig = vi.fn();
32-
const injectScript = vi.fn();
3338

3439
expect(integration.hooks['astro:config:setup']).toBeDefined();
3540
// @ts-expect-error - the hook exists and we only need to pass what we actually use
36-
await integration.hooks['astro:config:setup']({ updateConfig, injectScript });
41+
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config });
3742

3843
expect(updateConfig).toHaveBeenCalledTimes(1);
3944
expect(updateConfig).toHaveBeenCalledWith({
@@ -51,32 +56,52 @@ describe('sentryAstro integration', () => {
5156
org: 'my-org',
5257
project: 'my-project',
5358
telemetry: false,
59+
debug: false,
60+
sourcemaps: {
61+
assets: ['out/**/*'],
62+
},
63+
});
64+
});
65+
66+
it('falls back to default output dir, if out and root dir are not available', async () => {
67+
const integration = sentryAstro({
68+
sourceMapsUploadOptions: { enabled: true, org: 'my-org', project: 'my-project', telemetry: false },
69+
});
70+
// @ts-expect-error - the hook exists and we only need to pass what we actually use
71+
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config: {} });
72+
73+
expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1);
74+
expect(sentryVitePluginSpy).toHaveBeenCalledWith({
75+
authToken: 'my-token',
76+
org: 'my-org',
77+
project: 'my-project',
78+
telemetry: false,
79+
debug: false,
80+
sourcemaps: {
81+
assets: ['dist/**/*'],
82+
},
5483
});
5584
});
5685

5786
it("doesn't enable source maps if `sourceMapsUploadOptions.enabled` is `false`", async () => {
5887
const integration = sentryAstro({
5988
sourceMapsUploadOptions: { enabled: false },
6089
});
61-
const updateConfig = vi.fn();
62-
const injectScript = vi.fn();
6390

6491
expect(integration.hooks['astro:config:setup']).toBeDefined();
6592
// @ts-expect-error - the hook exists and we only need to pass what we actually use
66-
await integration.hooks['astro:config:setup']({ updateConfig, injectScript });
93+
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config });
6794

6895
expect(updateConfig).toHaveBeenCalledTimes(0);
6996
expect(sentryVitePluginSpy).toHaveBeenCalledTimes(0);
7097
});
7198

7299
it('injects client and server init scripts', async () => {
73100
const integration = sentryAstro({});
74-
const updateConfig = vi.fn();
75-
const injectScript = vi.fn();
76101

77102
expect(integration.hooks['astro:config:setup']).toBeDefined();
78103
// @ts-expect-error - the hook exists and we only need to pass what we actually use
79-
await integration.hooks['astro:config:setup']({ updateConfig, injectScript });
104+
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config });
80105

81106
expect(injectScript).toHaveBeenCalledTimes(2);
82107
expect(injectScript).toHaveBeenCalledWith('page', expect.stringContaining('Sentry.init'));
@@ -89,12 +114,9 @@ describe('sentryAstro integration', () => {
89114
serverInitPath: 'my-server-init-path.js',
90115
});
91116

92-
const updateConfig = vi.fn();
93-
const injectScript = vi.fn();
94-
95117
expect(integration.hooks['astro:config:setup']).toBeDefined();
96118
// @ts-expect-error - the hook exists and we only need to pass what we actually use
97-
await integration.hooks['astro:config:setup']({ updateConfig, injectScript });
119+
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config });
98120

99121
expect(injectScript).toHaveBeenCalledTimes(2);
100122
expect(injectScript).toHaveBeenCalledWith('page', expect.stringContaining('my-client-init-path.js'));

0 commit comments

Comments
 (0)