Skip to content

Commit 4a9d5a0

Browse files
author
Luca Forstner
authored
ref(core): Clean up @sentry/bundler-plugin-core package (#716)
1 parent d5ada3c commit 4a9d5a0

File tree

12 files changed

+126
-134
lines changed

12 files changed

+126
-134
lines changed

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

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import * as fs from "fs";
1313
import * as os from "os";
1414
import * as path from "path";
1515
import { normalizeUserOptions, validateOptions } from "./options-mapping";
16-
import { createLogger } from "./sentry/logger";
16+
import { createLogger } from "./logger";
1717
import {
1818
allowedToSendTelemetry,
1919
createSentryInstance,
@@ -27,9 +27,23 @@ import { dynamicSamplingContextToSentryBaggageHeader } from "@sentry/utils";
2727

2828
export type SentryBuildPluginManager = ReturnType<typeof createSentryBuildPluginManager>;
2929

30+
/**
31+
* Creates a build plugin manager that exposes primitives for everything that a Sentry JavaScript SDK or build tooling may do during a build.
32+
*
33+
* The build plugin manager's behavior strongly depends on the options that are passed in.
34+
*/
3035
export function createSentryBuildPluginManager(
3136
userOptions: Options,
32-
bundlerPluginMetaContext: { buildTool: string; loggerPrefix: string }
37+
bundlerPluginMetaContext: {
38+
/**
39+
* E.g. `webpack` or `nextjs` or `turbopack`
40+
*/
41+
buildTool: string;
42+
/**
43+
* E.g. `[sentry-webpack-plugin]` or `[@sentry/nextjs]`
44+
*/
45+
loggerPrefix: string;
46+
}
3347
) {
3448
const logger = createLogger({
3549
prefix: bundlerPluginMetaContext.loggerPrefix,
@@ -241,11 +255,35 @@ export function createSentryBuildPluginManager(
241255
}
242256

243257
return {
258+
/**
259+
* A logger instance that takes the options passed to the build plugin manager into account. (for silencing and log level etc.)
260+
*/
244261
logger,
262+
263+
/**
264+
* Options after normalization. Includes things like the inferred release name.
265+
*/
245266
normalizedOptions: options,
267+
268+
/**
269+
* Magic strings and their replacement values that can be used for bundle size optimizations. This already takes
270+
* into account the options passed to the build plugin manager.
271+
*/
246272
bundleSizeOptimizationReplacementValues,
273+
274+
/**
275+
* Metadata that should be injected into bundles if possible. Takes into account options passed to the build plugin manager.
276+
*/
277+
// See `generateModuleMetadataInjectorCode` for how this should be used exactly
247278
bundleMetadata,
279+
280+
/**
281+
* Contains utility functions for emitting telemetry via the build plugin manager.
282+
*/
248283
telemetry: {
284+
/**
285+
* Emits a `Sentry Bundler Plugin execution` signal.
286+
*/
249287
async emitBundlerPluginExecutionSignal() {
250288
if (await shouldSendTelemetry) {
251289
logger.info(
@@ -258,6 +296,16 @@ export function createSentryBuildPluginManager(
258296
}
259297
},
260298
},
299+
300+
/**
301+
* Will potentially create a release based on the build plugin manager options.
302+
*
303+
* Also
304+
* - finalizes the release
305+
* - sets commits
306+
* - uploads legacy sourcemaps
307+
* - adds deploy information
308+
*/
261309
async createRelease() {
262310
if (!options.release.name) {
263311
logger.debug(
@@ -367,6 +415,10 @@ export function createSentryBuildPluginManager(
367415
freeWriteBundleInvocationDependencyOnSourcemapFiles();
368416
}
369417
},
418+
419+
/**
420+
* Uploads sourcemaps using the "Debug ID" method. This function takes a list of build artifact paths that will be uploaded
421+
*/
370422
async uploadSourcemaps(buildArtifactPaths: string[]) {
371423
if (options.sourcemaps?.disable) {
372424
logger.debug(
@@ -547,6 +599,10 @@ export function createSentryBuildPluginManager(
547599
}
548600
);
549601
},
602+
603+
/**
604+
* Will delete artifacts based on the passed `sourcemaps.filesToDeleteAfterUpload` option.
605+
*/
550606
async deleteArtifacts() {
551607
try {
552608
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: 35 additions & 45 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,13 @@ 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+
});
11187

11288
if (Object.keys(bundleSizeOptimizationReplacementValues).length > 0) {
11389
plugins.push(bundleSizeOptimizationsPlugin(bundleSizeOptimizationReplacementValues));
@@ -136,11 +112,19 @@ export function sentryUnpluginFactory({
136112
plugins.push(moduleMetadataInjectionPlugin(injectionCode));
137113
}
138114

139-
plugins.push(
140-
releaseManagementPlugin({
141-
sentryBuildPluginManager,
142-
})
143-
);
115+
// Add plugin to create and finalize releases, and also take care of adding commits and legacy sourcemaps
116+
const freeGlobalDependencyOnBuildArtifacts =
117+
sentryBuildPluginManager.createDependencyOnBuildArtifacts();
118+
plugins.push({
119+
name: "sentry-release-management-plugin",
120+
async writeBundle() {
121+
try {
122+
await sentryBuildPluginManager.createRelease();
123+
} finally {
124+
freeGlobalDependencyOnBuildArtifacts();
125+
}
126+
},
127+
});
144128

145129
if (!options.sourcemaps?.disable) {
146130
plugins.push(debugIdInjectionPlugin(logger));
@@ -180,16 +164,22 @@ export function sentryUnpluginFactory({
180164
}
181165
}
182166

183-
plugins.push(
184-
fileDeletionPlugin({
185-
sentryBuildPluginManager,
186-
})
187-
);
167+
// Add plugin to delete unwanted artifacts like source maps after the uploads have completed
168+
plugins.push({
169+
name: "sentry-file-deletion-plugin",
170+
async writeBundle() {
171+
await sentryBuildPluginManager.deleteArtifacts();
172+
},
173+
});
188174

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);

packages/bundler-plugin-core/test/sentry/logger.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createLogger } from "../../src/sentry/logger";
1+
import { createLogger } from "../../src/logger";
22

33
describe("Logger", () => {
44
const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => undefined);

packages/rollup-plugin/test/public-api.test.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ describe("sentryRollupPlugin", () => {
2222

2323
const pluginNames = plugins.map((plugin) => plugin.name);
2424

25-
expect(pluginNames).toEqual([
26-
"sentry-telemetry-plugin",
27-
"sentry-rollup-release-injection-plugin",
28-
"sentry-release-management-plugin",
29-
"sentry-rollup-debug-id-injection-plugin",
30-
"sentry-rollup-debug-id-upload-plugin",
31-
"sentry-file-deletion-plugin",
32-
]);
25+
expect(pluginNames).toEqual(
26+
expect.arrayContaining([
27+
"sentry-telemetry-plugin",
28+
"sentry-rollup-release-injection-plugin",
29+
"sentry-release-management-plugin",
30+
"sentry-rollup-debug-id-injection-plugin",
31+
"sentry-rollup-debug-id-upload-plugin",
32+
"sentry-file-deletion-plugin",
33+
])
34+
);
3335
});
3436
});

0 commit comments

Comments
 (0)