Skip to content

feat(nuxt): Align build-time options to follow bundler plugins structure #17255

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 6 commits into from
Aug 1, 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
21 changes: 20 additions & 1 deletion packages/core/src/build-time-plugins/buildTimeOptionsBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ export interface BuildTimeOptionsBase {
*/
silent?: boolean;

/**
* When an error occurs during release creation or sourcemaps upload, the plugin will call this function.
*
* By default, the plugin will simply throw an error, thereby stopping the bundling process.
Copy link
Member

Choose a reason for hiding this comment

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

Unless I'm mistaken, by default the plugin fails gracefully by printing the error but not exiting the build process.

Copy link
Member Author

Choose a reason for hiding this comment

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

The docs are taken from here: https://www.npmjs.com/package/@sentry/vite-plugin#errorhandler

If this is not correct, we should also fix it in the bundler-plugins readme.

* If an `errorHandler` callback is provided, compilation will continue unless an error is
* thrown in the provided callback.
*
* To allow compilation to continue but still emit a warning, set this option to the following:
*
* ```js
* (err) => {
* console.warn(err);
* }
* ```
*/
errorHandler?: (err: Error) => void;

/**
* Enable debug information logs about the SDK during build-time.
* Enabling this will give you, for example, logs about source maps.
Expand Down Expand Up @@ -184,7 +201,9 @@ export type UnstableRollupPluginOptions<PluginOptionsType> = {

interface SourceMapsOptions {
/**
* If this flag is `true`, any functionality related to source maps will be disabled.
* If this flag is `true`, any functionality related to source maps will be disabled. This includes the automatic upload of source maps.
*
* By default (`false`), the plugin automatically uploads source maps during a production build if a Sentry auth token is detected.
*
* @default false
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
{
files: ['vite.config.ts'],
parserOptions: {
project: ['tsconfig.test.json'],
project: ['tsconfig.vite.json'],
},
},
],
Expand Down
34 changes: 27 additions & 7 deletions packages/nuxt/src/common/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { BuildTimeOptionsBase } from '@sentry/core';
import type { init as initNode } from '@sentry/node';
import type { SentryRollupPluginOptions } from '@sentry/rollup-plugin';
import type { SentryVitePluginOptions } from '@sentry/vite-plugin';
Expand Down Expand Up @@ -26,6 +27,7 @@ type SourceMapsOptions = {
* Suppresses all logs.
*
* @default false
* @deprecated Use option `silent` instead of `sourceMapsUploadOptions.silent`
*/
silent?: boolean;

Expand All @@ -43,13 +45,17 @@ type SourceMapsOptions = {
* console.warn(err);
* }
* ```
*
* @deprecated Use option `errorHandler` instead of `sourceMapsUploadOptions.errorHandler`
*/
errorHandler?: (err: Error) => void;

/**
* Options related to managing the Sentry releases for a build.
*
* More info: https://docs.sentry.io/product/releases/
*
* @deprecated Use option `release` instead of `sourceMapsUploadOptions.release`
*/
release?: {
/**
Expand All @@ -62,6 +68,8 @@ type SourceMapsOptions = {
* (the latter requires access to git CLI and for the root directory to be a valid repository)
*
* If you didn't provide a value and the plugin can't automatically detect one, no release will be created.
*
* @deprecated Use `release.name` instead of `sourceMapsUploadOptions.release.name`
*/
name?: string;
};
Expand All @@ -71,6 +79,7 @@ type SourceMapsOptions = {
* automatically generate and upload source maps to Sentry during a production build.
*
* @default true
* @deprecated Use option `sourcemaps.disable` instead of `sourceMapsUploadOptions.enabled`
*/
enabled?: boolean;

Expand All @@ -81,25 +90,30 @@ type SourceMapsOptions = {
*
* To create an auth token, follow this guide:
* @see https://docs.sentry.io/product/accounts/auth-tokens/#organization-auth-tokens
* @deprecated Use option `authToken` instead of `sourceMapsUploadOptions.authToken`
*/
authToken?: string;

/**
* The organization slug of your Sentry organization.
* Instead of specifying this option, you can also set the `SENTRY_ORG` environment variable.
* @deprecated Use option `org` instead of `sourceMapsUploadOptions.org`
*/
org?: string;

/**
* The URL of your Sentry instance if you're using self-hosted Sentry.
*
* @default https://sentry.io by default the plugin will point towards the Sentry SaaS URL
* @deprecated Use `sentryUrl` instead of `sourceMapsUploadOptions.url`
*/
url?: string;

/**
* The project slug of your Sentry project.
* Instead of specifying this option, you can also set the `SENTRY_PROJECT` environment variable.
*
* @deprecated Use option `project` instead of `sourceMapsUploadOptions.project`
*/
project?: string;

Expand All @@ -108,11 +122,14 @@ type SourceMapsOptions = {
* It will not collect any sensitive or user-specific data.
*
* @default true
* @deprecated Use option `telemetry` instead of `sourceMapsUploadOptions.telemetry`
*/
telemetry?: boolean;

/**
* Options related to sourcemaps
*
* @deprecated Use option `sourcemaps` instead of `sourceMapsUploadOptions.sourcemaps`
*/
sourcemaps?: {
/**
Expand All @@ -124,6 +141,8 @@ type SourceMapsOptions = {
*
* The globbing patterns must follow the implementation of the `glob` package.
* @see https://www.npmjs.com/package/glob#glob-primer
*
* @deprecated Use option `sourcemaps.assets` instead of `sourceMapsUploadOptions.sourcemaps.assets`
*/
assets?: string | Array<string>;

Expand All @@ -134,6 +153,8 @@ type SourceMapsOptions = {
* or the default value for `assets` are uploaded.
*
* The globbing patterns follow the implementation of the glob package. (https://www.npmjs.com/package/glob)
*
* @deprecated Use option `sourcemaps.ignore` instead of `sourceMapsUploadOptions.sourcemaps.ignore`
*/
ignore?: string | Array<string>;

Expand All @@ -144,6 +165,8 @@ type SourceMapsOptions = {
* @default [] - By default no files are deleted.
*
* The globbing patterns follow the implementation of the glob package. (https://www.npmjs.com/package/glob)
*
* @deprecated Use option `sourcemaps.filesToDeleteAfterUpload` instead of `sourceMapsUploadOptions.sourcemaps.filesToDeleteAfterUpload`
*/
filesToDeleteAfterUpload?: string | Array<string>;
};
Expand All @@ -152,7 +175,7 @@ type SourceMapsOptions = {
/**
* Build options for the Sentry module. These options are used during build-time by the Sentry SDK.
*/
export type SentryNuxtModuleOptions = {
export type SentryNuxtModuleOptions = BuildTimeOptionsBase & {
/**
* Enable the Sentry Nuxt Module.
*
Expand All @@ -165,15 +188,12 @@ export type SentryNuxtModuleOptions = {
*
* These options are always read from the `sentry` module options in the `nuxt.config.(js|ts).
* Do not define them in the `sentry.client.config.(js|ts)` or `sentry.server.config.(js|ts)` files.
*
* @deprecated This option was deprecated as it adds unnecessary nesting.
* Put the options one level higher to the root-level of the `sentry` module options.
*/
sourceMapsUploadOptions?: SourceMapsOptions;

/**
* Enable debug functionality of the SDK during build-time.
* Enabling this will give you, for example, logs about source maps.
*/
debug?: boolean;

/**
*
* Enables (partial) server tracing by automatically injecting Sentry for environments where modifying the node option `--import` is not possible.
Expand Down
71 changes: 54 additions & 17 deletions packages/nuxt/src/vite/sourceMaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,20 @@ export type SourceMapSetting = boolean | 'hidden' | 'inline';
* Setup source maps for Sentry inside the Nuxt module during build time (in Vite for Nuxt and Rollup for Nitro).
*/
export function setupSourceMaps(moduleOptions: SentryNuxtModuleOptions, nuxt: Nuxt): void {
// TODO(v11): remove deprecated options (also from SentryNuxtModuleOptions type)

const isDebug = moduleOptions.debug;

// eslint-disable-next-line deprecation/deprecation
const sourceMapsUploadOptions = moduleOptions.sourceMapsUploadOptions || {};
const sourceMapsEnabled = sourceMapsUploadOptions.enabled ?? true;

const sourceMapsEnabled =
moduleOptions.sourcemaps?.disable === true
? false
: moduleOptions.sourcemaps?.disable === false
? true
: // eslint-disable-next-line deprecation/deprecation
sourceMapsUploadOptions.enabled ?? true;

// In case we overwrite the source map settings, we default to deleting the files
let shouldDeleteFilesFallback = { client: true, server: true };
Expand All @@ -42,6 +52,8 @@ export function setupSourceMaps(moduleOptions: SentryNuxtModuleOptions, nuxt: Nu

if (
isDebug &&
!moduleOptions.sourcemaps?.filesToDeleteAfterUpload &&
// eslint-disable-next-line deprecation/deprecation
!sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload &&
(shouldDeleteFilesFallback.client || shouldDeleteFilesFallback.server)
) {
Expand Down Expand Up @@ -134,10 +146,13 @@ function normalizePath(path: string): string {
*
* Only exported for Testing purposes.
*/
// todo(v11): This "eslint-disable" can be removed again once we remove deprecated options.
// eslint-disable-next-line complexity
export function getPluginOptions(
moduleOptions: SentryNuxtModuleOptions,
shouldDeleteFilesFallback?: { client: boolean; server: boolean },
): SentryVitePluginOptions | SentryRollupPluginOptions {
// eslint-disable-next-line deprecation/deprecation
const sourceMapsUploadOptions = moduleOptions.sourceMapsUploadOptions || {};

const shouldDeleteFilesAfterUpload = shouldDeleteFilesFallback?.client || shouldDeleteFilesFallback?.server;
Expand All @@ -148,10 +163,17 @@ export function getPluginOptions(
: []),
];

if (
typeof sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload === 'undefined' &&
shouldDeleteFilesAfterUpload
) {
// Check for filesToDeleteAfterUpload in new location first, then deprecated location
const sourcemapsOptions = moduleOptions.sourcemaps || {};
// eslint-disable-next-line deprecation/deprecation
const deprecatedSourcemapsOptions = sourceMapsUploadOptions.sourcemaps || {};

const filesToDeleteAfterUpload =
sourcemapsOptions.filesToDeleteAfterUpload ??
// eslint-disable-next-line deprecation/deprecation
deprecatedSourcemapsOptions.filesToDeleteAfterUpload;

if (typeof filesToDeleteAfterUpload === 'undefined' && shouldDeleteFilesAfterUpload) {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.log(
Expand All @@ -164,16 +186,28 @@ export function getPluginOptions(
}

return {
org: sourceMapsUploadOptions.org ?? process.env.SENTRY_ORG,
project: sourceMapsUploadOptions.project ?? process.env.SENTRY_PROJECT,
authToken: sourceMapsUploadOptions.authToken ?? process.env.SENTRY_AUTH_TOKEN,
telemetry: sourceMapsUploadOptions.telemetry ?? true,
url: sourceMapsUploadOptions.url ?? process.env.SENTRY_URL,
// eslint-disable-next-line deprecation/deprecation
org: moduleOptions.org ?? sourceMapsUploadOptions.org ?? process.env.SENTRY_ORG,
// eslint-disable-next-line deprecation/deprecation
project: moduleOptions.project ?? sourceMapsUploadOptions.project ?? process.env.SENTRY_PROJECT,
// eslint-disable-next-line deprecation/deprecation
authToken: moduleOptions.authToken ?? sourceMapsUploadOptions.authToken ?? process.env.SENTRY_AUTH_TOKEN,
// eslint-disable-next-line deprecation/deprecation
telemetry: moduleOptions.telemetry ?? sourceMapsUploadOptions.telemetry ?? true,
// eslint-disable-next-line deprecation/deprecation
url: moduleOptions.sentryUrl ?? sourceMapsUploadOptions.url ?? process.env.SENTRY_URL,
headers: moduleOptions.headers,
debug: moduleOptions.debug ?? false,
silent: sourceMapsUploadOptions.silent ?? false,
errorHandler: sourceMapsUploadOptions.errorHandler,
// eslint-disable-next-line deprecation/deprecation
silent: moduleOptions.silent ?? sourceMapsUploadOptions.silent ?? false,
// eslint-disable-next-line deprecation/deprecation
errorHandler: moduleOptions.errorHandler ?? sourceMapsUploadOptions.errorHandler,
bundleSizeOptimizations: moduleOptions.bundleSizeOptimizations, // todo: test if this can be overridden by the user
Comment on lines +190 to +205
Copy link
Member

Choose a reason for hiding this comment

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

l/just to confirm: Did we settle on the new build time options taking precedence over the old ones? I think this is generally fine (as fine as vice versa) but let's make sure we're consistent with this behaviour across sdks. (also doesn't hurt to write it down in the issue).

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah we didn't specifically talk about that but I thought it makes sense as it makes migration easier as well. I'll write it down 👍

release: {
name: sourceMapsUploadOptions.release?.name,
// eslint-disable-next-line deprecation/deprecation
name: moduleOptions.release?.name ?? sourceMapsUploadOptions.release?.name,
// Support all release options from BuildTimeOptionsBase
...moduleOptions.release,
Copy link

Choose a reason for hiding this comment

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

Bug: Release Name Fallback Overwritten by Undefined

The release.name fallback logic is broken. The ...moduleOptions.release spread operator, applied after the explicit name assignment, can overwrite a valid fallback value from sourceMapsUploadOptions.release?.name with undefined if moduleOptions.release.name is undefined. This defeats the intended fallback behavior.

Locations (1)
Fix in Cursor Fix in Web

...moduleOptions?.unstable_sentryBundlerPluginOptions?.release,
},
_metaOptions: {
Expand All @@ -184,13 +218,16 @@ export function getPluginOptions(
...moduleOptions?.unstable_sentryBundlerPluginOptions,

sourcemaps: {
disable: moduleOptions.sourcemaps?.disable,
// The server/client files are in different places depending on the nitro preset (e.g. '.output/server' or '.netlify/functions-internal/server')
// We cannot determine automatically how the build folder looks like (depends on the preset), so we have to accept that source maps are uploaded multiple times (with the vitePlugin for Nuxt and the rollupPlugin for Nitro).
// If we could know where the server/client assets are located, we could do something like this (based on the Nitro preset): isNitro ? ['./.output/server/**/*'] : ['./.output/public/**/*'],
assets: sourceMapsUploadOptions.sourcemaps?.assets ?? undefined,
ignore: sourceMapsUploadOptions.sourcemaps?.ignore ?? undefined,
filesToDeleteAfterUpload: sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload
? sourceMapsUploadOptions.sourcemaps?.filesToDeleteAfterUpload
// eslint-disable-next-line deprecation/deprecation
assets: sourcemapsOptions.assets ?? deprecatedSourcemapsOptions.assets ?? undefined,
// eslint-disable-next-line deprecation/deprecation
ignore: sourcemapsOptions.ignore ?? deprecatedSourcemapsOptions.ignore ?? undefined,
filesToDeleteAfterUpload: filesToDeleteAfterUpload
? filesToDeleteAfterUpload
: shouldDeleteFilesFallback?.server || shouldDeleteFilesFallback?.client
? fallbackFilesToDelete
: undefined,
Expand Down
Loading
Loading