Skip to content

Commit

Permalink
switch to using loader for setting RewriteFrames global variable
Browse files Browse the repository at this point in the history
  • Loading branch information
lobsterkatie committed Jul 22, 2022
1 parent ac622db commit 0e610a9
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 18 deletions.
41 changes: 24 additions & 17 deletions packages/nextjs/src/config/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -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 };
Expand All @@ -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)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 0e610a9

Please sign in to comment.