Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 19 additions & 17 deletions packages/bundler-plugin-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,25 +123,27 @@ export function sentryUnpluginFactory({
},
});

if (!options.sourcemaps?.disable) {
if (options.sourcemaps?.disable !== true) {
plugins.push(debugIdInjectionPlugin(logger));

// This option is only strongly typed for the webpack plugin, where it is used. It has no effect on other plugins
const webpack_forceExitOnBuildComplete =
typeof options._experiments["forceExitOnBuildCompletion"] === "boolean"
? options._experiments["forceExitOnBuildCompletion"]
: undefined;

plugins.push(
debugIdUploadPlugin(
createDebugIdUploadFunction({
sentryBuildPluginManager,
}),
logger,
sentryBuildPluginManager.createDependencyOnBuildArtifacts,
webpack_forceExitOnBuildComplete
)
);
if (options.sourcemaps?.disable !== "disable-upload") {
// This option is only strongly typed for the webpack plugin, where it is used. It has no effect on other plugins
const webpack_forceExitOnBuildComplete =
typeof options._experiments["forceExitOnBuildCompletion"] === "boolean"
? options._experiments["forceExitOnBuildCompletion"]
: undefined;

plugins.push(
debugIdUploadPlugin(
createDebugIdUploadFunction({
sentryBuildPluginManager,
}),
logger,
sentryBuildPluginManager.createDependencyOnBuildArtifacts,
webpack_forceExitOnBuildComplete
)
);
}
}

if (options.reactComponentAnnotation) {
Expand Down
2 changes: 1 addition & 1 deletion packages/bundler-plugin-core/src/options-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type NormalizedOptions = {
disable: boolean;
sourcemaps:
| {
disable?: boolean;
disable?: boolean | "disable-upload";
assets?: string | string[];
ignore?: string | string[];
rewriteSources?: RewriteSourcesHook;
Expand Down
7 changes: 5 additions & 2 deletions packages/bundler-plugin-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,14 @@ export interface Options {
*/
sourcemaps?: {
/**
* Disables all functionality related to sourcemaps.
* Disables all functionality related to sourcemaps if set to `true`.
*
* If set to `"disable-upload"`, the plugin will not upload sourcemaps to Sentry, but will inject debug IDs into the build artifacts.
* This is useful if you want to manually upload sourcemaps to Sentry at a later point in time.
*
* Defaults to `false`.
*/
disable?: boolean;
disable?: boolean | "disable-upload";

/**
* A glob or an array of globs that specifies the build artifacts that should be uploaded to Sentry.
Expand Down
185 changes: 184 additions & 1 deletion packages/bundler-plugin-core/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getDebugIdSnippet } from "../src";
import { Compiler } from "webpack";
import { getDebugIdSnippet, sentryUnpluginFactory } from "../src";

describe("getDebugIdSnippet", () => {
it("returns the debugId injection snippet for a passed debugId", () => {
Expand All @@ -8,3 +9,185 @@ describe("getDebugIdSnippet", () => {
);
});
});

describe("sentryUnpluginFactory sourcemaps.disable behavior", () => {
const mockReleaseInjectionPlugin = jest.fn((_injectionCode: string) => ({
name: "mock-release-injection-plugin",
}));

const mockComponentNameAnnotatePlugin = jest.fn(() => ({
name: "mock-component-name-annotate-plugin",
}));

const mockModuleMetadataInjectionPlugin = jest.fn((_injectionCode: string) => ({
name: "mock-module-metadata-injection-plugin",
}));

const mockDebugIdInjectionPlugin = jest.fn(() => ({
name: "mock-debug-id-injection-plugin",
}));

const mockDebugIdUploadPlugin = jest.fn(() => ({
name: "mock-debug-id-upload-plugin",
}));

const mockBundleSizeOptimizationsPlugin = jest.fn(() => ({
name: "mock-bundle-size-optimizations-plugin",
}));

const createUnpluginInstance = (): ReturnType<typeof sentryUnpluginFactory> => {
return sentryUnpluginFactory({
releaseInjectionPlugin: mockReleaseInjectionPlugin,
componentNameAnnotatePlugin: mockComponentNameAnnotatePlugin,
moduleMetadataInjectionPlugin: mockModuleMetadataInjectionPlugin,
debugIdInjectionPlugin: mockDebugIdInjectionPlugin,
debugIdUploadPlugin: mockDebugIdUploadPlugin,
bundleSizeOptimizationsPlugin: mockBundleSizeOptimizationsPlugin,
});
};

beforeEach(() => {
jest.clearAllMocks();
});

describe("when sourcemaps.disable is true", () => {
it("should not include debug ID injection or upload plugins", () => {
const unpluginInstance = createUnpluginInstance();

const plugins = unpluginInstance.raw(
{
authToken: "test-token",
org: "test-org",
project: "test-project",
sourcemaps: {
disable: true,
},
},
{ framework: "webpack", webpack: { compiler: {} as Compiler } }
);

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

// Should not include debug ID related plugins
expect(pluginNames).not.toContain("mock-debug-id-injection-plugin");
expect(pluginNames).not.toContain("mock-debug-id-upload-plugin");

// Should still include other core plugins
expect(pluginNames).toContain("sentry-telemetry-plugin");
expect(pluginNames).toContain("sentry-release-management-plugin");
expect(pluginNames).toContain("sentry-file-deletion-plugin");
});
});

describe('when sourcemaps.disable is "disable-upload"', () => {
it("should include debug ID injection plugin but not upload plugin", () => {
const unpluginInstance = createUnpluginInstance();

const plugins = unpluginInstance.raw(
{
authToken: "test-token",
org: "test-org",
project: "test-project",
sourcemaps: {
disable: "disable-upload",
},
},
{ framework: "webpack", webpack: { compiler: {} as Compiler } }
);

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

// Should include debug ID injection but not upload
expect(pluginNames).toContain("mock-debug-id-injection-plugin");
expect(pluginNames).not.toContain("mock-debug-id-upload-plugin");

// Should still include other core plugins
expect(pluginNames).toContain("sentry-telemetry-plugin");
expect(pluginNames).toContain("sentry-release-management-plugin");
expect(pluginNames).toContain("sentry-file-deletion-plugin");
});
});

describe("when sourcemaps.disable is false", () => {
it("should include both debug ID injection and upload plugins", () => {
const unpluginInstance = createUnpluginInstance();

const plugins = unpluginInstance.raw(
{
authToken: "test-token",
org: "test-org",
project: "test-project",
sourcemaps: {
disable: false,
},
},
{ framework: "webpack", webpack: { compiler: {} as Compiler } }
);

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

// Should include both debug ID related plugins
expect(pluginNames).toContain("mock-debug-id-injection-plugin");
expect(pluginNames).toContain("mock-debug-id-upload-plugin");

// Should include other core plugins
expect(pluginNames).toContain("sentry-telemetry-plugin");
expect(pluginNames).toContain("sentry-release-management-plugin");
expect(pluginNames).toContain("sentry-file-deletion-plugin");
});
});

describe("when sourcemaps.disable is undefined (default)", () => {
it("should include both debug ID injection and upload plugins", () => {
const unpluginInstance = createUnpluginInstance();

const plugins = unpluginInstance.raw(
{
authToken: "test-token",
org: "test-org",
project: "test-project",
// sourcemaps.disable not specified (undefined)
},
{ framework: "webpack", webpack: { compiler: {} as Compiler } }
);

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

// Should include both debug ID related plugins by default
expect(pluginNames).toContain("mock-debug-id-injection-plugin");
expect(pluginNames).toContain("mock-debug-id-upload-plugin");

// Should include other core plugins
expect(pluginNames).toContain("sentry-telemetry-plugin");
expect(pluginNames).toContain("sentry-release-management-plugin");
expect(pluginNames).toContain("sentry-file-deletion-plugin");
});
});

describe("when entire sourcemaps option is undefined", () => {
it("should include both debug ID injection and upload plugins", () => {
const unpluginInstance = createUnpluginInstance();

const plugins = unpluginInstance.raw(
{
authToken: "test-token",
org: "test-org",
project: "test-project",
// sourcemaps option not specified at all
},
{ framework: "webpack", webpack: { compiler: {} as Compiler } }
);

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

// Should include both debug ID related plugins by default
expect(pluginNames).toContain("mock-debug-id-injection-plugin");
expect(pluginNames).toContain("mock-debug-id-upload-plugin");

// Should include other core plugins
expect(pluginNames).toContain("sentry-telemetry-plugin");
expect(pluginNames).toContain("sentry-release-management-plugin");
expect(pluginNames).toContain("sentry-file-deletion-plugin");
});
});
});
Loading