11/* eslint-disable max-lines */
22import { getSentryRelease } from '@sentry/node' ;
3- import { arrayify , dropUndefinedKeys , escapeStringForRegex , logger } from '@sentry/utils' ;
3+ import { arrayify , dropUndefinedKeys , escapeStringForRegex , logger , stringMatchesSomePattern } from '@sentry/utils' ;
44import { default as SentryWebpackPlugin } from '@sentry/webpack-plugin' ;
55import * as chalk from 'chalk' ;
66import * as fs from 'fs' ;
@@ -91,7 +91,11 @@ export function constructWebpackConfigFunction(
9191 use : [
9292 {
9393 loader : path . resolve ( __dirname , 'loaders/proxyLoader.js' ) ,
94- options : { pagesDir, pageExtensionRegex } ,
94+ options : {
95+ pagesDir,
96+ pageExtensionRegex,
97+ excludeServerRoutes : userSentryOptions . excludeServerRoutes ,
98+ } ,
9599 } ,
96100 ] ,
97101 } ) ;
@@ -135,7 +139,7 @@ export function constructWebpackConfigFunction(
135139 // will call the callback which will call `f` which will call `x.y`... and on and on. Theoretically this could also
136140 // be fixed by using `bind`, but this is way simpler.)
137141 const origEntryProperty = newConfig . entry ;
138- newConfig . entry = async ( ) => addSentryToEntryProperty ( origEntryProperty , buildContext ) ;
142+ newConfig . entry = async ( ) => addSentryToEntryProperty ( origEntryProperty , buildContext , userSentryOptions ) ;
139143
140144 // Enable the Sentry plugin (which uploads source maps to Sentry when not in dev) by default
141145 if ( shouldEnableWebpackPlugin ( buildContext , userSentryOptions ) ) {
@@ -248,6 +252,7 @@ function findTranspilationRules(rules: WebpackModuleRule[] | undefined, projectD
248252async function addSentryToEntryProperty (
249253 currentEntryProperty : WebpackEntryProperty ,
250254 buildContext : BuildContext ,
255+ userSentryOptions : UserSentryOptions ,
251256) : Promise < EntryPropertyObject > {
252257 // The `entry` entry in a webpack config can be a string, array of strings, object, or function. By default, nextjs
253258 // sets it to an async function which returns the promise of an object of string arrays. Because we don't know whether
@@ -268,8 +273,18 @@ async function addSentryToEntryProperty(
268273
269274 // inject into all entry points which might contain user's code
270275 for ( const entryPointName in newEntryProperty ) {
271- if ( shouldAddSentryToEntryPoint ( entryPointName , isServer ) ) {
276+ if ( shouldAddSentryToEntryPoint ( entryPointName , isServer , userSentryOptions . excludeServerRoutes ) ) {
272277 addFilesToExistingEntryPoint ( newEntryProperty , entryPointName , filesToInject ) ;
278+ } else {
279+ if (
280+ isServer &&
281+ // If the user has asked to exclude pages, confirm for them that it's worked
282+ userSentryOptions . excludeServerRoutes &&
283+ // We always skip these, so it's not worth telling the user that we've done so
284+ ! [ 'pages/_app' , 'pages/_document' ] . includes ( entryPointName )
285+ ) {
286+ __DEBUG_BUILD__ && logger . log ( `Skipping Sentry injection for ${ entryPointName . replace ( / ^ p a g e s / , '' ) } ` ) ;
287+ }
273288 }
274289 }
275290
@@ -377,13 +392,21 @@ function checkWebpackPluginOverrides(
377392 *
378393 * @param entryPointName The name of the entry point in question
379394 * @param isServer Whether or not this function is being called in the context of a server build
395+ * @param excludeServerRoutes A list of excluded serverside entrypoints provided by the user
380396 * @returns `true` if sentry code should be injected, and `false` otherwise
381397 */
382- function shouldAddSentryToEntryPoint ( entryPointName : string , isServer : boolean ) : boolean {
398+ function shouldAddSentryToEntryPoint (
399+ entryPointName : string ,
400+ isServer : boolean ,
401+ excludeServerRoutes : Array < string | RegExp > = [ ] ,
402+ ) : boolean {
383403 // On the server side, by default we inject the `Sentry.init()` code into every page (with a few exceptions).
384404 if ( isServer ) {
385405 const entryPointRoute = entryPointName . replace ( / ^ p a g e s / , '' ) ;
386406 if (
407+ // User-specified pages to skip. (Note: For ease of use, `excludeServerRoutes` is specified in terms of routes,
408+ // which don't have the `pages` prefix.)
409+ stringMatchesSomePattern ( entryPointRoute , excludeServerRoutes , true ) ||
387410 // All non-API pages contain both of these components, and we don't want to inject more than once, so as long as
388411 // we're doing the individual pages, it's fine to skip these. (Note: Even if a given user doesn't have either or
389412 // both of these in their `pages/` folder, they'll exist as entrypoints because nextjs will supply default
@@ -462,7 +485,8 @@ export function getWebpackPluginOptions(
462485 configFile : hasSentryProperties ? 'sentry.properties' : undefined ,
463486 stripPrefix : [ 'webpack://_N_E/' ] ,
464487 urlPrefix,
465- entries : ( entryPointName : string ) => shouldAddSentryToEntryPoint ( entryPointName , isServer ) ,
488+ entries : ( entryPointName : string ) =>
489+ shouldAddSentryToEntryPoint ( entryPointName , isServer , userSentryOptions . excludeServerRoutes ) ,
466490 release : getSentryRelease ( buildId ) ,
467491 dryRun : isDev ,
468492 } ) ;
0 commit comments