Skip to content

Commit 1ee4667

Browse files
committed
Merge branch 'main' into antonis/enhanced-fragment-detection
2 parents 034a818 + c15f9df commit 1ee4667

File tree

19 files changed

+160
-201
lines changed

19 files changed

+160
-201
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44

55
- "You know what they say ‘Fool me once, strike one, but fool me twice… strike three.’" — Michael Scott
66

7+
## 4.0.2
8+
9+
- fix(core): Make `moduleMetadata` injection snippet ES5-compliant ([#774](https://github.com/getsentry/sentry-javascript-bundler-plugins/pull/774))
10+
11+
## 4.0.1
12+
13+
- fix(core): Make plugin inject ES5-friendly code ([#770](https://github.com/getsentry/sentry-javascript-bundler-plugins/pull/770))
14+
- fix(core): Use `renderChunk` for release injection for Rollup/Rolldown/Vite ([#761](https://github.com/getsentry/sentry-javascript-bundler-plugins/pull/761))
15+
16+
Work in this release was contributed by @grushetsky. Thank you for your contribution!
17+
718
## 4.0.0
819

920
### Breaking Changes
@@ -111,6 +122,10 @@ Work in this release was contributed by @thecodewarrior. Thank you for your cont
111122

112123
Work in this release contributed by @jdelStrother. Thank you for your contribution!
113124

125+
## 2.23.1
126+
127+
- fix(v2/core): Make `moduleMetadata` injection code ES5-compliant (#773)
128+
114129
## 2.23.0
115130

116131
- chore(deps): bump nanoid from 3.3.6 to 3.3.8 (#641)

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
3-
"version": "3.6.1",
3+
"version": "4.0.2",
44
"npmClient": "yarn",
55
"useWorkspaces": true
66
}

packages/babel-plugin-component-annotate/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry/babel-plugin-component-annotate",
3-
"version": "3.6.1",
3+
"version": "4.0.2",
44
"description": "A Babel plugin that annotates frontend components with additional data to enrich the experience in Sentry",
55
"repository": "git://github.com/getsentry/sentry-javascript-bundler-plugins.git",
66
"homepage": "https://github.com/getsentry/sentry-javascript-bundler-plugins/tree/main/packages/babel-plugin-component-annotate",
@@ -56,8 +56,8 @@
5656
"@babel/preset-typescript": "7.17.12",
5757
"@rollup/plugin-babel": "5.3.1",
5858
"@rollup/plugin-node-resolve": "13.3.0",
59-
"@sentry-internal/eslint-config": "3.6.1",
60-
"@sentry-internal/sentry-bundler-plugin-tsconfig": "3.6.1",
59+
"@sentry-internal/eslint-config": "4.0.2",
60+
"@sentry-internal/sentry-bundler-plugin-tsconfig": "4.0.2",
6161
"@swc/core": "^1.2.205",
6262
"@swc/jest": "^0.2.21",
6363
"@types/jest": "^28.1.3",

packages/bundler-plugin-core/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry/bundler-plugin-core",
3-
"version": "3.6.1",
3+
"version": "4.0.2",
44
"description": "Sentry Bundler Plugin Core",
55
"repository": "git://github.com/getsentry/sentry-javascript-bundler-plugins.git",
66
"homepage": "https://github.com/getsentry/sentry-javascript-bundler-plugins/tree/main/packages/bundler-plugin-core",
@@ -53,7 +53,7 @@
5353
},
5454
"dependencies": {
5555
"@babel/core": "^7.18.5",
56-
"@sentry/babel-plugin-component-annotate": "3.6.1",
56+
"@sentry/babel-plugin-component-annotate": "4.0.2",
5757
"@sentry/cli": "^2.49.0",
5858
"dotenv": "^16.3.1",
5959
"find-up": "^5.0.0",
@@ -68,8 +68,8 @@
6868
"@rollup/plugin-json": "4.1.0",
6969
"@rollup/plugin-node-resolve": "13.3.0",
7070
"@rollup/plugin-replace": "^4.0.0",
71-
"@sentry-internal/eslint-config": "3.6.1",
72-
"@sentry-internal/sentry-bundler-plugin-tsconfig": "3.6.1",
71+
"@sentry-internal/eslint-config": "4.0.2",
72+
"@sentry-internal/sentry-bundler-plugin-tsconfig": "4.0.2",
7373
"@sentry/core": "8.30.0",
7474
"@sentry/types": "8.30.0",
7575
"@sentry/utils": "8.30.0",

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

Lines changed: 45 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -182,63 +182,59 @@ export function sentryCliBinaryExists(): boolean {
182182
return fs.existsSync(SentryCli.getPath());
183183
}
184184

185+
// We need to be careful not to inject the snippet before any `"use strict";`s.
186+
// As an additional complication `"use strict";`s may come after any number of comments.
187+
const COMMENT_USE_STRICT_REGEX =
188+
// Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.
189+
/^(?:\s*|\/\*(?:.|\r|\n)*?\*\/|\/\/.*[\n\r])*(?:"[^"]*";|'[^']*';)?/;
190+
191+
/**
192+
* Simplified `renderChunk` hook type from Rollup.
193+
* We can't reference the type directly because the Vite plugin complains
194+
* about type mismatches
195+
*/
196+
type RenderChunkHook = (
197+
code: string,
198+
chunk: {
199+
fileName: string;
200+
}
201+
) => {
202+
code: string;
203+
map: SourceMap;
204+
} | null;
205+
185206
export function createRollupReleaseInjectionHooks(injectionCode: string): {
186-
resolveId: UnpluginOptions["resolveId"];
187-
load: UnpluginOptions["load"];
188-
transform: UnpluginOptions["transform"];
207+
renderChunk: RenderChunkHook;
189208
} {
190-
const virtualReleaseInjectionFileId = "\0sentry-release-injection-file";
191209
return {
192-
resolveId(id: string) {
193-
if (id === virtualReleaseInjectionFileId) {
194-
return {
195-
id: virtualReleaseInjectionFileId,
196-
external: false,
197-
moduleSideEffects: true,
198-
};
199-
} else {
200-
return null;
201-
}
202-
},
203-
204-
load(id: string) {
205-
if (id === virtualReleaseInjectionFileId) {
206-
return injectionCode;
207-
} else {
208-
return null;
209-
}
210-
},
211-
212-
transform(code: string, id: string) {
213-
if (id === virtualReleaseInjectionFileId) {
214-
return null;
215-
}
216-
217-
// id may contain query and hash which will trip up our file extension logic below
218-
const idWithoutQueryAndHash = stripQueryAndHashFromPath(id);
219-
220-
if (idWithoutQueryAndHash.match(/\\node_modules\\|\/node_modules\//)) {
221-
return null;
222-
}
223-
210+
renderChunk(code: string, chunk: { fileName: string }) {
224211
if (
225-
![".js", ".ts", ".jsx", ".tsx", ".mjs"].some((ending) =>
226-
idWithoutQueryAndHash.endsWith(ending)
212+
// chunks could be any file (html, md, ...)
213+
[".js", ".mjs", ".cjs"].some((ending) =>
214+
stripQueryAndHashFromPath(chunk.fileName).endsWith(ending)
227215
)
228216
) {
229-
return null;
230-
}
217+
const ms = new MagicString(code, { filename: chunk.fileName });
231218

232-
const ms = new MagicString(code);
219+
const match = code.match(COMMENT_USE_STRICT_REGEX)?.[0];
233220

234-
// Appending instead of prepending has less probability of mucking with user's source maps.
235-
// Luckily import statements get hoisted to the top anyways.
236-
ms.append(`\n\n;import "${virtualReleaseInjectionFileId}";`);
221+
if (match) {
222+
// Add injected code after any comments or "use strict" at the beginning of the bundle.
223+
ms.appendLeft(match.length, injectionCode);
224+
} else {
225+
// ms.replace() doesn't work when there is an empty string match (which happens if
226+
// there is neither, a comment, nor a "use strict" at the top of the chunk) so we
227+
// need this special case here.
228+
ms.prepend(injectionCode);
229+
}
237230

238-
return {
239-
code: ms.toString(),
240-
map: ms.generateMap({ hires: "boundary" }),
241-
};
231+
return {
232+
code: ms.toString(),
233+
map: ms.generateMap({ file: chunk.fileName, hires: "boundary" }),
234+
};
235+
} else {
236+
return null; // returning null means not modifying the chunk at all
237+
}
242238
},
243239
};
244240
}
@@ -253,27 +249,6 @@ export function createRollupBundleSizeOptimizationHooks(replacementValues: Sentr
253249
};
254250
}
255251

256-
// We need to be careful not to inject the snippet before any `"use strict";`s.
257-
// As an additional complication `"use strict";`s may come after any number of comments.
258-
const COMMENT_USE_STRICT_REGEX =
259-
// Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.
260-
/^(?:\s*|\/\*(?:.|\r|\n)*?\*\/|\/\/.*[\n\r])*(?:"[^"]*";|'[^']*';)?/;
261-
262-
/**
263-
* Simplified `renderChunk` hook type from Rollup.
264-
* We can't reference the type directly because the Vite plugin complains
265-
* about type mismatches
266-
*/
267-
type RenderChunkHook = (
268-
code: string,
269-
chunk: {
270-
fileName: string;
271-
}
272-
) => {
273-
code: string;
274-
map: SourceMap;
275-
} | null;
276-
277252
export function createRollupDebugIdInjectionHooks(): {
278253
renderChunk: RenderChunkHook;
279254
} {
@@ -456,7 +431,7 @@ export function createComponentNameAnnotateHooks(ignoredComponents?: string[]):
456431
}
457432

458433
export function getDebugIdSnippet(debugId: string): string {
459-
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){}};`;
434+
return `;{try{(function(){var 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){}};`;
460435
}
461436

462437
export type { Logger } from "./logger";

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

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -314,28 +314,17 @@ export function generateGlobalInjectorCode({
314314
}): string {
315315
// The code below is mostly ternary operators because it saves bundle size.
316316
// The checks are to support as many environments as possible. (Node.js, Browser, webworkers, etc.)
317-
let code = `{
318-
let _global =
319-
typeof window !== 'undefined' ?
320-
window :
321-
typeof global !== 'undefined' ?
322-
global :
323-
typeof globalThis !== 'undefined' ?
324-
globalThis :
325-
typeof self !== 'undefined' ?
326-
self :
327-
{};
328-
329-
_global.SENTRY_RELEASE={id:${JSON.stringify(release)}};`;
317+
let code = `!function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};`;
318+
319+
code += `e.SENTRY_RELEASE={id:${JSON.stringify(release)}};`;
330320

331321
if (injectBuildInformation) {
332322
const buildInfo = getBuildInformation();
333323

334-
code += `
335-
_global.SENTRY_BUILD_INFO=${JSON.stringify(buildInfo)};`;
324+
code += `e.SENTRY_BUILD_INFO=${JSON.stringify(buildInfo)};`;
336325
}
337326

338-
code += "}";
327+
code += "}();";
339328

340329
return code;
341330
}
@@ -345,28 +334,9 @@ export function generateModuleMetadataInjectorCode(metadata: any): string {
345334
// The code below is mostly ternary operators because it saves bundle size.
346335
// The checks are to support as many environments as possible. (Node.js, Browser, webworkers, etc.)
347336
// We are merging the metadata objects in case modules are bundled twice with the plugin
348-
return `{
349-
let _sentryModuleMetadataGlobal =
350-
typeof window !== "undefined"
351-
? window
352-
: typeof global !== "undefined"
353-
? global
354-
: typeof globalThis !== "undefined"
355-
? globalThis
356-
: typeof self !== "undefined"
357-
? self
358-
: {};
359-
360-
_sentryModuleMetadataGlobal._sentryModuleMetadata =
361-
_sentryModuleMetadataGlobal._sentryModuleMetadata || {};
362-
363-
_sentryModuleMetadataGlobal._sentryModuleMetadata[new _sentryModuleMetadataGlobal.Error().stack] =
364-
Object.assign(
365-
{},
366-
_sentryModuleMetadataGlobal._sentryModuleMetadata[new _sentryModuleMetadataGlobal.Error().stack],
367-
${JSON.stringify(metadata)}
368-
);
369-
}`;
337+
return `!function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};e._sentryModuleMetadata=e._sentryModuleMetadata||{},e._sentryModuleMetadata[(new e.Error).stack]=function(e){for(var n=1;n<arguments.length;n++){var a=arguments[n];if(null!=a)for(var t in a)a.hasOwnProperty(t)&&(e[t]=a[t])}return e}({},e._sentryModuleMetadata[(new e.Error).stack],${JSON.stringify(
338+
metadata
339+
)})}();`;
370340
}
371341

372342
export function getBuildInformation(): {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`generateGlobalInjectorCode generates code with release 1`] = `"!function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};e.SENTRY_RELEASE={id:\\"1.2.3\\"};}();"`;
4+
5+
exports[`generateGlobalInjectorCode generates code with release and build information 1`] = `"!function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};e.SENTRY_RELEASE={id:\\"1.2.3\\"};e.SENTRY_BUILD_INFO={\\"deps\\":[\\"myDep\\",\\"rollup\\"],\\"depsVersions\\":{\\"rollup\\":3},\\"nodeVersion\\":18};}();"`;
6+
7+
exports[`generateModuleMetadataInjectorCode generates code with empty metadata object 1`] = `"!function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};e._sentryModuleMetadata=e._sentryModuleMetadata||{},e._sentryModuleMetadata[(new e.Error).stack]=function(e){for(var n=1;n<arguments.length;n++){var a=arguments[n];if(null!=a)for(var t in a)a.hasOwnProperty(t)&&(e[t]=a[t])}return e}({},e._sentryModuleMetadata[(new e.Error).stack],{})}();"`;
8+
9+
exports[`generateModuleMetadataInjectorCode generates code with metadata object 1`] = `"!function(){var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};e._sentryModuleMetadata=e._sentryModuleMetadata||{},e._sentryModuleMetadata[(new e.Error).stack]=function(e){for(var n=1;n<arguments.length;n++){var a=arguments[n];if(null!=a)for(var t in a)a.hasOwnProperty(t)&&(e[t]=a[t])}return e}({},e._sentryModuleMetadata[(new e.Error).stack],{\\"file1.js\\":{\\"foo\\":\\"bar\\"},\\"file2.js\\":{\\"bar\\":\\"baz\\"}})}();"`;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ describe("getDebugIdSnippet", () => {
44
it("returns the debugId injection snippet for a passed debugId", () => {
55
const snippet = getDebugIdSnippet("1234");
66
expect(snippet).toMatchInlineSnapshot(
7-
`";{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]=\\"1234\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-1234\\")}catch(e){}};"`
7+
`";{try{(function(){var 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]=\\"1234\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-1234\\");})();}catch(e){}};"`
88
);
99
});
1010
});

0 commit comments

Comments
 (0)