@@ -23,6 +23,7 @@ import type {
23
23
UserSentryOptions ,
24
24
WebpackConfigFunction ,
25
25
WebpackConfigObject ,
26
+ WebpackConfigObjectWithModuleRules ,
26
27
WebpackEntryProperty ,
27
28
WebpackModuleRule ,
28
29
WebpackPluginInstance ,
@@ -67,35 +68,33 @@ export function constructWebpackConfigFunction(
67
68
buildContext : BuildContext ,
68
69
) : WebpackConfigObject {
69
70
const { isServer, dev : isDev , dir : projectDir } = buildContext ;
70
- let newConfig = { ...incomingConfig } ;
71
+ let rawNewConfig = { ...incomingConfig } ;
71
72
72
73
// if user has custom webpack config (which always takes the form of a function), run it so we have actual values to
73
74
// work with
74
75
if ( 'webpack' in userNextConfig && typeof userNextConfig . webpack === 'function' ) {
75
- newConfig = userNextConfig . webpack ( newConfig , buildContext ) ;
76
+ rawNewConfig = userNextConfig . webpack ( rawNewConfig , buildContext ) ;
76
77
}
77
78
79
+ // This mutates `rawNewConfig` in place, but also returns it in order to switch its type to one in which
80
+ // `newConfig.module.rules` is required, so we don't have to keep asserting its existence
81
+ const newConfig = setUpModuleRules ( rawNewConfig ) ;
82
+
78
83
if ( isServer ) {
79
- newConfig . module = {
80
- ...newConfig . module ,
81
- rules : [
82
- ...( newConfig . module ?. rules || [ ] ) ,
84
+ newConfig . module . rules . push ( {
85
+ test : / s e n t r y \. s e r v e r \. c o n f i g \. ( j s x ? | t s x ? ) / ,
86
+ use : [
83
87
{
84
- test : / s e n t r y \. s e r v e r \. c o n f i g \. ( j s x ? | t s x ? ) / ,
85
- use : [
86
- {
87
- // Support non-default output directories by making the output path (easy to get here at build-time)
88
- // available to the server SDK's default `RewriteFrames` instance (which needs it at runtime), by
89
- // injecting code to attach it to `global`.
90
- loader : path . resolve ( __dirname , 'loaders/prefixLoader.js' ) ,
91
- options : {
92
- distDir : userNextConfig . distDir || '.next' ,
93
- } ,
94
- } ,
95
- ] ,
88
+ // Support non-default output directories by making the output path (easy to get here at build-time)
89
+ // available to the server SDK's default `RewriteFrames` instance (which needs it at runtime), by
90
+ // injecting code to attach it to `global`.
91
+ loader : path . resolve ( __dirname , 'loaders/prefixLoader.js' ) ,
92
+ options : {
93
+ distDir : userNextConfig . distDir || '.next' ,
94
+ } ,
96
95
} ,
97
96
] ,
98
- } ;
97
+ } ) ;
99
98
100
99
if ( userSentryOptions . autoInstrumentServerFunctions !== false ) {
101
100
const pagesDir = newConfig . resolve ?. alias ?. [ 'private-next-pages' ] as string ;
@@ -628,3 +627,20 @@ function handleSourcemapHidingOptionWarning(userSentryOptions: UserSentryOptions
628
627
// );
629
628
// }
630
629
}
630
+
631
+ /**
632
+ * Ensure that `newConfig.module.rules` exists. Modifies the given config in place but also returns it in order to
633
+ * change its type.
634
+ *
635
+ * @param newConfig A webpack config object which may or may not contain `module` and `module.rules`
636
+ * @returns The same object, with an empty `module.rules` array added if necessary
637
+ */
638
+ function setUpModuleRules ( newConfig : WebpackConfigObject ) : WebpackConfigObjectWithModuleRules {
639
+ newConfig . module = {
640
+ ...newConfig . module ,
641
+ rules : [ ...( newConfig . module ?. rules || [ ] ) ] ,
642
+ } ;
643
+ // Surprising that we have to assert the type here, since we've demonstrably guaranteed the existence of
644
+ // `newConfig.module.rules` just above, but ¯\_(ツ)_/¯
645
+ return newConfig as WebpackConfigObjectWithModuleRules ;
646
+ }
0 commit comments