@sentry/nextjs
Version:
Official Sentry SDK for Next.js
119 lines (115 loc) • 5.26 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const core = require('@sentry/core');
const fs = require('fs');
const path = require('path');
const getBuildPluginOptions = require('./getBuildPluginOptions.js');
async function handleRunAfterProductionCompile({
releaseName,
distDir,
buildTool,
usesNativeDebugIds,
sriEnabled
}, sentryBuildOptions) {
if (sentryBuildOptions.debug) {
console.debug("[@sentry/nextjs] Running runAfterProductionCompile logic.");
}
const { createSentryBuildPluginManager } = core.loadModule(
"@sentry/bundler-plugin-core",
module
) ?? {};
if (!createSentryBuildPluginManager) {
console.warn(
"[@sentry/nextjs] Could not load build manager package. Will not run runAfterProductionCompile logic."
);
return;
}
const options = getBuildPluginOptions.getBuildPluginOptions({
sentryBuildOptions,
releaseName,
distDirAbsPath: distDir,
buildTool: `after-production-compile-${buildTool}`
});
const sentryBuildPluginManager = createSentryBuildPluginManager(options, {
buildTool,
loggerPrefix: "[@sentry/nextjs - After Production Compile]"
});
await sentryBuildPluginManager.telemetry.emitBundlerPluginExecutionSignal();
await sentryBuildPluginManager.createRelease();
if (!usesNativeDebugIds && sentryBuildOptions.sourcemaps?.disable !== true) {
await sentryBuildPluginManager.injectDebugIds([distDir]);
}
await sentryBuildPluginManager.uploadSourcemaps([distDir], {
// We don't want to prepare the artifacts because we injected debug ids manually before
prepareArtifacts: false
});
const deleteSourcemapsAfterUpload = sentryBuildOptions.sourcemaps?.deleteSourcemapsAfterUpload ?? false;
if (deleteSourcemapsAfterUpload && buildTool === "turbopack" && !sentryBuildOptions.sourcemaps?.assets && options.sourcemaps?.disable !== true) {
await warnAboutUncoveredSourcemaps(path.join(distDir, "static"), options.sourcemaps?.assets);
}
await sentryBuildPluginManager.deleteArtifacts();
if (deleteSourcemapsAfterUpload && buildTool === "turbopack" && !sriEnabled) {
await stripSourceMappingURLComments(path.join(distDir, "static"), sentryBuildOptions.debug);
}
if (deleteSourcemapsAfterUpload && buildTool === "turbopack" && sriEnabled && sentryBuildOptions.debug) {
console.debug(
"[@sentry/nextjs] Skipping sourceMappingURL comment stripping because Subresource Integrity (SRI) is enabled."
);
}
}
async function warnAboutUncoveredSourcemaps(staticDir, uploadAssets) {
let entries;
try {
entries = await fs.promises.readdir(staticDir, { recursive: true }).then((e) => e.map((f) => String(f)));
} catch {
return;
}
const assetPaths = (Array.isArray(uploadAssets) ? uploadAssets : uploadAssets ? [uploadAssets] : []).map(
(p) => p.replace(/\\/g, "/")
);
const staticDirPosix = staticDir.replace(/\\/g, "/");
const uncovered = entries.filter((entry) => /\.(js|mjs|cjs)\.map$/.test(entry)).map((entry) => path.posix.join(staticDirPosix, entry.replace(/\\/g, "/"))).filter((mapPath) => !assetPaths.some((assetPath) => mapPath === assetPath || mapPath.startsWith(`${assetPath}/`)));
if (uncovered.length > 0) {
console.warn(
`[@sentry/nextjs] Found ${uncovered.length} source map file(s) under "${staticDir}" (e.g. "${uncovered[0]}") that are not covered by the source map upload patterns and will be deleted without having been uploaded to Sentry. Stack traces for the affected files will not be symbolicated. Set the \`sourcemaps.assets\` option in \`withSentryConfig\` to cover these files.`
);
}
}
const SOURCEMAPPING_URL_COMMENT_REGEX = /\n?\/\/[#@] sourceMappingURL=[^\n]+$/;
const CSS_SOURCEMAPPING_URL_COMMENT_REGEX = /\n?\/\*[#@] sourceMappingURL=[^\n]+\*\/$/;
async function stripSourceMappingURLComments(staticDir, debug) {
let entries;
try {
entries = await fs.promises.readdir(staticDir, { recursive: true }).then((e) => e.map((f) => String(f)));
} catch {
return;
}
const filesToProcess = entries.filter(
(f) => f.endsWith(".js") || f.endsWith(".mjs") || f.endsWith(".cjs") || f.endsWith(".css")
);
const results = await Promise.all(
filesToProcess.map(async (file) => {
const filePath = path.join(staticDir, file);
try {
const content = await fs.promises.readFile(filePath, "utf-8");
const isCSS = file.endsWith(".css");
const regex = isCSS ? CSS_SOURCEMAPPING_URL_COMMENT_REGEX : SOURCEMAPPING_URL_COMMENT_REGEX;
const strippedContent = content.replace(regex, "");
if (strippedContent !== content) {
await fs.promises.writeFile(filePath, strippedContent, "utf-8");
return file;
}
} catch {
}
return void 0;
})
);
const strippedCount = results.filter(Boolean).length;
if (debug && strippedCount > 0) {
console.debug(
`[@sentry/nextjs] Stripped sourceMappingURL comments from ${String(strippedCount)} file(s) to prevent requests for deleted source maps.`
);
}
}
exports.handleRunAfterProductionCompile = handleRunAfterProductionCompile;
exports.stripSourceMappingURLComments = stripSourceMappingURLComments;
//# sourceMappingURL=handleRunAfterProductionCompile.js.map