Skip to content

Commit b6b7b80

Browse files
author
Luca Forstner
committed
ref: Clean up core package
1 parent d5ada3c commit b6b7b80

File tree

9 files changed

+114
-122
lines changed

9 files changed

+114
-122
lines changed

packages/bundler-plugin-core/src/api-primitives.ts renamed to packages/bundler-plugin-core/src/build-plugin-manager.ts

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import {
66
makeSession,
77
setMeasurement,
88
spanToTraceHeader,
9+
startInactiveSpan,
910
startSpan,
1011
} from "@sentry/core";
1112
import * as dotenv from "dotenv";
1213
import * as fs from "fs";
1314
import * as os from "os";
1415
import * as path from "path";
1516
import { normalizeUserOptions, validateOptions } from "./options-mapping";
16-
import { createLogger } from "./sentry/logger";
17+
import { createLogger } from "./logger";
1718
import {
1819
allowedToSendTelemetry,
1920
createSentryInstance,
@@ -27,9 +28,24 @@ import { dynamicSamplingContextToSentryBaggageHeader } from "@sentry/utils";
2728

2829
export type SentryBuildPluginManager = ReturnType<typeof createSentryBuildPluginManager>;
2930

31+
/**
32+
* Creates a build plugin manager that exposes primitives for everything that a Sentry JavaScript SDK or build tooling may do during a build.
33+
*
34+
* The build plugin manager's behavior strongly depends on the options that are passed in.
35+
*/
3036
export function createSentryBuildPluginManager(
3137
userOptions: Options,
32-
bundlerPluginMetaContext: { buildTool: string; loggerPrefix: string }
38+
bundlerPluginMetaContext: {
39+
/**
40+
* E.g. `webpack` or `nextjs` or `turbopack`
41+
*/
42+
43+
buildTool: string;
44+
/**
45+
* E.g. `[sentry-webpack-plugin]` or `[@sentry/nextjs]`
46+
*/
47+
loggerPrefix: string;
48+
}
3349
) {
3450
const logger = createLogger({
3551
prefix: bundlerPluginMetaContext.loggerPrefix,
@@ -241,23 +257,59 @@ export function createSentryBuildPluginManager(
241257
}
242258

243259
return {
260+
/**
261+
* A logger instance that takes the options passed to the build plugin manager into account. (for silencing and log level etc.)
262+
*/
244263
logger,
264+
265+
/**
266+
* Options after normalization. Includes things like the inferred release name.
267+
*/
245268
normalizedOptions: options,
269+
270+
/**
271+
* Magic strings and their replacement values that can be used for bundle size optimizations. This already takes
272+
* into account the options passed to the build plugin manager.
273+
*/
246274
bundleSizeOptimizationReplacementValues,
275+
276+
/**
277+
* Metadata that should be injected into bundles if possible. Takes into account options passed to the build plugin manager.
278+
*/
279+
// See `generateModuleMetadataInjectorCode` for how this should be used exactly
247280
bundleMetadata,
281+
282+
/**
283+
* Contains utility functions for emitting telemetry via the build plugin manager.
284+
*/
248285
telemetry: {
286+
/**
287+
* Emits a `Sentry Bundler Plugin execution` signal.
288+
*/
249289
async emitBundlerPluginExecutionSignal() {
250290
if (await shouldSendTelemetry) {
251291
logger.info(
252292
"Sending telemetry data on issues and performance to Sentry. To disable telemetry, set `options.telemetry` to `false`."
253293
);
254-
startSpan({ name: "Sentry Bundler Plugin execution", scope: sentryScope }, () => {
255-
//
256-
});
294+
startInactiveSpan({
295+
name: "Sentry Bundler Plugin execution",
296+
forceTransaction: true,
297+
scope: sentryScope,
298+
}).end();
257299
await safeFlushTelemetry(sentryClient);
258300
}
259301
},
260302
},
303+
304+
/**
305+
* Will potentially create a release based on the build plugin manager options.
306+
*
307+
* Also
308+
* - finalizes the release
309+
* - sets commits
310+
* - uploads legacy sourcemaps
311+
* - adds deploy information
312+
*/
261313
async createRelease() {
262314
if (!options.release.name) {
263315
logger.debug(
@@ -367,6 +419,10 @@ export function createSentryBuildPluginManager(
367419
freeWriteBundleInvocationDependencyOnSourcemapFiles();
368420
}
369421
},
422+
423+
/**
424+
* Uploads sourcemaps using the "Debug ID" method. This function takes a list of build artifact paths that will be uploaded
425+
*/
370426
async uploadSourcemaps(buildArtifactPaths: string[]) {
371427
if (options.sourcemaps?.disable) {
372428
logger.debug(
@@ -547,6 +603,10 @@ export function createSentryBuildPluginManager(
547603
}
548604
);
549605
},
606+
607+
/**
608+
* Will delete artifacts based on the passed `sourcemaps.filesToDeleteAfterUpload` option.
609+
*/
550610
async deleteArtifacts() {
551611
try {
552612
const filesToDelete = await options.sourcemaps?.filesToDeleteAfterUpload;

packages/bundler-plugin-core/src/debug-id-upload.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import fs from "fs";
22
import path from "path";
33
import * as util from "util";
44
import { promisify } from "util";
5-
import { SentryBuildPluginManager } from "./api-primitives";
6-
import { Logger } from "./sentry/logger";
5+
import { SentryBuildPluginManager } from "./build-plugin-manager";
6+
import { Logger } from "./logger";
77

88
interface RewriteSourcesHook {
99
// eslint-disable-next-line @typescript-eslint/no-explicit-any

packages/bundler-plugin-core/src/index.ts

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@ import { glob } from "glob";
77
import MagicString from "magic-string";
88
import * as path from "path";
99
import { createUnplugin, TransformResult, UnpluginOptions } from "unplugin";
10-
import { createSentryBuildPluginManager } from "./api-primitives";
10+
import { createSentryBuildPluginManager } from "./build-plugin-manager";
1111
import { createDebugIdUploadFunction } from "./debug-id-upload";
12-
import { releaseManagementPlugin } from "./plugins/release-management";
13-
import { fileDeletionPlugin } from "./plugins/sourcemap-deletion";
14-
import { telemetryPlugin } from "./plugins/telemetry";
15-
import { Logger } from "./sentry/logger";
12+
import { Logger } from "./logger";
1613
import { Options, SentrySDKBuildFlags } from "./types";
1714
import {
1815
generateGlobalInjectorCode,
@@ -40,30 +37,7 @@ interface SentryUnpluginFactoryOptions {
4037
}
4138

4239
/**
43-
* The sentry bundler plugin concerns itself with two things:
44-
* - Release injection
45-
* - Sourcemaps upload
46-
*
47-
* Release injection:
48-
* Per default the sentry bundler plugin will inject a global `SENTRY_RELEASE` into each JavaScript/TypeScript module
49-
* that is part of the bundle. On a technical level this is done by appending an import (`import "sentry-release-injector";`)
50-
* to all entrypoint files of the user code (see `transformInclude` and `transform` hooks). This import is then resolved
51-
* by the sentry plugin to a virtual module that sets the global variable (see `resolveId` and `load` hooks).
52-
* If a user wants to inject the release into a particular set of modules they can use the `releaseInjectionTargets` option.
53-
*
54-
* Source maps upload:
55-
*
56-
* The sentry bundler plugin will also take care of uploading source maps to Sentry. This
57-
* is all done in the `writeBundle` hook. In this hook the sentry plugin will execute the
58-
* release creation pipeline:
59-
*
60-
* 1. Create a new release
61-
* 2. Upload sourcemaps based on `include` and source-map-specific options
62-
* 3. Associate a range of commits with the release (if `setCommits` is specified)
63-
* 4. Finalize the release (unless `finalize` is disabled)
64-
* 5. Add deploy information to the release (if `deploy` is specified)
65-
*
66-
* This release creation pipeline relies on Sentry CLI to execute the different steps.
40+
* Creates an unplugin instance used to create Sentry plugins for Vite, Rollup, esbuild, and Webpack.
6741
*/
6842
export function sentryUnpluginFactory({
6943
releaseInjectionPlugin,
@@ -103,11 +77,35 @@ export function sentryUnpluginFactory({
10377

10478
const plugins: UnpluginOptions[] = [];
10579

106-
plugins.push(
107-
telemetryPlugin({
108-
sentryBuildPluginManager,
109-
})
110-
);
80+
// Add plugin to emit a telemetry signal when the build starts
81+
plugins.push({
82+
name: "sentry-telemetry-plugin",
83+
async buildStart() {
84+
await sentryBuildPluginManager.telemetry.emitBundlerPluginExecutionSignal();
85+
},
86+
});
87+
88+
// Add plugin to create and finalize releases, and also take care of adding commits and legacy sourcemaps
89+
const freeGlobalDependencyOnBuildArtifacts =
90+
sentryBuildPluginManager.createDependencyOnBuildArtifacts();
91+
plugins.push({
92+
name: "sentry-release-management-plugin",
93+
async writeBundle() {
94+
try {
95+
await sentryBuildPluginManager.createRelease();
96+
} finally {
97+
freeGlobalDependencyOnBuildArtifacts();
98+
}
99+
},
100+
});
101+
102+
// Add plugin to delete unwanted artifacts like source maps after the uploads have completed
103+
plugins.push({
104+
name: "sentry-file-deletion-plugin",
105+
async writeBundle() {
106+
await sentryBuildPluginManager.deleteArtifacts();
107+
},
108+
});
111109

112110
if (Object.keys(bundleSizeOptimizationReplacementValues).length > 0) {
113111
plugins.push(bundleSizeOptimizationsPlugin(bundleSizeOptimizationReplacementValues));
@@ -136,12 +134,6 @@ export function sentryUnpluginFactory({
136134
plugins.push(moduleMetadataInjectionPlugin(injectionCode));
137135
}
138136

139-
plugins.push(
140-
releaseManagementPlugin({
141-
sentryBuildPluginManager,
142-
})
143-
);
144-
145137
if (!options.sourcemaps?.disable) {
146138
plugins.push(debugIdInjectionPlugin(logger));
147139
}
@@ -180,16 +172,14 @@ export function sentryUnpluginFactory({
180172
}
181173
}
182174

183-
plugins.push(
184-
fileDeletionPlugin({
185-
sentryBuildPluginManager,
186-
})
187-
);
188-
189175
return plugins;
190176
});
191177
}
192178

179+
/**
180+
* @deprecated
181+
*/
182+
// TODO(v4): Don't export this from the package
193183
export function getBuildInformation() {
194184
const packageJson = getPackageJson();
195185

@@ -458,6 +448,6 @@ export function getDebugIdSnippet(debugId: string): string {
458448
return `;{try{let e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="${debugId}",e._sentryDebugIdIdentifier="sentry-dbid-${debugId}")}catch(e){}};`;
459449
}
460450

461-
export type { Logger } from "./sentry/logger";
451+
export type { Logger } from "./logger";
462452
export type { Options, SentrySDKBuildFlags } from "./types";
463453
export { replaceBooleanFlagsInCode, stringToUUID } from "./utils";

packages/bundler-plugin-core/src/options-mapping.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Logger } from "./sentry/logger";
1+
import { Logger } from "./logger";
22
import { Options as UserOptions, SetCommitsOptions } from "./types";
33
import { determineReleaseName } from "./utils";
44

packages/bundler-plugin-core/src/plugins/release-management.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

packages/bundler-plugin-core/src/plugins/sourcemap-deletion.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

packages/bundler-plugin-core/src/plugins/telemetry.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

packages/bundler-plugin-core/src/sentry/telemetry.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const stackParser = createStackParser(nodeStackLineParser());
1313
export function createSentryInstance(
1414
options: NormalizedOptions,
1515
shouldSendTelemetry: Promise<boolean>,
16-
bundler: string
16+
buildTool: string
1717
): { sentryScope: Scope; sentryClient: Client } {
1818
const clientOptions: ServerRuntimeClientOptions = {
1919
platform: "node",
@@ -55,12 +55,16 @@ export function createSentryInstance(
5555
const scope = new Scope();
5656
scope.setClient(client);
5757

58-
setTelemetryDataOnScope(options, scope, bundler);
58+
setTelemetryDataOnScope(options, scope, buildTool);
5959

6060
return { sentryScope: scope, sentryClient: client };
6161
}
6262

63-
export function setTelemetryDataOnScope(options: NormalizedOptions, scope: Scope, bundler: string) {
63+
export function setTelemetryDataOnScope(
64+
options: NormalizedOptions,
65+
scope: Scope,
66+
buildTool: string
67+
) {
6468
const { org, project, release, errorHandler, sourcemaps, reactComponentAnnotation } = options;
6569

6670
scope.setTag("upload-legacy-sourcemaps", !!release.uploadLegacySourcemaps);
@@ -103,7 +107,7 @@ export function setTelemetryDataOnScope(options: NormalizedOptions, scope: Scope
103107
scope.setTags({
104108
organization: org,
105109
project,
106-
bundler,
110+
bundler: buildTool,
107111
});
108112

109113
scope.setUser({ id: org });
@@ -134,7 +138,7 @@ export async function allowedToSendTelemetry(options: NormalizedOptions): Promis
134138
let cliInfo;
135139
try {
136140
// Makes a call to SentryCLI to get the Sentry server URL the CLI uses.
137-
// We need to check and decide to use telemetry based on the CLI's respone to this call
141+
// We need to check and decide to use telemetry based on the CLI's response to this call
138142
// because only at this time we checked a possibly existing .sentryclirc file. This file
139143
// could point to another URL than the default URL.
140144
cliInfo = await cli.execute(["info"], false);

0 commit comments

Comments
 (0)