-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathconstructTurbopackConfig.ts
More file actions
136 lines (125 loc) · 4.85 KB
/
constructTurbopackConfig.ts
File metadata and controls
136 lines (125 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { debug } from '@sentry/core';
import * as path from 'path';
import type { VercelCronsConfig } from '../../common/types';
import type { RouteManifest } from '../manifest/types';
import type { NextConfigObject, SentryBuildOptions, TurbopackMatcherWithRule, TurbopackOptions } from '../types';
import { supportsNativeDebugIds, supportsTurbopackRuleCondition } from '../util';
import { generateValueInjectionRules } from './generateValueInjectionRules';
/**
* Construct a Turbopack config object from a Next.js config object and a Turbopack options object.
*
* @param userNextConfig - The Next.js config object.
* @param userSentryOptions - The Sentry build options object.
* @param routeManifest - The route manifest object.
* @param nextJsVersion - The Next.js version.
* @param vercelCronsConfig - The Vercel crons configuration from vercel.json.
* @returns The Turbopack config object.
*/
export function constructTurbopackConfig({
userNextConfig,
userSentryOptions,
routeManifest,
nextJsVersion,
vercelCronsConfig,
}: {
userNextConfig: NextConfigObject;
userSentryOptions?: SentryBuildOptions;
routeManifest?: RouteManifest;
nextJsVersion?: string;
vercelCronsConfig?: VercelCronsConfig;
}): TurbopackOptions {
// If sourcemaps are disabled, we don't need to enable native debug ids as this will add build time.
const shouldEnableNativeDebugIds =
(supportsNativeDebugIds(nextJsVersion ?? '') && userNextConfig?.turbopack?.debugIds) ??
userSentryOptions?.sourcemaps?.disable !== true;
const newConfig: TurbopackOptions = {
...userNextConfig.turbopack,
...(shouldEnableNativeDebugIds ? { debugIds: true } : {}),
};
const tunnelPath =
userSentryOptions?.tunnelRoute !== undefined &&
userNextConfig.output !== 'export' &&
typeof userSentryOptions.tunnelRoute === 'string'
? `${userNextConfig.basePath ?? ''}${userSentryOptions.tunnelRoute}`
: undefined;
const valueInjectionRules = generateValueInjectionRules({
routeManifest,
nextJsVersion,
tunnelPath,
vercelCronsConfig,
});
for (const { matcher, rule } of valueInjectionRules) {
newConfig.rules = safelyAddTurbopackRule(newConfig.rules, { matcher, rule });
}
// Add module metadata injection loader for thirdPartyErrorFilterIntegration support.
// This is only added when turbopackApplicationKey is set AND the Next.js version supports the
// `condition` field in Turbopack rules (Next.js 16+). Without `condition: { not: 'foreign' }`,
// the loader would tag node_modules as first-party, defeating the purpose.
const applicationKey = userSentryOptions?._experimental?.turbopackApplicationKey;
if (applicationKey && nextJsVersion && supportsTurbopackRuleCondition(nextJsVersion)) {
newConfig.rules = safelyAddTurbopackRule(newConfig.rules, {
matcher: '*.{ts,tsx,js,jsx,mjs,cjs}',
rule: {
condition: { not: 'foreign' },
loaders: [
{
loader: path.resolve(__dirname, '..', 'loaders', 'moduleMetadataInjectionLoader.js'),
options: {
applicationKey,
},
},
],
},
});
}
// Add component annotation loader for react component name annotation in Turbopack builds.
// This is only added when turbopackReactComponentAnnotation.enabled is set AND the Next.js
// version supports the `condition` field in Turbopack rules (Next.js 16+).
const turbopackReactComponentAnnotation = userSentryOptions?._experimental?.turbopackReactComponentAnnotation;
if (turbopackReactComponentAnnotation?.enabled && 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: turbopackReactComponentAnnotation.ignoredComponents ?? [],
},
},
],
},
});
}
return newConfig;
}
/**
* Safely add a Turbopack rule to the existing rules.
*
* @param existingRules - The existing rules.
* @param matcher - The matcher for the rule.
* @param rule - The rule to add.
* @returns The updated rules object.
*/
export function safelyAddTurbopackRule(
existingRules: TurbopackOptions['rules'],
{ matcher, rule }: TurbopackMatcherWithRule,
): TurbopackOptions['rules'] {
if (!existingRules) {
return {
[matcher]: rule,
};
}
// If the rule already exists, we don't want to mess with it.
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,
};
}