Skip to content

feat(solidstart): Respect user-provided source map setting #14979

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/migration/v8-to-v9.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ In v9, an `undefined` value will be treated the same as if the value is not defi

- By default, source maps will now be automatically deleted after being uploaded to Sentry for client-side builds. You can opt out of this behavior by explicitly setting `sourcemaps.deleteSourcemapsAfterUpload` to `false` in your Sentry config.

### All Meta-Framework SDKs (`@sentry/astro`, `@sentry/nuxt`)
### All Meta-Framework SDKs (`@sentry/astro`, `@sentry/nuxt`, `@sentry/solidstart`)

- Updated source map generation to respect the user-provided value of your build config, such as `vite.build.sourcemap`:

Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/integration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.log(
`[Sentry] Setting \`sourceMapsUploadOptions.filesToDeleteAfterUpload: ${JSON.stringify(
`[Sentry] Automatically setting \`sourceMapsUploadOptions.filesToDeleteAfterUpload: ${JSON.stringify(
updatedFilesToDeleteAfterUpload,
)}\` to delete generated source maps after they were uploaded to Sentry.`,
);
Expand Down Expand Up @@ -226,7 +226,7 @@ export function getUpdatedSourceMapSettings(
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.warn(
`[Sentry] Source map generation are currently disabled in your Astro 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\`).`,
`[Sentry] Source map generation is currently disabled in your Astro 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\`).`,
);
});
} else if (viteSourceMap && ['hidden', 'inline', true].includes(viteSourceMap)) {
Expand Down
4 changes: 1 addition & 3 deletions packages/astro/test/integration/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,9 +456,7 @@ describe('getUpdatedSourceMapSettings', () => {

astroConfig.vite.build.sourcemap = false;
getUpdatedSourceMapSettings(astroConfig, sentryOptions);
expect(consoleWarnSpy).toHaveBeenCalledWith(
expect.stringContaining('Source map generation are currently disabled'),
);
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('Source map generation is currently disabled'));

astroConfig.vite.build.sourcemap = 'hidden';
getUpdatedSourceMapSettings(astroConfig, sentryOptions);
Expand Down
11 changes: 7 additions & 4 deletions packages/solidstart/src/vite/sentrySolidStartVite.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { Plugin, UserConfig } from 'vite';
import { makeBuildInstrumentationFilePlugin } from './buildInstrumentationFile';
import { makeSourceMapsVitePlugin } from './sourceMaps';
import { makeAddSentryVitePlugin, makeEnableSourceMapsVitePlugin } from './sourceMaps';
import type { SentrySolidStartPluginOptions } from './types';

/**
* Various Sentry vite plugins to be used for SolidStart.
*/
export const sentrySolidStartVite = (options: SentrySolidStartPluginOptions = {}): Plugin[] => {
export const sentrySolidStartVite = (options: SentrySolidStartPluginOptions = {}, viteConfig: UserConfig): Plugin[] => {
const sentryPlugins: Plugin[] = [];

if (options.autoInjectServerSentry !== 'experimental_dynamic-import') {
Expand All @@ -15,7 +15,10 @@ export const sentrySolidStartVite = (options: SentrySolidStartPluginOptions = {}

if (process.env.NODE_ENV !== 'development') {
if (options.sourceMapsUploadOptions?.enabled ?? true) {
sentryPlugins.push(...makeSourceMapsVitePlugin(options));
const sourceMapsPlugin = makeAddSentryVitePlugin(options, viteConfig);
const enableSourceMapsPlugin = makeEnableSourceMapsVitePlugin(options);

sentryPlugins.push(...sourceMapsPlugin, ...enableSourceMapsPlugin);
}
}

Expand All @@ -27,7 +30,7 @@ export const sentrySolidStartVite = (options: SentrySolidStartPluginOptions = {}
*/
export const addSentryPluginToVite = (config: UserConfig = {}, options: SentrySolidStartPluginOptions): UserConfig => {
const plugins = Array.isArray(config.plugins) ? [...config.plugins] : [];
plugins.unshift(sentrySolidStartVite(options));
plugins.unshift(sentrySolidStartVite(options, config));

return {
...config,
Expand Down
149 changes: 113 additions & 36 deletions packages/solidstart/src/vite/sourceMaps.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,48 @@
import { consoleSandbox } from '@sentry/core';
import { sentryVitePlugin } from '@sentry/vite-plugin';
import type { Plugin } from 'vite';
import type { Plugin, UserConfig } from 'vite';
import type { SentrySolidStartPluginOptions } from './types';

/**
* A Sentry plugin for SolidStart to enable source maps and use
* @sentry/vite-plugin to automatically upload source maps to Sentry.
* @param {SourceMapsOptions} options
* A Sentry plugin for adding the @sentry/vite-plugin to automatically upload source maps to Sentry.
*/
export function makeSourceMapsVitePlugin(options: SentrySolidStartPluginOptions): Plugin[] {
export function makeAddSentryVitePlugin(options: SentrySolidStartPluginOptions, viteConfig: UserConfig): Plugin[] {
const { authToken, debug, org, project, sourceMapsUploadOptions } = options;
return [
{
name: 'sentry-solidstart-source-maps',
apply: 'build',
enforce: 'post',
config(config) {
// TODO(v9): Remove this warning
if (config.build?.sourcemap === false) {
// eslint-disable-next-line no-console
console.warn(
"[Sentry SolidStart Plugin] You disabled sourcemaps with the `build.sourcemap` option. Currently, the Sentry SDK will override this option to generate sourcemaps. In future versions, the Sentry SDK will not override the `build.sourcemap` option if you explicitly disable it. If you want to generate and upload sourcemaps please set the `build.sourcemap` option to 'hidden' or undefined.",
);
}

// TODO(v9): Remove this warning and print warning in case source map deletion is auto configured
if (!sourceMapsUploadOptions?.filesToDeleteAfterUpload) {
// eslint-disable-next-line no-console
console.warn(
"[Sentry SolidStart Plugin] The Sentry SDK has enabled source map generation for your SolidStart app. If you don't want to serve Source Maps to your users, either configure the `filesToDeleteAfterUpload` option with a glob to remove source maps after uploading them, or manually delete the source maps after the build. In future Sentry SDK versions source maps will be deleted automatically after uploading them.",
);
}

return {
...config,
build: {
...config.build,
sourcemap: true,
},
};
},
},
let updatedFilesToDeleteAfterUpload: string[] | undefined = undefined;

if (
typeof sourceMapsUploadOptions?.filesToDeleteAfterUpload === 'undefined' &&
typeof sourceMapsUploadOptions?.unstable_sentryVitePluginOptions?.sourcemaps?.filesToDeleteAfterUpload ===
'undefined' &&
// Only if source maps were previously not set, we update the "filesToDeleteAfterUpload" (as we override the setting with "hidden")
typeof viteConfig.build?.sourcemap === 'undefined'
) {
// This also works for adapters, as the source maps are also copied to e.g. the .vercel folder
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: any chance this comment is from astro (not sure if solid start has adapters)? :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yes, good catch

updatedFilesToDeleteAfterUpload = ['.*/**/*.map'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
updatedFilesToDeleteAfterUpload = ['.*/**/*.map'];
updatedFilesToDeleteAfterUpload = ['./**/*.map'];

Unless this is intentional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional. It should match .output, .vercel, etc.


consoleSandbox(() => {
// eslint-disable-next-line no-console
console.log(
`[Sentry] Automatically setting \`sourceMapsUploadOptions.filesToDeleteAfterUpload: ${JSON.stringify(
updatedFilesToDeleteAfterUpload,
)}\` to delete generated source maps after they were uploaded to Sentry.`,
);
});
}

return [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: If we only return sentryVitePlugin() here, we don't need to spread the plugins into a new array but can simply return the call directly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was done to make it easier to add more plugins if we ever need, but I guess we can cross that bridge then :)

...sentryVitePlugin({
authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,
bundleSizeOptimizations: options.bundleSizeOptimizations,
debug: debug ?? false,
org: org ?? process.env.SENTRY_ORG,
project: project ?? process.env.SENTRY_PROJECT,
sourcemaps: {
filesToDeleteAfterUpload: sourceMapsUploadOptions?.filesToDeleteAfterUpload ?? undefined,
filesToDeleteAfterUpload:
(sourceMapsUploadOptions?.filesToDeleteAfterUpload ||
sourceMapsUploadOptions?.unstable_sentryVitePluginOptions?.sourcemaps?.filesToDeleteAfterUpload) ??
updatedFilesToDeleteAfterUpload,
...sourceMapsUploadOptions?.unstable_sentryVitePluginOptions?.sourcemaps,
},
telemetry: sourceMapsUploadOptions?.telemetry ?? true,
Expand All @@ -60,3 +55,85 @@ export function makeSourceMapsVitePlugin(options: SentrySolidStartPluginOptions)
}),
];
}

/**
* A Sentry plugin for SolidStart to enable "hidden" source maps if they are unset.
*/
export function makeEnableSourceMapsVitePlugin(options: SentrySolidStartPluginOptions): Plugin[] {
return [
{
name: 'sentry-solidstart-update-source-map-setting',
apply: 'build',
enforce: 'post',
config(viteConfig) {
return {
...viteConfig,
build: {
...viteConfig.build,
sourcemap: getUpdatedSourceMapSettings(viteConfig, options),
},
};
},
},
];
}

/** There are 3 ways to set up source map generation (https://github.com/getsentry/sentry-j avascript/issues/13993)
*
* 1. User explicitly disabled source maps
* - keep this setting (emit a warning that errors won't be unminified in Sentry)
* - We won't upload anything
*
* 2. Users enabled source map generation (true, 'hidden', 'inline').
* - keep this setting (don't do anything - like deletion - besides uploading)
*
* 3. Users didn't set source maps generation
* - we enable 'hidden' source maps generation
* - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)
*
* --> only exported for testing
*/
export function getUpdatedSourceMapSettings(
viteConfig: UserConfig,
sentryPluginOptions?: SentrySolidStartPluginOptions,
): boolean | 'inline' | 'hidden' {
viteConfig.build = viteConfig.build || {};

const viteSourceMap = viteConfig?.build?.sourcemap;
let updatedSourceMapSetting = viteSourceMap;

const settingKey = 'vite.build.sourcemap';

if (viteSourceMap === false) {
updatedSourceMapSetting = viteSourceMap;

consoleSandbox(() => {
// eslint-disable-next-line no-console
console.warn(
`[Sentry] Source map generation is currently disabled in your SolidStart 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\`).`,
);
});
} else if (viteSourceMap && ['hidden', 'inline', true].includes(viteSourceMap)) {
updatedSourceMapSetting = viteSourceMap;

if (sentryPluginOptions?.debug) {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.log(
`[Sentry] We discovered \`${settingKey}\` is set to \`${viteSourceMap.toString()}\`. Sentry will keep this source map setting. This will un-minify the code snippet on the Sentry Issue page.`,
);
});
}
} else {
updatedSourceMapSetting = 'hidden';

consoleSandbox(() => {
// eslint-disable-next-line no-console
console.log(
`[Sentry] Enabled source map generation in the build options with \`${settingKey}: 'hidden'\`. The source maps will be deleted after they were uploaded to Sentry.`,
);
});
}

return updatedSourceMapSetting;
}
6 changes: 3 additions & 3 deletions packages/solidstart/test/config/withSentry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ describe('withSentry()', () => {
const names = config?.vite.plugins.flat().map((plugin: Plugin) => plugin.name);
expect(names).toEqual([
'sentry-solidstart-build-instrumentation-file',
'sentry-solidstart-source-maps',
'sentry-telemetry-plugin',
'sentry-vite-release-injection-plugin',
'sentry-debug-id-upload-plugin',
'sentry-vite-debug-id-injection-plugin',
'sentry-vite-debug-id-upload-plugin',
'sentry-file-deletion-plugin',
'sentry-solidstart-update-source-map-setting',
]);
});

Expand All @@ -107,13 +107,13 @@ describe('withSentry()', () => {
const names = config?.vite.plugins.flat().map((plugin: Plugin) => plugin.name);
expect(names).toEqual([
'sentry-solidstart-build-instrumentation-file',
'sentry-solidstart-source-maps',
'sentry-telemetry-plugin',
'sentry-vite-release-injection-plugin',
'sentry-debug-id-upload-plugin',
'sentry-vite-debug-id-injection-plugin',
'sentry-vite-debug-id-upload-plugin',
'sentry-file-deletion-plugin',
'sentry-solidstart-update-source-map-setting',
'my-test-plugin',
]);
});
Expand All @@ -139,13 +139,13 @@ describe('withSentry()', () => {
.map((plugin: Plugin) => plugin.name);
expect(names).toEqual([
'sentry-solidstart-build-instrumentation-file',
'sentry-solidstart-source-maps',
'sentry-telemetry-plugin',
'sentry-vite-release-injection-plugin',
'sentry-debug-id-upload-plugin',
'sentry-vite-debug-id-injection-plugin',
'sentry-vite-debug-id-upload-plugin',
'sentry-file-deletion-plugin',
'sentry-solidstart-update-source-map-setting',
'my-test-plugin',
]);
});
Expand Down
17 changes: 10 additions & 7 deletions packages/solidstart/test/vite/sentrySolidStartVite.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ vi.spyOn(console, 'warn').mockImplementation(() => {
});

function getSentrySolidStartVitePlugins(options?: Parameters<typeof sentrySolidStartVite>[0]): Plugin[] {
return sentrySolidStartVite({
project: 'project',
org: 'org',
authToken: 'token',
...options,
});
return sentrySolidStartVite(
{
project: 'project',
org: 'org',
authToken: 'token',
...options,
},
{},
);
}

describe('sentrySolidStartVite()', () => {
Expand All @@ -24,13 +27,13 @@ describe('sentrySolidStartVite()', () => {
const names = plugins.map(plugin => plugin.name);
expect(names).toEqual([
'sentry-solidstart-build-instrumentation-file',
'sentry-solidstart-source-maps',
'sentry-telemetry-plugin',
'sentry-vite-release-injection-plugin',
'sentry-debug-id-upload-plugin',
'sentry-vite-debug-id-injection-plugin',
'sentry-vite-debug-id-upload-plugin',
'sentry-file-deletion-plugin',
'sentry-solidstart-update-source-map-setting',
]);
});

Expand Down
Loading
Loading