Skip to content

feat(nitro): Handle sourcemap preparation and upload#19304

Merged
logaretm merged 18 commits intoawad/create-nitro-sdk-metadatafrom
awad/js-1076-nitro-upload-sourcemaps
Apr 22, 2026
Merged

feat(nitro): Handle sourcemap preparation and upload#19304
logaretm merged 18 commits intoawad/create-nitro-sdk-metadatafrom
awad/js-1076-nitro-upload-sourcemaps

Conversation

@logaretm
Copy link
Copy Markdown
Member

@logaretm logaretm commented Feb 12, 2026

Adds automatic sourcemap handling to the Nitro SDK, using @sentry/bundler-plugin-core for builder-agnostic post-build upload.

Nitro uses rollup or rolldown, so it made sense to make it as agnostic as possible.

Closes #17992


This PR is part of a stack:

@linear
Copy link
Copy Markdown

linear Bot commented Feb 12, 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 12, 2026

Codecov Results 📊


Generated by Codecov Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 12, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 25.88 kB added added
@sentry/browser - with treeshaking flags 24.35 kB added added
@sentry/browser (incl. Tracing) 43.77 kB added added
@sentry/browser (incl. Tracing + Span Streaming) 45.47 kB added added
@sentry/browser (incl. Tracing, Profiling) 48.7 kB added added
@sentry/browser (incl. Tracing, Replay) 82.89 kB added added
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 72.4 kB added added
@sentry/browser (incl. Tracing, Replay with Canvas) 87.58 kB added added
@sentry/browser (incl. Tracing, Replay, Feedback) 99.83 kB added added
@sentry/browser (incl. Feedback) 42.7 kB added added
@sentry/browser (incl. sendFeedback) 30.55 kB added added
@sentry/browser (incl. FeedbackAsync) 35.55 kB added added
@sentry/browser (incl. Metrics) 27.16 kB added added
@sentry/browser (incl. Logs) 27.29 kB added added
@sentry/browser (incl. Metrics & Logs) 27.98 kB added added
@sentry/react 27.62 kB added added
@sentry/react (incl. Tracing) 46.01 kB added added
@sentry/vue 30.7 kB added added
@sentry/vue (incl. Tracing) 45.58 kB added added
@sentry/svelte 25.89 kB added added
CDN Bundle 28.55 kB added added
CDN Bundle (incl. Tracing) 44.82 kB added added
CDN Bundle (incl. Logs, Metrics) 29.93 kB added added
CDN Bundle (incl. Tracing, Logs, Metrics) 45.91 kB added added
CDN Bundle (incl. Replay, Logs, Metrics) 68.83 kB added added
CDN Bundle (incl. Tracing, Replay) 81.78 kB added added
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 82.85 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback) 87.29 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 88.36 kB added added
CDN Bundle - uncompressed 83.4 kB added added
CDN Bundle (incl. Tracing) - uncompressed 134.03 kB added added
CDN Bundle (incl. Logs, Metrics) - uncompressed 87.55 kB added added
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 137.44 kB added added
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 210.91 kB added added
CDN Bundle (incl. Tracing, Replay) - uncompressed 251.26 kB added added
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 254.66 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 264.18 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 267.56 kB added added
@sentry/nextjs (client) 48.54 kB added added
@sentry/sveltekit (client) 44.18 kB added added
@sentry/node-core 57.97 kB added added
@sentry/node 174.81 kB added added
@sentry/node - without tracing 97.93 kB added added
@sentry/aws-serverless 115.16 kB added added

@logaretm logaretm force-pushed the awad/js-1128-nitro-use-tracing-channels-for-srvx-and-h3 branch from 1923dda to be2f037 Compare February 23, 2026 14:50
@logaretm logaretm force-pushed the awad/js-1076-nitro-upload-sourcemaps branch from 0d86a79 to 9f6254a Compare February 23, 2026 14:50
@logaretm logaretm force-pushed the awad/js-1128-nitro-use-tracing-channels-for-srvx-and-h3 branch from be2f037 to 3b30e36 Compare February 23, 2026 14:52
@logaretm logaretm force-pushed the awad/js-1076-nitro-upload-sourcemaps branch from 9f6254a to 63a2175 Compare February 23, 2026 14:52
@logaretm logaretm force-pushed the awad/js-1128-nitro-use-tracing-channels-for-srvx-and-h3 branch from 3b30e36 to 36c96b6 Compare February 23, 2026 16:17
@logaretm logaretm force-pushed the awad/js-1076-nitro-upload-sourcemaps branch 2 times, most recently from d3e3ae1 to a24cad5 Compare February 23, 2026 16:23
@github-actions
Copy link
Copy Markdown
Contributor

This pull request has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you apply the label PR: no-auto-close I will leave it alone ... forever!

@logaretm logaretm force-pushed the awad/js-1128-nitro-use-tracing-channels-for-srvx-and-h3 branch 2 times, most recently from 3cf1515 to 342ea3b Compare April 15, 2026 13:54
@logaretm logaretm force-pushed the awad/js-1076-nitro-upload-sourcemaps branch from a24cad5 to 1583866 Compare April 15, 2026 14:44
@logaretm logaretm force-pushed the awad/js-1128-nitro-use-tracing-channels-for-srvx-and-h3 branch from 342ea3b to 8d44437 Compare April 15, 2026 14:55
@logaretm logaretm force-pushed the awad/js-1076-nitro-upload-sourcemaps branch 2 times, most recently from a967e7a to 00bd835 Compare April 15, 2026 14:59
@logaretm logaretm marked this pull request as ready for review April 15, 2026 18:13
Comment thread packages/nitro/src/sourceMaps.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds build-time sourcemap generation + post-build sourcemap (and debug ID) handling to the @sentry/nitro SDK by wiring Nitro’s compiled hook to @sentry/bundler-plugin-core.

Changes:

  • Introduces packages/nitro/src/sourceMaps.ts to configure Nitro sourcemap settings and to run a post-build upload flow via createSentryBuildPluginManager.
  • Threads SentryNitroOptions through module setup so sourcemap behavior can be configured from withSentryConfig/setupSentryNitroModule.
  • Adds Vitest coverage for option-shaping and basic hook registration behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/nitro/src/sourceMaps.ts New sourcemap config + post-build hook which injects debug IDs and uploads sourcemaps via bundler-plugin-core
packages/nitro/test/sourceMaps.test.ts New unit tests for plugin option building, config mutation, and hook registration
packages/nitro/src/module.ts Passes Sentry options into module setup to enable sourcemap handling
packages/nitro/src/config.ts Defines SentryNitroOptions from bundler-plugin-core options and enables sourcemap config during module setup
packages/nitro/rollup.npm.config.mjs Marks @sentry/bundler-plugin-core as external in the package build
packages/nitro/package.json Adds @sentry/bundler-plugin-core dependency

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/nitro/src/sourceMaps.ts
Comment thread packages/nitro/src/sourceMaps.ts Outdated
Comment thread packages/nitro/src/sourceMaps.ts Outdated
Comment thread packages/nitro/src/sourceMaps.ts Outdated
Comment thread packages/nitro/src/sourceMaps.ts Outdated
Comment thread packages/nitro/test/sourceMaps.test.ts
logaretm and others added 8 commits April 17, 2026 23:53
…is set

When `sourcemaps.disable` is `'disable-upload'`, the plugin should still
inject debug IDs and keep `.map` files so users can upload them manually.
Previously, both `injectDebugIds()` and `deleteArtifacts()` were
incorrectly gated or ungated, causing debug IDs to be skipped and source
maps to be deleted even in the manual-upload workflow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Derive `SentryNitroOptions` from `BuildTimeOptionsBase` (from `@sentry/core`)
instead of picking from the bundler plugin's internal `Options` type. This
provides a stable public API that follows this repo's semver, rather than
exposing bundler-plugin-specific fields like `_metaOptions` and top-level
`disable`.

Key changes:
- `url` option renamed to `sentryUrl` (consistent with other SDKs)
- Top-level `disable` removed (use `sourcemaps.disable` instead)
- `_metaOptions` no longer user-configurable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ing `true`

Previously, `configureSourcemapSettings` unconditionally set
`config.sourcemap = true`, overriding the user's explicit `false`. This
could expose source maps publicly when users intentionally disabled them.

Now follows the same 3-case pattern as other meta-framework SDKs (Nuxt):
1. User disabled (false) → keep their setting, warn about unminified errors
2. User enabled (true) → keep their setting
3. User didn't set (undefined) → enable for Sentry

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
`configureSourcemapSettings` runs at build time, but the `debug` logger
from `@sentry/core` is only initialized by `Sentry.init()` at runtime.
Switch to `console.warn`/`console.log` so build-time warnings (e.g.
source maps explicitly disabled) are actually visible to developers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The `rewriteSources` option was hardcoded to `normalizePath`, silently
discarding any custom function provided by the user. Now falls back to
`normalizePath` only when the user doesn't provide their own function,
matching the behavior of other meta-framework SDKs (Nuxt, Next.js).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously `filesToDeleteAfterUpload` defaulted to `['**/*.map']`
unconditionally, deleting user-generated source maps even when the user
explicitly set `sourcemap: true` in their Nitro config. Now the default
only applies when Sentry was the one to enable sourcemap generation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nitro spawns a nested Nitro instance for prerendering with the user's
`modules` array re-installed, which caused the Sentry module to run
twice and upload source maps + create a release twice per build.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@logaretm logaretm force-pushed the awad/js-1076-nitro-upload-sourcemaps branch from ff591f3 to 14b31ea Compare April 18, 2026 03:53
Comment thread packages/nitro/src/sourceMaps.ts
// We don't prepare the artifacts because we injected debug IDs manually before
prepareArtifacts: false,
});
await sentryBuildPluginManager.deleteArtifacts();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Did you manually also check if this deletes the correct source maps - based on the user-set source map setting?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I tried 3 scenarios locally:

  • default: Sourcemaps files get deleted
  • explicit true, sourcemap files is retained
  • disable-upload: retained but not uploaded

I did miss that it should only delete nitro's sourcemaps (fixed now in 1c13825) but not sure what other scenarios to take into account. Also checked that it respects the filesToDeleteAfterUpload option, is that what you meant?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, your scenarios plus:

  • respecting filesToDeleteAfterUpload
  • undefined source maps: setting them to hidden, uploading them and deleting them afterwards

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yep I did test filesToDeleteAfterUpload and it was respected. For hidden, it isn't part of nitro's v3 API but it works under the hood since it forwards it to vite so i'm not sure. I will follow your suggestion still.

logaretm and others added 3 commits April 20, 2026 09:36
`filesToDeleteAfterUpload` previously defaulted to `['**/*.map']`, which
is resolved from the project root and could traverse `node_modules`.
Scope the default to `nitro.options.output.serverDir` so we only touch
maps we generated. Also log the chosen glob in debug mode to match the
Nuxt SDK UX.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@logaretm logaretm requested a review from s1gr1d April 20, 2026 15:25
Comment thread packages/nitro/src/sourceMaps.ts
Comment thread packages/nitro/src/sourceMaps.ts Outdated
}

let sentryEnabledSourcemaps = false;
if (config.sourcemap === true) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

They could also be enabled with 'inline' | 'hidden'

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not part of Nitro's v3 API, it's always a boolean but hidden would work through vite still so I'm not sure what to do here.

Comment thread packages/nitro/src/sourceMaps.ts Outdated
}
} else {
// User did not explicitly set sourcemap — enable it for Sentry
config.sourcemap = true;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
config.sourcemap = true;
config.sourcemap = 'hidden';

It's safer to set them to hidden, if they are not already set by something by the user.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's not part of nitro's API for some reason but it works, so I will follow your suggestion.

Previously when users didn't set `sourcemap`, we set it to `true`, which
causes Nitro/Vite to append `//# sourceMappingURL=` to each output file,
publicly exposing sourcemap references. Switch to `'hidden'` so .map files
are still emitted (and uploaded/deleted by Sentry) without the public
reference comment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
// Nitro types `sourcemap` as `boolean`, but it forwards the value to Vite which supports `'hidden'`.
// `'hidden'` emits .map files without adding a `//# sourceMappingURL=` comment to the output, avoiding public exposure.
(config as { sourcemap?: unknown }).sourcemap = 'hidden';
sentryEnabledSourcemaps = true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Source map config modified unconditionally including dev mode

Medium Severity

configureSourcemapSettings unconditionally sets config.sourcemap = 'hidden' at config construction time, affecting both dev and production builds. While shouldSkipSourcemapUpload correctly skips the upload hook in dev mode, the config-level sourcemap change to 'hidden' persists. This differs from the Nuxt implementation, which defers source map modifications to a lifecycle hook guarded by !nuxt.options.dev. Setting 'hidden' in dev mode removes the //# sourceMappingURL= comment, potentially degrading Node.js source map support during development.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3f30c9a. Configure here.

@logaretm logaretm requested a review from s1gr1d April 21, 2026 18:56
…ne'`)

Nitro types `sourcemap` as `boolean`, but the value is forwarded to Vite
which also accepts `'hidden'` and `'inline'`. The previous logic treated
any non-`true`/`false` value as unset and overwrote it with `'hidden'`
plus default deletion, which (1) clobbered an explicit `'inline'` choice
and (2) auto-deleted `.map` files the user had configured via `'hidden'`.

Now we keep `'hidden'` and `true` as-is (upload, no deletion), warn and
skip upload for `'inline'` (no `.map` files exist to upload), and only
enable hidden + deletion when `sourcemap` is unset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 26a6dd2. Configure here.

prepareArtifacts: false,
});
await sentryBuildPluginManager.deleteArtifacts();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sourcemap disable passed redundantly to plugin manager

Medium Severity

The sourcemaps.disable value (e.g., 'disable-upload') is passed to the bundler plugin manager via getPluginOptions at line 110, AND the same value is manually checked at line 55 to skip uploadSourcemaps/deleteArtifacts. If the plugin manager internally also honors disable: 'disable-upload' (as it does in other SDKs), these calls would be no-ops anyway. But if the plugin manager treats 'disable-upload' as also suppressing createRelease or injectDebugIds internally, those calls on lines 51 and 53 could silently fail. The Next.js implementation avoids this by letting the plugin manager handle disable internally rather than double-gating. Consider either not passing disable to the plugin options (letting the manual orchestration control the flow) or removing the manual check and letting the plugin manager handle it, but not both.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 26a6dd2. Configure here.

@logaretm logaretm merged commit e660250 into awad/create-nitro-sdk-metadata Apr 22, 2026
32 checks passed
@logaretm logaretm deleted the awad/js-1076-nitro-upload-sourcemaps branch April 22, 2026 20:48
logaretm added a commit that referenced this pull request Apr 22, 2026
Implements HTTP server instrumentation for both `h3` and `srvx` by
listening to their tracing channel events.

- `h3` TC PR: h3js/h3#1251
- `srvx` TC PR: h3js/srvx#141

Closes #18123

---

**This PR is part of a stack:**

- #20358
- #19224
- #19225 👈
- #19304

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
logaretm added a commit that referenced this pull request Apr 22, 2026
Adds automatic sourcemap handling to the Nitro SDK, using
`@sentry/bundler-plugin-core` for builder-agnostic post-build upload.

Nitro uses rollup or rolldown, so it made sense to make it as agnostic
as possible.

Closes #17992 

---

**This PR is part of a stack:**

- #20358
- #19224
- #19225
- #19304 👈

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
logaretm added a commit that referenced this pull request Apr 23, 2026
Implements HTTP server instrumentation for both `h3` and `srvx` by
listening to their tracing channel events.

- `h3` TC PR: h3js/h3#1251
- `srvx` TC PR: h3js/srvx#141

Closes #18123

---

**This PR is part of a stack:**

- #20358
- #19224
- #19225 👈
- #19304

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
logaretm added a commit that referenced this pull request Apr 23, 2026
Adds automatic sourcemap handling to the Nitro SDK, using
`@sentry/bundler-plugin-core` for builder-agnostic post-build upload.

Nitro uses rollup or rolldown, so it made sense to make it as agnostic
as possible.

Closes #17992 

---

**This PR is part of a stack:**

- #20358
- #19224
- #19225
- #19304 👈

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
logaretm added a commit that referenced this pull request Apr 23, 2026
This PR just isolates the mundane changes needed for a new SDK to keep
the next stacked PRs clean, it adds the Nitro SDK to the monorepo.

This PR is a base of a stack, the stacked PRs will be merged into it. I
thought this will be easier to review.

---

**This PR is part of a stack:**

- #20358
- #19224 👈
- #19225 
- #19304

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants