123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119 |
- var {
- _nullishCoalesce,
- _optionalChain
- } = require('@sentry/utils');
- Object.defineProperty(exports, '__esModule', { value: true });
- const fs = require('fs');
- const path = require('path');
- const node = require('@sentry/node');
- const utils = require('@sentry/utils');
- const chalk = require('chalk');
- const resolve = require('resolve');
- const debugBuild = require('../common/debug-build.js');
- const RUNTIME_TO_SDK_ENTRYPOINT_MAP = {
- client: './client',
- server: './server',
- edge: './edge',
- } ;
- let showedMissingAuthTokenErrorMsg = false;
- let showedMissingOrgSlugErrorMsg = false;
- let showedMissingProjectSlugErrorMsg = false;
- let showedHiddenSourceMapsWarningMsg = false;
- let showedMissingCliBinaryWarningMsg = false;
- let showedMissingGlobalErrorWarningMsg = false;
- function constructWebpackConfigFunction(
- userNextConfig = {},
- userSentryWebpackPluginOptions = {},
- userSentryOptions = {},
- ) {
-
-
-
- return function newWebpackFunction(
- incomingConfig,
- buildContext,
- ) {
- const { isServer, dev: isDev, dir: projectDir } = buildContext;
- const runtime = isServer ? (buildContext.nextRuntime === 'edge' ? 'edge' : 'server') : 'client';
- let rawNewConfig = { ...incomingConfig };
-
-
- if ('webpack' in userNextConfig && typeof userNextConfig.webpack === 'function') {
- rawNewConfig = userNextConfig.webpack(rawNewConfig, buildContext);
- }
-
-
- const newConfig = setUpModuleRules(rawNewConfig);
-
- addValueInjectionLoader(newConfig, userNextConfig, userSentryOptions, buildContext, userSentryWebpackPluginOptions);
- newConfig.module.rules.push({
- test: /node_modules[/\\]@sentry[/\\]nextjs/,
- use: [
- {
- loader: path.resolve(__dirname, 'loaders', 'sdkMultiplexerLoader.js'),
- options: {
- importTarget: RUNTIME_TO_SDK_ENTRYPOINT_MAP[runtime],
- },
- },
- ],
- });
- let pagesDirPath;
- const maybePagesDirPath = path.join(projectDir, 'pages');
- const maybeSrcPagesDirPath = path.join(projectDir, 'src', 'pages');
- if (fs.existsSync(maybePagesDirPath) && fs.lstatSync(maybePagesDirPath).isDirectory()) {
- pagesDirPath = maybePagesDirPath;
- } else if (fs.existsSync(maybeSrcPagesDirPath) && fs.lstatSync(maybeSrcPagesDirPath).isDirectory()) {
- pagesDirPath = maybeSrcPagesDirPath;
- }
- let appDirPath;
- const maybeAppDirPath = path.join(projectDir, 'app');
- const maybeSrcAppDirPath = path.join(projectDir, 'src', 'app');
- if (fs.existsSync(maybeAppDirPath) && fs.lstatSync(maybeAppDirPath).isDirectory()) {
- appDirPath = maybeAppDirPath;
- } else if (fs.existsSync(maybeSrcAppDirPath) && fs.lstatSync(maybeSrcAppDirPath).isDirectory()) {
- appDirPath = maybeSrcAppDirPath;
- }
- const apiRoutesPath = pagesDirPath ? path.join(pagesDirPath, 'api') : undefined;
- const middlewareLocationFolder = pagesDirPath
- ? path.join(pagesDirPath, '..')
- : appDirPath
- ? path.join(appDirPath, '..')
- : projectDir;
-
- const pageExtensions = userNextConfig.pageExtensions || ['tsx', 'ts', 'jsx', 'js'];
- const dotPrefixedPageExtensions = pageExtensions.map(ext => `.${ext}`);
- const pageExtensionRegex = pageExtensions.map(utils.escapeStringForRegex).join('|');
- const staticWrappingLoaderOptions = {
- appDir: appDirPath,
- pagesDir: pagesDirPath,
- pageExtensionRegex,
- excludeServerRoutes: userSentryOptions.excludeServerRoutes,
- sentryConfigFilePath: getUserConfigFilePath(projectDir, runtime),
- nextjsRequestAsyncStorageModulePath: getRequestAsyncStorageModuleLocation(
- projectDir,
- _optionalChain([rawNewConfig, 'access', _ => _.resolve, 'optionalAccess', _2 => _2.modules]),
- ),
- };
- const normalizeLoaderResourcePath = (resourcePath) => {
-
- let absoluteResourcePath;
- if (path.isAbsolute(resourcePath)) {
- absoluteResourcePath = resourcePath;
- } else {
- absoluteResourcePath = path.join(projectDir, resourcePath);
- }
- return path.normalize(absoluteResourcePath);
- };
- const isPageResource = (resourcePath) => {
- const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath);
- return (
- pagesDirPath !== undefined &&
- normalizedAbsoluteResourcePath.startsWith(pagesDirPath + path.sep) &&
- !normalizedAbsoluteResourcePath.startsWith(apiRoutesPath + path.sep) &&
- dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext))
- );
- };
- const isApiRouteResource = (resourcePath) => {
- const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath);
- return (
- normalizedAbsoluteResourcePath.startsWith(apiRoutesPath + path.sep) &&
- dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext))
- );
- };
- const possibleMiddlewareLocations = ['js', 'jsx', 'ts', 'tsx'].map(middlewareFileEnding => {
- return path.join(middlewareLocationFolder, `middleware.${middlewareFileEnding}`);
- });
- const isMiddlewareResource = (resourcePath) => {
- const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath);
- return possibleMiddlewareLocations.includes(normalizedAbsoluteResourcePath);
- };
- const isServerComponentResource = (resourcePath) => {
- const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath);
-
-
- return (
- appDirPath !== undefined &&
- normalizedAbsoluteResourcePath.startsWith(appDirPath + path.sep) &&
- !!normalizedAbsoluteResourcePath.match(/[\\/](page|layout|loading|head|not-found)\.(js|jsx|tsx)$/)
- );
- };
- const isRouteHandlerResource = (resourcePath) => {
- const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath);
- return (
- appDirPath !== undefined &&
- normalizedAbsoluteResourcePath.startsWith(appDirPath + path.sep) &&
- !!normalizedAbsoluteResourcePath.match(/[\\/]route\.(js|jsx|ts|tsx)$/)
- );
- };
- if (isServer && userSentryOptions.autoInstrumentServerFunctions !== false) {
-
-
- newConfig.module.rules.unshift({
- test: isPageResource,
- use: [
- {
- loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'),
- options: {
- ...staticWrappingLoaderOptions,
- wrappingTargetKind: 'page',
- },
- },
- ],
- });
- let vercelCronsConfig = undefined;
- try {
- if (process.env.VERCEL && userSentryOptions.automaticVercelMonitors) {
-
- vercelCronsConfig = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'vercel.json'), 'utf8')).crons;
- if (vercelCronsConfig) {
- utils.logger.info(
- `${chalk.cyan(
- 'info',
- )} - Creating Sentry cron monitors for your Vercel Cron Jobs. You can disable this feature by setting the ${chalk.bold.cyan(
- 'automaticVercelMonitors',
- )} option to false in you Next.js config.`,
- );
- }
- }
- } catch (e) {
- if ((e ).code === 'ENOENT') ; else {
-
- utils.logger.error(`${chalk.red('error')} - Sentry failed to read vercel.json`, e);
- }
- }
-
- newConfig.module.rules.unshift({
- test: isApiRouteResource,
- use: [
- {
- loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'),
- options: {
- ...staticWrappingLoaderOptions,
- vercelCronsConfig,
- wrappingTargetKind: 'api-route',
- },
- },
- ],
- });
-
- if (_nullishCoalesce(userSentryOptions.autoInstrumentMiddleware, () => ( true))) {
- newConfig.module.rules.unshift({
- test: isMiddlewareResource,
- use: [
- {
- loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'),
- options: {
- ...staticWrappingLoaderOptions,
- wrappingTargetKind: 'middleware',
- },
- },
- ],
- });
- }
- }
- if (isServer && userSentryOptions.autoInstrumentAppDirectory !== false) {
-
- newConfig.module.rules.unshift({
- test: isServerComponentResource,
- use: [
- {
- loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'),
- options: {
- ...staticWrappingLoaderOptions,
- wrappingTargetKind: 'server-component',
- },
- },
- ],
- });
-
- newConfig.module.rules.unshift({
- test: isRouteHandlerResource,
- use: [
- {
- loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'),
- options: {
- ...staticWrappingLoaderOptions,
- wrappingTargetKind: 'route-handler',
- },
- },
- ],
- });
- }
- if (isServer) {
-
- newConfig.module.rules.unshift({
- test: resourcePath => {
- return (
- isPageResource(resourcePath) ||
- isApiRouteResource(resourcePath) ||
- isMiddlewareResource(resourcePath) ||
- isServerComponentResource(resourcePath) ||
- isRouteHandlerResource(resourcePath)
- );
- },
- use: [
- {
- loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'),
- options: {
- ...staticWrappingLoaderOptions,
- wrappingTargetKind: 'sentry-init',
- },
- },
- ],
- });
- }
- if (appDirPath) {
- const hasGlobalErrorFile = ['global-error.js', 'global-error.jsx', 'global-error.ts', 'global-error.tsx'].some(
- globalErrorFile => fs.existsSync(path.join(appDirPath, globalErrorFile)),
- );
- if (!hasGlobalErrorFile && !showedMissingGlobalErrorWarningMsg) {
-
- console.log(
- `${chalk.yellow(
- 'warn',
- )} - It seems like you don't have a global error handler set up. It is recommended that you add a ${chalk.cyan(
- 'global-error.js',
- )} file with Sentry instrumentation so that React rendering errors are reported to Sentry. Read more: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#react-render-errors-in-app-router`,
- );
- showedMissingGlobalErrorWarningMsg = true;
- }
- }
-
-
-
-
- if (!isServer && _optionalChain([userSentryOptions, 'optionalAccess', _3 => _3.transpileClientSDK])) {
-
- const transpilationRules = findTranspilationRules(_optionalChain([newConfig, 'access', _4 => _4.module, 'optionalAccess', _5 => _5.rules]), projectDir);
-
-
- transpilationRules.forEach(rule => {
-
- if (rule.exclude && typeof rule.exclude === 'function') {
- const origExclude = rule.exclude;
- const newExclude = (filepath) => {
- if (filepath.includes('@sentry')) {
-
- return false;
- }
- return origExclude(filepath);
- };
- rule.exclude = newExclude;
- }
- });
- }
-
-
-
-
-
-
-
-
- const origEntryProperty = newConfig.entry;
- newConfig.entry = async () => addSentryToEntryProperty(origEntryProperty, buildContext, userSentryOptions);
-
- if (shouldEnableWebpackPlugin(buildContext, userSentryOptions)) {
-
-
-
- handleSourcemapHidingOptionWarning(userSentryOptions, isServer);
-
-
- if (!isDev) {
-
-
-
-
-
-
- newConfig.devtool = userSentryOptions.hideSourceMaps && !isServer ? 'hidden-source-map' : 'source-map';
- const SentryWebpackPlugin = utils.loadModule('@sentry/webpack-plugin');
- if (SentryWebpackPlugin) {
- newConfig.plugins = newConfig.plugins || [];
- newConfig.plugins.push(new SentryCliDownloadPlugin());
- newConfig.plugins.push(
-
- new SentryWebpackPlugin(
- getWebpackPluginOptions(buildContext, userSentryWebpackPluginOptions, userSentryOptions),
- ),
- );
- }
- }
- }
- if (userSentryOptions.disableLogger) {
- newConfig.plugins = newConfig.plugins || [];
- newConfig.plugins.push(
- new buildContext.webpack.DefinePlugin({
- __SENTRY_DEBUG__: false,
- }),
- );
- }
- return newConfig;
- };
- }
- function isMatchingRule(rule, projectDir) {
-
-
- const samplePagePath = path.resolve(projectDir, 'pageFile.js');
- if (rule.test && rule.test instanceof RegExp && !rule.test.test(samplePagePath)) {
- return false;
- }
- if (Array.isArray(rule.include) && !rule.include.includes(projectDir)) {
- return false;
- }
-
- const useEntries = utils.arrayify(rule.use);
-
-
-
-
-
-
-
-
- if (!useEntries.some(entry => _optionalChain([entry, 'optionalAccess', _6 => _6.loader]) && /next.*(babel|swc).*loader/.test(entry.loader))) {
- return false;
- }
- return true;
- }
- function findTranspilationRules(rules, projectDir) {
- if (!rules) {
- return [];
- }
- const matchingRules = [];
-
-
- rules.forEach(rule => {
-
- if (isMatchingRule(rule, projectDir)) {
- matchingRules.push(rule);
- } else if (rule.oneOf) {
- const matchingOneOfRules = rule.oneOf.filter(oneOfRule => isMatchingRule(oneOfRule, projectDir));
- matchingRules.push(...matchingOneOfRules);
-
- }
- });
- return matchingRules;
- }
- async function addSentryToEntryProperty(
- currentEntryProperty,
- buildContext,
- userSentryOptions,
- ) {
-
-
-
-
-
- const { isServer, dir: projectDir, nextRuntime, dev: isDevMode } = buildContext;
- const runtime = isServer ? (buildContext.nextRuntime === 'edge' ? 'edge' : 'node') : 'browser';
- const newEntryProperty =
- typeof currentEntryProperty === 'function' ? await currentEntryProperty() : { ...currentEntryProperty };
-
- const userConfigFile =
- nextRuntime === 'edge'
- ? getUserConfigFile(projectDir, 'edge')
- : isServer
- ? getUserConfigFile(projectDir, 'server')
- : getUserConfigFile(projectDir, 'client');
-
- const filesToInject = userConfigFile ? [`./${userConfigFile}`] : [];
-
- for (const entryPointName in newEntryProperty) {
- if (shouldAddSentryToEntryPoint(entryPointName, runtime)) {
- addFilesToExistingEntryPoint(newEntryProperty, entryPointName, filesToInject, isDevMode);
- } else {
- if (
- isServer &&
-
- userSentryOptions.excludeServerRoutes &&
-
- !['pages/_app', 'pages/_document'].includes(entryPointName)
- ) {
- debugBuild.DEBUG_BUILD && utils.logger.log(`Skipping Sentry injection for ${entryPointName.replace(/^pages/, '')}`);
- }
- }
- }
- return newEntryProperty;
- }
- function getUserConfigFile(projectDir, platform) {
- const possibilities = [`sentry.${platform}.config.ts`, `sentry.${platform}.config.js`];
- for (const filename of possibilities) {
- if (fs.existsSync(path.resolve(projectDir, filename))) {
- return filename;
- }
- }
-
- if (platform === 'edge') {
-
- console.warn(
- '[@sentry/nextjs] You are using Next.js features that run on the Edge Runtime. Please add a "sentry.edge.config.js" or a "sentry.edge.config.ts" file to your project root in which you initialize the Sentry SDK with "Sentry.init()".',
- );
- return;
- } else {
- throw new Error(`Cannot find '${possibilities[0]}' or '${possibilities[1]}' in '${projectDir}'.`);
- }
- }
- function getUserConfigFilePath(projectDir, platform) {
- const possibilities = [`sentry.${platform}.config.ts`, `sentry.${platform}.config.js`];
- for (const filename of possibilities) {
- const configPath = path.resolve(projectDir, filename);
- if (fs.existsSync(configPath)) {
- return configPath;
- }
- }
- return undefined;
- }
- function addFilesToExistingEntryPoint(
- entryProperty,
- entryPointName,
- filesToInsert,
- isDevMode,
- ) {
-
-
-
-
- const currentEntryPoint = entryProperty[entryPointName];
- let newEntryPoint = currentEntryPoint;
- if (typeof currentEntryPoint === 'string' || Array.isArray(currentEntryPoint)) {
- newEntryPoint = utils.arrayify(currentEntryPoint);
- if (newEntryPoint.some(entry => filesToInsert.includes(entry))) {
- return;
- }
- if (isDevMode) {
-
- newEntryPoint.push(...filesToInsert);
- } else {
-
- newEntryPoint.unshift(...filesToInsert);
- }
- }
-
- else if (typeof currentEntryPoint === 'object' && 'import' in currentEntryPoint) {
- const currentImportValue = currentEntryPoint.import;
- const newImportValue = utils.arrayify(currentImportValue);
- if (newImportValue.some(entry => filesToInsert.includes(entry))) {
- return;
- }
- if (isDevMode) {
-
- newImportValue.push(...filesToInsert);
- } else {
-
- newImportValue.unshift(...filesToInsert);
- }
- newEntryPoint = {
- ...currentEntryPoint,
- import: newImportValue,
- };
- }
-
-
- else {
-
- console.error(
- 'Sentry Logger [Error]:',
- `Could not inject SDK initialization code into entry point ${entryPointName}, as its current value is not in a recognized format.\n`,
- 'Expected: string | Array<string> | { [key:string]: any, import: string | Array<string> }\n',
- `Got: ${currentEntryPoint}`,
- );
- }
- entryProperty[entryPointName] = newEntryPoint;
- }
- function checkWebpackPluginOverrides(
- defaultOptions,
- userOptions,
- ) {
-
- const sentryWebpackPluginOptionOverrides = Object.keys(defaultOptions).filter(key => key in userOptions);
- if (sentryWebpackPluginOptionOverrides.length > 0) {
- debugBuild.DEBUG_BUILD &&
- utils.logger.warn(
- '[Sentry] You are overriding the following automatically-set SentryWebpackPlugin config options:\n' +
- `\t${sentryWebpackPluginOptionOverrides.toString()},\n` +
- "which has the possibility of breaking source map upload and application. This is only a good idea if you know what you're doing.",
- );
- }
- }
- function shouldAddSentryToEntryPoint(entryPointName, runtime) {
- return (
- runtime === 'browser' &&
- (entryPointName === 'pages/_app' ||
-
- entryPointName === 'main-app')
- );
- }
- function getWebpackPluginOptions(
- buildContext,
- userPluginOptions,
- userSentryOptions,
- ) {
- const { buildId, isServer, config, dir: projectDir } = buildContext;
- const userNextConfig = config ;
- const distDirAbsPath = path.resolve(projectDir, userNextConfig.distDir || '.next');
- const isServerless = userNextConfig.target === 'experimental-serverless-trace';
- const hasSentryProperties = fs.existsSync(path.resolve(projectDir, 'sentry.properties'));
- const urlPrefix = '~/_next';
- const serverInclude = isServerless
- ? [{ paths: [`${distDirAbsPath}/serverless/`], urlPrefix: `${urlPrefix}/serverless` }]
- : [{ paths: [`${distDirAbsPath}/server/`], urlPrefix: `${urlPrefix}/server` }];
- const serverIgnore = [];
- const clientInclude = userSentryOptions.widenClientFileUpload
- ? [{ paths: [`${distDirAbsPath}/static/chunks`], urlPrefix: `${urlPrefix}/static/chunks` }]
- : [
- { paths: [`${distDirAbsPath}/static/chunks/pages`], urlPrefix: `${urlPrefix}/static/chunks/pages` },
- { paths: [`${distDirAbsPath}/static/chunks/app`], urlPrefix: `${urlPrefix}/static/chunks/app` },
- ];
-
-
-
- const clientIgnore = userSentryOptions.widenClientFileUpload
- ? ['framework-*', 'framework.*', 'main-*', 'polyfills-*', 'webpack-*']
- : [];
- const defaultPluginOptions = utils.dropUndefinedKeys({
- include: isServer ? serverInclude : clientInclude,
- ignore: isServer ? serverIgnore : clientIgnore,
- url: process.env.SENTRY_URL,
- org: process.env.SENTRY_ORG,
- project: process.env.SENTRY_PROJECT,
- authToken: process.env.SENTRY_AUTH_TOKEN,
- configFile: hasSentryProperties ? 'sentry.properties' : undefined,
- stripPrefix: ['webpack://_N_E/', 'webpack://'],
- urlPrefix,
- entries: [],
- release: node.getSentryRelease(buildId),
- });
- checkWebpackPluginOverrides(defaultPluginOptions, userPluginOptions);
- return {
- ...defaultPluginOptions,
- ...userPluginOptions,
- errorHandler(err, invokeErr, compilation) {
- if (err) {
- const errorMessagePrefix = `${chalk.red('error')} -`;
- if (err.message.includes('ENOENT')) {
- if (!showedMissingCliBinaryWarningMsg) {
-
- console.error(
- `\n${errorMessagePrefix} ${chalk.bold(
- 'The Sentry binary to upload sourcemaps could not be found.',
- )} Source maps will not be uploaded. Please check that post-install scripts are enabled in your package manager when installing your dependencies and please run your build once without any caching to avoid caching issues of dependencies.\n`,
- );
- showedMissingCliBinaryWarningMsg = true;
- }
- return;
- }
-
- if (err.message.includes('Authentication credentials were not provided.')) {
- let msg;
- if (process.env.VERCEL) {
- msg = `To fix this, use Sentry's Vercel integration to automatically set the ${chalk.bold.cyan(
- 'SENTRY_AUTH_TOKEN',
- )} environment variable: https://vercel.com/integrations/sentry`;
- } else {
- msg =
- 'You can find information on how to generate a Sentry auth token here: https://docs.sentry.io/api/auth/\n' +
- `After generating a Sentry auth token, set it via the ${chalk.bold.cyan(
- 'SENTRY_AUTH_TOKEN',
- )} environment variable during the build.`;
- }
- if (!showedMissingAuthTokenErrorMsg) {
-
- console.error(
- `${errorMessagePrefix} ${chalk.bold(
- 'No Sentry auth token configured.',
- )} Source maps will not be uploaded.\n${msg}\n`,
- );
- showedMissingAuthTokenErrorMsg = true;
- }
- return;
- }
-
- if (err.message.includes('An organization slug is required')) {
- let msg;
- if (process.env.VERCEL) {
- msg = `To fix this, use Sentry's Vercel integration to automatically set the ${chalk.bold.cyan(
- 'SENTRY_ORG',
- )} environment variable: https://vercel.com/integrations/sentry`;
- } else {
- msg = `To fix this, set the ${chalk.bold.cyan(
- 'SENTRY_ORG',
- )} environment variable to the to your organization slug during the build.`;
- }
- if (!showedMissingOrgSlugErrorMsg) {
-
- console.error(
- `${errorMessagePrefix} ${chalk.bold(
- 'No Sentry organization slug configured.',
- )} Source maps will not be uploaded.\n${msg}\n`,
- );
- showedMissingOrgSlugErrorMsg = true;
- }
- return;
- }
-
- if (err.message.includes('A project slug is required')) {
- let msg;
- if (process.env.VERCEL) {
- msg = `To fix this, use Sentry's Vercel integration to automatically set the ${chalk.bold.cyan(
- 'SENTRY_PROJECT',
- )} environment variable: https://vercel.com/integrations/sentry`;
- } else {
- msg = `To fix this, set the ${chalk.bold.cyan(
- 'SENTRY_PROJECT',
- )} environment variable to the name of your Sentry project during the build.`;
- }
- if (!showedMissingProjectSlugErrorMsg) {
-
- console.error(
- `${errorMessagePrefix} ${chalk.bold(
- 'No Sentry project slug configured.',
- )} Source maps will not be uploaded.\n${msg}\n`,
- );
- showedMissingProjectSlugErrorMsg = true;
- }
- return;
- }
- }
- if (userPluginOptions.errorHandler) {
- return userPluginOptions.errorHandler(err, invokeErr, compilation);
- }
- return invokeErr();
- },
- };
- }
- function shouldEnableWebpackPlugin(buildContext, userSentryOptions) {
- const { isServer } = buildContext;
- const { disableServerWebpackPlugin, disableClientWebpackPlugin } = userSentryOptions;
- if (isServer && disableServerWebpackPlugin !== undefined) {
- return !disableServerWebpackPlugin;
- } else if (!isServer && disableClientWebpackPlugin !== undefined) {
- return !disableClientWebpackPlugin;
- }
- return true;
- }
- function handleSourcemapHidingOptionWarning(userSentryOptions, isServer) {
-
-
-
-
- const codeFormat = (str) => chalk.bold.cyan(str);
- const _warningPrefix_ = `${chalk.yellow('warn')} -`;
- const _sentryNextjs_ = codeFormat('@sentry/nextjs');
- const _hideSourceMaps_ = codeFormat('hideSourceMaps');
- const _true_ = codeFormat('true');
- const _false_ = codeFormat('false');
- const _sentry_ = codeFormat('sentry');
- const _nextConfigJS_ = codeFormat('next.config.js');
- if (isServer && userSentryOptions.hideSourceMaps === undefined && !showedHiddenSourceMapsWarningMsg) {
-
- console.warn(
- `\n${_warningPrefix_} In order to be able to deminify errors, ${_sentryNextjs_} creates sourcemaps and uploads ` +
- 'them to the Sentry server. Depending on your deployment setup, this means your original code may be visible ' +
- `in browser devtools in production. To prevent this, set ${_hideSourceMaps_} to ${_true_} in the ${_sentry_} ` +
- `options in your ${_nextConfigJS_}. To disable this warning without changing sourcemap behavior, set ` +
- `${_hideSourceMaps_} to ${_false_}. (In ${_sentryNextjs_} version 8.0.0 and beyond, this option will default ` +
- `to ${_true_}.) See https://webpack.js.org/configuration/devtool/ and ` +
- 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-hidden-source-map for more ' +
- 'information.\n',
- );
- showedHiddenSourceMapsWarningMsg = true;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
- function setUpModuleRules(newConfig) {
- newConfig.module = {
- ...newConfig.module,
- rules: [...(_optionalChain([newConfig, 'access', _7 => _7.module, 'optionalAccess', _8 => _8.rules]) || [])],
- };
-
-
- return newConfig ;
- }
- function addValueInjectionLoader(
- newConfig,
- userNextConfig,
- userSentryOptions,
- buildContext,
- sentryWebpackPluginOptions,
- ) {
- const assetPrefix = userNextConfig.assetPrefix || userNextConfig.basePath || '';
- const isomorphicValues = {
-
- __sentryRewritesTunnelPath__:
- userSentryOptions.tunnelRoute !== undefined && userNextConfig.output !== 'export'
- ? `${_nullishCoalesce(userNextConfig.basePath, () => ( ''))}${userSentryOptions.tunnelRoute}`
- : undefined,
-
-
- SENTRY_RELEASE: buildContext.dev
- ? undefined
- : { id: _nullishCoalesce(sentryWebpackPluginOptions.release, () => ( node.getSentryRelease(buildContext.buildId))) },
- __sentryBasePath: buildContext.dev ? userNextConfig.basePath : undefined,
- };
- const serverValues = {
- ...isomorphicValues,
-
-
- __rewriteFramesDistDir__: _optionalChain([userNextConfig, 'access', _9 => _9.distDir, 'optionalAccess', _10 => _10.replace, 'call', _11 => _11(/\\/g, '\\\\')]) || '.next',
- };
- const clientValues = {
- ...isomorphicValues,
-
-
- __rewriteFramesAssetPrefixPath__: assetPrefix
- ? new URL(assetPrefix, 'http://dogs.are.great').pathname.replace(/\/$/, '')
- : '',
- };
- newConfig.module.rules.push(
- {
- test: /sentry\.(server|edge)\.config\.(jsx?|tsx?)/,
- use: [
- {
- loader: path.resolve(__dirname, 'loaders/valueInjectionLoader.js'),
- options: {
- values: serverValues,
- },
- },
- ],
- },
- {
- test: /sentry\.client\.config\.(jsx?|tsx?)/,
- use: [
- {
- loader: path.resolve(__dirname, 'loaders/valueInjectionLoader.js'),
- options: {
- values: clientValues,
- },
- },
- ],
- },
- );
- }
- function resolveNextPackageDirFromDirectory(basedir) {
- try {
- return path.dirname(resolve.sync('next/package.json', { basedir }));
- } catch (e2) {
-
- return undefined;
- }
- }
- const POTENTIAL_REQUEST_ASNYC_STORAGE_LOCATIONS = [
-
-
- 'next/dist/client/components/request-async-storage.js',
-
-
- 'next/dist/client/components/request-async-storage.external.js',
- ];
- function getRequestAsyncStorageModuleLocation(
- webpackContextDir,
- webpackResolvableModuleLocations,
- ) {
- if (webpackResolvableModuleLocations === undefined) {
- return undefined;
- }
- const absoluteWebpackResolvableModuleLocations = webpackResolvableModuleLocations.map(loc =>
- path.resolve(webpackContextDir, loc),
- );
- for (const webpackResolvableLocation of absoluteWebpackResolvableModuleLocations) {
- const nextPackageDir = resolveNextPackageDirFromDirectory(webpackResolvableLocation);
- if (nextPackageDir) {
- const asyncLocalStorageLocation = POTENTIAL_REQUEST_ASNYC_STORAGE_LOCATIONS.find(loc =>
- fs.existsSync(path.join(nextPackageDir, '..', loc)),
- );
- if (asyncLocalStorageLocation) {
- return asyncLocalStorageLocation;
- }
- }
- }
- return undefined;
- }
- let downloadingCliAttempted = false;
- class SentryCliDownloadPlugin {
- apply(compiler) {
- compiler.hooks.beforeRun.tapAsync('SentryCliDownloadPlugin', (compiler, callback) => {
- const SentryWebpackPlugin = utils.loadModule('@sentry/webpack-plugin');
- if (!SentryWebpackPlugin) {
-
- return callback();
- }
-
- if (SentryWebpackPlugin.cliBinaryExists()) {
- return callback();
- }
- if (!downloadingCliAttempted) {
- downloadingCliAttempted = true;
-
- utils.logger.info(
- `\n${chalk.cyan('info')} - ${chalk.bold(
- 'Sentry binary to upload source maps not found.',
- )} Package manager post-install scripts are likely disabled or there is a caching issue. Manually downloading instead...`,
- );
-
- const cliDownloadPromise = SentryWebpackPlugin.downloadCliBinary({
- log: () => {
-
- },
- });
- cliDownloadPromise.then(
- () => {
-
- utils.logger.info(`${chalk.cyan('info')} - Sentry binary was successfully downloaded.\n`);
- return callback();
- },
- e => {
-
- utils.logger.error(`${chalk.red('error')} - Sentry binary download failed:`, e);
- return callback();
- },
- );
- } else {
- return callback();
- }
- });
- }
- }
- exports.constructWebpackConfigFunction = constructWebpackConfigFunction;
- exports.getUserConfigFile = getUserConfigFile;
- exports.getUserConfigFilePath = getUserConfigFilePath;
- exports.getWebpackPluginOptions = getWebpackPluginOptions;
|