From 0e610a9403aa97807ee670ffb7a6d469d2ff2cf8 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Thu, 21 Jul 2022 15:05:41 -0700 Subject: [PATCH] switch to using loader for setting `RewriteFrames` global variable --- packages/nextjs/src/config/webpack.ts | 41 ++++++++++++++++----------- packages/nextjs/src/index.server.ts | 2 +- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index f255925d9b99..347baa09d49b 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -3,7 +3,6 @@ import { getSentryRelease } from '@sentry/node'; import { dropUndefinedKeys, logger } from '@sentry/utils'; import { default as SentryWebpackPlugin } from '@sentry/webpack-plugin'; import * as fs from 'fs'; -import * as os from 'os'; import * as path from 'path'; import { @@ -51,6 +50,29 @@ export function constructWebpackConfigFunction( newConfig = userNextConfig.webpack(newConfig, buildContext); } + if (isServer) { + newConfig.module = { + ...newConfig.module, + rules: [ + ...(newConfig.module?.rules || []), + { + test: /sentry\.server\.config\.(jsx?|tsx?)/, + use: [ + { + // Support non-default output directories by making the output path (easy to get here at build-time) + // available to the server SDK's default `RewriteFrames` instance (which needs it at runtime), by + // injecting code to attach it to `global`. + loader: path.resolve(__dirname, 'prefixLoader.js'), + options: { + distDir: userNextConfig.distDir || '.next', + }, + }, + ], + }, + ], + }; + } + // Tell webpack to inject user config files (containing the two `Sentry.init()` calls) into the appropriate output // bundles. Store a separate reference to the original `entry` value to avoid an infinite loop. (If we don't do // this, we'll have a statement of the form `x.y = () => f(x.y)`, where one of the things `f` does is call `x.y`. @@ -121,7 +143,7 @@ async function addSentryToEntryProperty( // we know is that it won't have gotten *simpler* in form, so we only need to worry about the object and function // options. See https://webpack.js.org/configuration/entry-context/#entry. - const { isServer, dir: projectDir, dev: isDev, config: userNextConfig } = buildContext; + const { isServer, dir: projectDir } = buildContext; const newEntryProperty = typeof currentEntryProperty === 'function' ? await currentEntryProperty() : { ...currentEntryProperty }; @@ -132,21 +154,6 @@ async function addSentryToEntryProperty( // we need to turn the filename into a path so webpack can find it const filesToInject = [`./${userConfigFile}`]; - // Support non-default output directories by making the output path (easy to get here at build-time) available to the - // server SDK's default `RewriteFrames` instance (which needs it at runtime). Doesn't work when using the dev server - // because it somehow tricks the file watcher into thinking that compilation itself is a file change, triggering an - // infinite recompiling loop. (This should be fine because we don't upload sourcemaps in dev in any case.) - if (isServer && !isDev) { - const rewriteFramesHelper = path.resolve( - fs.mkdtempSync(path.resolve(os.tmpdir(), 'sentry-')), - 'rewriteFramesHelper.js', - ); - fs.writeFileSync(rewriteFramesHelper, `global.__rewriteFramesDistDir__ = '${userNextConfig.distDir}';\n`); - // stick our helper file ahead of the user's config file so the value is in the global namespace *before* - // `Sentry.init()` is called - filesToInject.unshift(rewriteFramesHelper); - } - // inject into all entry points which might contain user's code for (const entryPointName in newEntryProperty) { if (shouldAddSentryToEntryPoint(entryPointName, isServer)) { diff --git a/packages/nextjs/src/index.server.ts b/packages/nextjs/src/index.server.ts index 76094b8deb0b..c4109e6598e5 100644 --- a/packages/nextjs/src/index.server.ts +++ b/packages/nextjs/src/index.server.ts @@ -110,7 +110,7 @@ function sdkAlreadyInitialized(): boolean { function addServerIntegrations(options: NextjsOptions): void { // This value is injected at build time, based on the output directory specified in the build config - const distDirName = (global as GlobalWithDistDir).__rewriteFramesDistDir__ || '.next'; + const distDirName = (global as GlobalWithDistDir).__rewriteFramesDistDir__; // nextjs always puts the build directory at the project root level, which is also where you run `next start` from, so // we can read in the project directory from the currently running process const distDirAbsPath = path.resolve(process.cwd(), distDirName);