|
1 | 1 | import { Compiler } from "webpack"; |
2 | | -import { getDebugIdSnippet, sentryUnpluginFactory, createRollupInjectionHooks } from "../src"; |
3 | | -import { CodeInjection, containsOnlyImports } from "../src/utils"; |
| 2 | +import { getDebugIdSnippet, sentryUnpluginFactory } from "../src"; |
| 3 | +import { containsOnlyImports } from "../src/utils"; |
4 | 4 |
|
5 | 5 | describe("getDebugIdSnippet", () => { |
6 | 6 | it("returns the debugId injection snippet for a passed debugId", () => { |
@@ -142,200 +142,6 @@ app.mount('#app'); |
142 | 142 | }); |
143 | 143 | }); |
144 | 144 |
|
145 | | -describe("createRollupInjectionHooks", () => { |
146 | | - const inject = new CodeInjection(); |
147 | | - const hooks = createRollupInjectionHooks(inject, true); |
148 | | - |
149 | | - beforeEach(() => { |
150 | | - inject.clear(); |
151 | | - }); |
152 | | - |
153 | | - describe("renderChunk", () => { |
154 | | - it("should inject debug ID into clean JavaScript files", () => { |
155 | | - const code = 'console.log("Hello world");'; |
156 | | - const result = hooks.renderChunk(code, { fileName: "bundle.js" }); |
157 | | - |
158 | | - expect(result).not.toBeNull(); |
159 | | - expect(result?.code).toMatchInlineSnapshot( |
160 | | - `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"d4309f93-5358-4ae1-bcf0-3813aa590eb5\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-d4309f93-5358-4ae1-bcf0-3813aa590eb5\\");}catch(e){}}();console.log(\\"Hello world\\");"` |
161 | | - ); |
162 | | - }); |
163 | | - |
164 | | - it("should inject debug ID after 'use strict'", () => { |
165 | | - const code = '"use strict";\nconsole.log("Hello world");'; |
166 | | - const result = hooks.renderChunk(code, { fileName: "bundle.js" }); |
167 | | - |
168 | | - expect(result).not.toBeNull(); |
169 | | - expect(result?.code).toMatchInlineSnapshot(` |
170 | | - "\\"use strict\\";!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"79a86c07-8ecc-4367-82b0-88cf822f2d41\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-79a86c07-8ecc-4367-82b0-88cf822f2d41\\");}catch(e){}}(); |
171 | | - console.log(\\"Hello world\\");" |
172 | | - `); |
173 | | - }); |
174 | | - |
175 | | - it.each([ |
176 | | - ["bundle.js"], |
177 | | - ["bundle.mjs"], |
178 | | - ["bundle.cjs"], |
179 | | - ["bundle.js?foo=bar"], |
180 | | - ["bundle.js#hash"], |
181 | | - ])("should process file '%s': %s", (fileName) => { |
182 | | - const code = 'console.log("test");'; |
183 | | - const result = hooks.renderChunk(code, { fileName }); |
184 | | - |
185 | | - expect(result).not.toBeNull(); |
186 | | - expect(result?.code).toMatchInlineSnapshot( |
187 | | - `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"b80112c0-6818-486d-96f0-185c023439b4\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-b80112c0-6818-486d-96f0-185c023439b4\\");}catch(e){}}();console.log(\\"test\\");"` |
188 | | - ); |
189 | | - }); |
190 | | - |
191 | | - it.each([["index.html"], ["styles.css"]])("should NOT process file '%s': %s", (fileName) => { |
192 | | - const code = 'console.log("test");'; |
193 | | - const result = hooks.renderChunk(code, { fileName }); |
194 | | - |
195 | | - expect(result).toBeNull(); |
196 | | - }); |
197 | | - |
198 | | - it.each([ |
199 | | - [ |
200 | | - "inline format at start", |
201 | | - ';{try{(function(){var e="undefined"!=typeof window?window:e._sentryDebugIdIdentifier="sentry-dbid-existing-id");})();}catch(e){}};console.log("test");', |
202 | | - ], |
203 | | - [ |
204 | | - "comment format at end", |
205 | | - 'console.log("test");\n//# debugId=f6ccd6f4-7ea0-4854-8384-1c9f8340af81\n//# sourceMappingURL=bundle.js.map', |
206 | | - ], |
207 | | - [ |
208 | | - "inline format with large file", |
209 | | - '"use strict";\n' + |
210 | | - "// comment\n".repeat(10) + |
211 | | - ';{try{(function(){var e="undefined"!=typeof window?window:e._sentryDebugIdIdentifier="sentry-dbid-existing-id");})();}catch(e){}};' + |
212 | | - '\nconsole.log("line");\n'.repeat(100), |
213 | | - ], |
214 | | - ])("should NOT inject when debug ID already exists (%s)", (_description, code) => { |
215 | | - const result = hooks.renderChunk(code, { fileName: "bundle.js" }); |
216 | | - expect(result?.code).not.toContain("_sentryDebugIds"); |
217 | | - }); |
218 | | - |
219 | | - it("should only check boundaries for performance (not entire file)", () => { |
220 | | - // Inline format beyond first 6KB boundary |
221 | | - const codeWithInlineBeyond6KB = |
222 | | - "a".repeat(6100) + |
223 | | - ';{try{(function(){var e="undefined"!=typeof window?window:e._sentryDebugIdIdentifier="sentry-dbid-existing-id");})();}catch(e){}};'; |
224 | | - |
225 | | - expect(hooks.renderChunk(codeWithInlineBeyond6KB, { fileName: "bundle.js" })).not.toBeNull(); |
226 | | - |
227 | | - // Comment format beyond last 500 bytes boundary |
228 | | - const codeWithCommentBeyond500B = |
229 | | - "//# debugId=f6ccd6f4-7ea0-4854-8384-1c9f8340af81\n" + "a".repeat(600); |
230 | | - |
231 | | - expect( |
232 | | - hooks.renderChunk(codeWithCommentBeyond500B, { fileName: "bundle.js" }) |
233 | | - ).not.toBeNull(); |
234 | | - }); |
235 | | - |
236 | | - describe("HTML facade chunks (MPA vs SPA)", () => { |
237 | | - // Issue #829: MPA facades should be skipped |
238 | | - // Regression fix: SPA main bundles with HTML facades should NOT be skipped |
239 | | - |
240 | | - it.each([ |
241 | | - ["empty", ""], |
242 | | - ["only side-effect imports", `import './shared-module.js';`], |
243 | | - ["only named imports", `import { foo, bar } from './shared-module.js';`], |
244 | | - ["only re-exports", `export * from './shared-module.js';`], |
245 | | - [ |
246 | | - "multiple imports and comments", |
247 | | - `// This is a facade module |
248 | | -import './moduleA.js'; |
249 | | -import { x } from './moduleB.js'; |
250 | | -/* block comment */ |
251 | | -export * from './moduleC.js';`, |
252 | | - ], |
253 | | - ["'use strict' and imports only", `"use strict";\nimport './shared-module.js';`], |
254 | | - ["query string in facadeModuleId", `import './shared.js';`, "?query=param"], |
255 | | - ["hash in facadeModuleId", `import './shared.js';`, "#hash"], |
256 | | - ])("should SKIP HTML facade chunks: %s", (_, code, suffix = "") => { |
257 | | - const result = hooks.renderChunk(code, { |
258 | | - fileName: "page1.js", |
259 | | - facadeModuleId: `/path/to/page1.html${suffix}`, |
260 | | - }); |
261 | | - expect(result).toBeNull(); |
262 | | - }); |
263 | | - |
264 | | - it("should inject into HTML facade with function declarations", () => { |
265 | | - const result = hooks.renderChunk(`function main() { console.log("hello"); }`, { |
266 | | - fileName: "index.js", |
267 | | - facadeModuleId: "/path/to/index.html", |
268 | | - }); |
269 | | - expect(result).not.toBeNull(); |
270 | | - expect(result?.code).toMatchInlineSnapshot( |
271 | | - `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"c4c89e04-3658-4874-b25b-07e638185091\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-c4c89e04-3658-4874-b25b-07e638185091\\");}catch(e){}}();function main() { console.log(\\"hello\\"); }"` |
272 | | - ); |
273 | | - }); |
274 | | - |
275 | | - it("should inject into HTML facade with variable declarations", () => { |
276 | | - const result = hooks.renderChunk(`const x = 42;`, { |
277 | | - fileName: "index.js", |
278 | | - facadeModuleId: "/path/to/index.html", |
279 | | - }); |
280 | | - expect(result).not.toBeNull(); |
281 | | - expect(result?.code).toMatchInlineSnapshot( |
282 | | - `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"43e69766-1963-49f2-a291-ff8de60cc652\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-43e69766-1963-49f2-a291-ff8de60cc652\\");}catch(e){}}();const x = 42;"` |
283 | | - ); |
284 | | - }); |
285 | | - |
286 | | - it("should inject into HTML facade with substantial code (SPA main bundle)", () => { |
287 | | - const code = `import { initApp } from './app.js'; |
288 | | -
|
289 | | -const config = { debug: true }; |
290 | | -
|
291 | | -function bootstrap() { |
292 | | - initApp(config); |
293 | | -} |
294 | | -
|
295 | | -bootstrap();`; |
296 | | - const result = hooks.renderChunk(code, { |
297 | | - fileName: "index.js", |
298 | | - facadeModuleId: "/path/to/index.html", |
299 | | - }); |
300 | | - expect(result).not.toBeNull(); |
301 | | - expect(result?.code).toMatchInlineSnapshot(` |
302 | | - "!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"d0c4524b-496e-45a4-9852-7558d043ba3c\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-d0c4524b-496e-45a4-9852-7558d043ba3c\\");}catch(e){}}();import { initApp } from './app.js'; |
303 | | -
|
304 | | - const config = { debug: true }; |
305 | | -
|
306 | | - function bootstrap() { |
307 | | - initApp(config); |
308 | | - } |
309 | | -
|
310 | | - bootstrap();" |
311 | | - `); |
312 | | - }); |
313 | | - |
314 | | - it("should inject into HTML facade with mixed imports and code", () => { |
315 | | - const result = hooks.renderChunk( |
316 | | - `import './polyfills.js';\nimport { init } from './app.js';\n\ninit();`, |
317 | | - { fileName: "index.js", facadeModuleId: "/path/to/index.html" } |
318 | | - ); |
319 | | - expect(result).not.toBeNull(); |
320 | | - expect(result?.code).toMatchInlineSnapshot(` |
321 | | - "!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"28f0bbaa-9aeb-40c4-98c9-4e44f1d4e175\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-28f0bbaa-9aeb-40c4-98c9-4e44f1d4e175\\");}catch(e){}}();import './polyfills.js'; |
322 | | - import { init } from './app.js'; |
323 | | -
|
324 | | - init();" |
325 | | - `); |
326 | | - }); |
327 | | - |
328 | | - it("should inject into regular JS chunks (no HTML facade)", () => { |
329 | | - const result = hooks.renderChunk(`console.log("Hello");`, { fileName: "bundle.js" }); |
330 | | - expect(result).not.toBeNull(); |
331 | | - expect(result?.code).toMatchInlineSnapshot( |
332 | | - `"!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof globalThis?globalThis:\\"undefined\\"!=typeof self?self:{};var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"79f18a7f-ca16-4168-9797-906c82058367\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-79f18a7f-ca16-4168-9797-906c82058367\\");}catch(e){}}();console.log(\\"Hello\\");"` |
333 | | - ); |
334 | | - }); |
335 | | - }); |
336 | | - }); |
337 | | -}); |
338 | | - |
339 | 145 | describe("sentryUnpluginFactory sourcemaps.disable behavior", () => { |
340 | 146 | const mockComponentNameAnnotatePlugin = jest.fn(() => ({ |
341 | 147 | name: "mock-component-name-annotate-plugin", |
|
0 commit comments