@sentry/nextjs
Version:
Official Sentry SDK for Next.js
128 lines (125 loc) • 5.01 kB
JavaScript
import { debug, escapeStringForRegex } from '@sentry/core';
import * as path from 'path';
import { getInstrumentedModuleNames } from '@sentry/server-utils/orchestrion/config';
import { resolveOrchestrionRuntimeRequest, serializeInstrumentations, getSentryInstrumentations, getOrchestrionLoaderPath } from '@sentry/server-utils/orchestrion/webpack';
import { getBuildLogger } from '../buildLogger.js';
import { supportsNativeDebugIds, supportsTurbopackRuleCondition } from '../util.js';
import { getTunnelRouteInjectedValues } from '../withSentryConfig/tunnel.js';
import { generateValueInjectionRules } from './generateValueInjectionRules.js';
function constructTurbopackConfig({
userNextConfig,
userSentryOptions,
routeManifest,
nextJsVersion,
vercelCronsConfig
}) {
const shouldEnableNativeDebugIds = (supportsNativeDebugIds(nextJsVersion ?? "") && userNextConfig?.turbopack?.debugIds) ?? userSentryOptions?.sourcemaps?.disable !== true;
const newConfig = {
...userNextConfig.turbopack,
...shouldEnableNativeDebugIds ? { debugIds: true } : {}
};
const valueInjectionRules = generateValueInjectionRules({
routeManifest,
nextJsVersion,
tunnelRouteValues: getTunnelRouteInjectedValues(userNextConfig, userSentryOptions),
vercelCronsConfig
});
for (const { matcher, rule } of valueInjectionRules) {
newConfig.rules = safelyAddTurbopackRule(newConfig.rules, { matcher, rule });
}
const applicationKey = userSentryOptions?.applicationKey;
if (applicationKey && nextJsVersion && supportsTurbopackRuleCondition(nextJsVersion)) {
newConfig.rules = safelyAddTurbopackRule(newConfig.rules, {
matcher: "*.{ts,tsx,js,jsx,mjs,cjs}",
rule: {
condition: {
all: [
"browser",
{ not: { path: /next\/dist\/build\/polyfills/ } },
...userSentryOptions?.applicationKeyExcludeDependencies ? [{ not: "foreign" }] : []
]
},
loaders: [
{
loader: path.resolve(__dirname, "..", "loaders", "moduleMetadataInjectionLoader.js"),
options: {
applicationKey
}
}
]
}
});
}
const reactComponentAnnotation = {
...userSentryOptions?.reactComponentAnnotation,
// eslint-disable-next-line typescript/no-deprecated
...userSentryOptions?._experimental?.turbopackReactComponentAnnotation
};
if (reactComponentAnnotation.enabled) {
if (nextJsVersion && supportsTurbopackRuleCondition(nextJsVersion)) {
newConfig.rules = safelyAddTurbopackRule(newConfig.rules, {
matcher: "*.{tsx,jsx}",
rule: {
condition: { not: "foreign" },
loaders: [
{
loader: path.resolve(__dirname, "..", "loaders", "componentAnnotationLoader.js"),
options: {
ignoredComponents: reactComponentAnnotation.ignoredComponents ?? []
}
}
]
}
});
} else {
getBuildLogger(userSentryOptions?.silent).warn(
`[@sentry/nextjs] \`reactComponentAnnotation\` is enabled but React component annotation requires Next.js 16+ on Turbopack builds${nextJsVersion ? ` (detected ${nextJsVersion})` : ""}. Your components will not be annotated.`
);
}
}
newConfig.rules = maybeAddOrchestrionRule(newConfig.rules, userSentryOptions, nextJsVersion);
return newConfig;
}
function maybeAddOrchestrionRule(rules, userSentryOptions, nextJsVersion) {
if (userSentryOptions?.buildTimeInstrumentation === false || !nextJsVersion || !supportsTurbopackRuleCondition(nextJsVersion)) {
return rules;
}
const importHelperPath = resolveOrchestrionRuntimeRequest("@sentry/server-utils");
const instrumentedPackages = getInstrumentedModuleNames().map(escapeStringForRegex);
const instrumentedPackagePath = new RegExp(`node_modules/(?:${instrumentedPackages.join("|")})/`);
return safelyAddTurbopackRule(rules, {
matcher: "*.{js,mjs,cjs}",
rule: {
condition: { all: ["node", { path: instrumentedPackagePath }] },
loaders: [
{
loader: getOrchestrionLoaderPath(),
// Turbopack JSON-serializes loader options, so a RegExp `filePath` must be encoded first.
options: {
instrumentations: serializeInstrumentations(getSentryInstrumentations()),
...importHelperPath ? { importHelperPath } : {}
}
}
]
}
});
}
function safelyAddTurbopackRule(existingRules, { matcher, rule }) {
if (!existingRules) {
return {
[matcher]: rule
};
}
if (existingRules[matcher]) {
debug.log(
`[@sentry/nextjs] - Turbopack rule already exists for ${matcher}. Please remove it from your Next.js config in order for Sentry to work properly.`
);
return existingRules;
}
return {
...existingRules,
[matcher]: rule
};
}
export { constructTurbopackConfig, safelyAddTurbopackRule };
//# sourceMappingURL=constructTurbopackConfig.js.map