@@ -2,11 +2,13 @@ import { getSentryRelease } from '@sentry/node';
2
2
import { logger } from '@sentry/utils' ;
3
3
import defaultWebpackPlugin , { SentryCliPluginOptions } from '@sentry/webpack-plugin' ;
4
4
import * as SentryWebpackPlugin from '@sentry/webpack-plugin' ;
5
+ import * as fs from 'fs' ;
6
+ import * as path from 'path' ;
5
7
6
8
const SENTRY_CLIENT_CONFIG_FILE = './sentry.client.config.js' ;
7
9
const SENTRY_SERVER_CONFIG_FILE = './sentry.server.config.js' ;
8
10
// this is where the transpiled/bundled version of `USER_SERVER_CONFIG_FILE` will end up
9
- export const SERVER_INIT_OUTPUT_LOCATION = 'sentry/serverInit ' ;
11
+ export const SERVER_SDK_INIT_PATH = 'sentry/initServer.js ' ;
10
12
11
13
// eslint-disable-next-line @typescript-eslint/no-explicit-any
12
14
type PlainObject < T = any > = { [ key : string ] : T } ;
@@ -15,7 +17,14 @@ type PlainObject<T = any> = { [key: string]: T };
15
17
type WebpackExport = ( config : WebpackConfig , options : WebpackOptions ) => WebpackConfig ;
16
18
17
19
// The two arguments passed to the exported `webpack` function, as well as the thing it returns
18
- type WebpackConfig = { devtool : string ; plugins : PlainObject [ ] ; entry : EntryProperty ; output : { path : string } } ;
20
+ type WebpackConfig = {
21
+ devtool : string ;
22
+ plugins : PlainObject [ ] ;
23
+ entry : EntryProperty ;
24
+ output : { path : string } ;
25
+ target : string ;
26
+ context : string ;
27
+ } ;
19
28
type WebpackOptions = { dev : boolean ; isServer : boolean ; buildId : string } ;
20
29
21
30
// For our purposes, the value for `entry` is either an object, or a function which returns such an object
@@ -87,7 +96,7 @@ const injectSentry = async (origEntryProperty: EntryProperty, isServer: boolean)
87
96
// `require()` on the resulting file when we're instrumenting the sesrver. (We can't use a dynamic import there
88
97
// because that then forces the user into a particular TS config.)
89
98
if ( isServer ) {
90
- newEntryProperty [ SERVER_INIT_OUTPUT_LOCATION ] = SENTRY_SERVER_CONFIG_FILE ;
99
+ newEntryProperty [ SERVER_SDK_INIT_PATH ] = SENTRY_SERVER_CONFIG_FILE ;
91
100
}
92
101
// On the client, it's sufficient to inject it into the `main` JS code, which is included in every browser page.
93
102
else {
@@ -144,6 +153,12 @@ export function withSentryConfig(
144
153
}
145
154
146
155
const newWebpackExport = ( config : WebpackConfig , options : WebpackOptions ) : WebpackConfig => {
156
+ // if we're building server code, store the webpack output path as an env variable, so we know where to look for the
157
+ // webpack-processed version of `sentry.server.config.js` when we need it
158
+ if ( config . target === 'node' ) {
159
+ memoizeOutputPath ( config ) ;
160
+ }
161
+
147
162
let newConfig = config ;
148
163
149
164
if ( typeof providedExports . webpack === 'function' ) {
@@ -181,3 +196,23 @@ export function withSentryConfig(
181
196
webpack : newWebpackExport ,
182
197
} ;
183
198
}
199
+
200
+ /**
201
+ * Store the future location of the webpack-processed version of `sentry.server.config.js` in a runtime env variable, so
202
+ * we know where to find it when we want to initialize the SDK.
203
+ *
204
+ * @param config The webpack config object for this build
205
+ */
206
+ function memoizeOutputPath ( config : WebpackConfig ) : void {
207
+ const builtServerSDKInitPath = path . join ( config . output . path , SERVER_SDK_INIT_PATH ) ;
208
+ const projectDir = config . context ;
209
+ // next will automatically set variables from `.env.local` in `process.env` at runtime
210
+ const envFilePath = path . join ( projectDir , '.env.local' ) ;
211
+ const envVarString = `SENTRY_SERVER_INIT_PATH=${ builtServerSDKInitPath } \n` ;
212
+
213
+ if ( fs . existsSync ( envFilePath ) ) {
214
+ fs . appendFileSync ( envFilePath , `\n${ envVarString } ` ) ;
215
+ } else {
216
+ fs . writeFileSync ( envFilePath , envVarString ) ;
217
+ }
218
+ }
0 commit comments