From 5b49901fdf04afb3c03eda02314790c6bec4fafd Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 28 May 2026 15:20:34 -0800 Subject: [PATCH 1/2] fix(scripts): rename local __dirname shadow that breaks Jest+SWC `scripts/genPlatformProductInfo.ts` and `scripts/extractFormFields.ts` both reconstruct `__dirname` (and one of them `__filename`) under ESM via `path.dirname(fileURLToPath(import.meta.url))`. When Jest's `@swc/jest` transformer compiles these files to CommonJS for dependency analysis (e.g. during `--listTests --changedSince` on a PR), SWC emits the local `const __dirname = ...` verbatim. That collides with the `__dirname` Node already provides via the module wrapper: ``` /scripts/genPlatformProductInfo.ts:51 const __dirname = _nodepath.dirname((0, _nodeurl.fileURLToPath)( require("url").pathToFileURL(__filename).toString())); ^ SyntaxError: Identifier '__dirname' has already been declared ``` The crash cascades through Jest's worker pool and surfaces as a wave of "Your test suite must contain at least one test" on unrelated files, ultimately timing out the shards at 30 min. The earlier fix in #116413 (testPathIgnorePatterns + modulePathIgnorePatterns for `/scripts/`) only governs test discovery and the in-test-environment require; it doesn't stop Jest's pre-test dependency analysis from invoking the transformer on these scripts. Renaming the shadowing identifiers removes the collision at the source. Behavior-equivalent at runtime: the original locals only shadowed the wrapper-provided names inside the module, and the renamed THIS_DIR / THIS_FILE are used identically (for path.resolve / path.join in the same module). Verified: `pnpm exec jest --listTests --json --changedSince=$(git rev-parse origin/master) --passWithNoTests` returns `[]` locally with no parse errors. Co-Authored-By: Claude Opus 4.7 (1M context) --- scripts/extractFormFields.ts | 14 ++++++++++---- scripts/genPlatformProductInfo.ts | 9 +++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/scripts/extractFormFields.ts b/scripts/extractFormFields.ts index 736b94314ff6..da0385aeb583 100644 --- a/scripts/extractFormFields.ts +++ b/scripts/extractFormFields.ts @@ -11,8 +11,14 @@ import {fileURLToPath} from 'node:url'; import * as ts from 'typescript'; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +// Named THIS_FILE / THIS_DIR rather than the conventional __filename / +// __dirname so SWC's CJS transform (used by Jest) doesn't emit a +// `const __dirname = ...` that collides with the wrapper-provided +// binding and crashes the frontend test run with a SyntaxError. +// Behavior-equivalent at runtime — the originals only shadowed the +// wrapper inside this module. +const THIS_FILE = fileURLToPath(import.meta.url); +const THIS_DIR = path.dirname(THIS_FILE); interface ExtractedField { formId: string; @@ -480,14 +486,14 @@ ${registryEntries} // Main execution try { - const configPath = path.join(__dirname, '../tsconfig.json'); + const configPath = path.join(THIS_DIR, '../tsconfig.json'); const extractor = new FormFieldExtractor(configPath); console.log('🔍 Extracting form fields from TypeScript files...'); const fields = extractor.extractAllFields(); const outputPath = path.join( - __dirname, + THIS_DIR, '../static/app/components/core/form/generatedFieldRegistry.ts' ); diff --git a/scripts/genPlatformProductInfo.ts b/scripts/genPlatformProductInfo.ts index 16b31ac937ca..b91cb215cb7b 100644 --- a/scripts/genPlatformProductInfo.ts +++ b/scripts/genPlatformProductInfo.ts @@ -26,8 +26,13 @@ import {fileURLToPath} from 'node:url'; import * as ts from 'typescript'; import {parse as parseYaml} from 'yaml'; -const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const SENTRY_ROOT = path.resolve(__dirname, '..'); +// Named THIS_DIR rather than __dirname so SWC's CJS transform (used by Jest) +// doesn't emit a `const __dirname = ...` that collides with the wrapper- +// provided binding and crashes the whole frontend test run with a +// SyntaxError. The original `__dirname` only shadowed the wrapper inside +// this module anyway, so the rename is behavior-equivalent at runtime. +const THIS_DIR = path.dirname(fileURLToPath(import.meta.url)); +const SENTRY_ROOT = path.resolve(THIS_DIR, '..'); const DOCS_ROOT = process.env.SENTRY_DOCS_PATH ? path.resolve(process.env.SENTRY_DOCS_PATH) : path.resolve(SENTRY_ROOT, '..', 'sentry-docs'); From cf1db67ea29373369e59c4a09780d03b92a06657 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 28 May 2026 15:25:20 -0800 Subject: [PATCH 2/2] revert(jest): remove scripts/ ignore patterns now that root cause is fixed PR #116413 added `/scripts/` to `testPathIgnorePatterns` and `modulePathIgnorePatterns` as a workaround for the SWC `__dirname` SyntaxError cascade. Investigation showed those patterns don't actually prevent the failure (they only govern test discovery and the runtime test environment, not Jest's pre-test transform during `--listTests --changedSince`). The real fix is in the preceding commit (`fix(scripts): rename local __dirname shadow ...`), which removes the collision at the source by renaming the local helpers to `THIS_DIR` / `THIS_FILE`. With that in place, the ignore patterns are dead config that misleadingly claim to address the SWC issue. Remove them. Verified: `pnpm exec jest --listTests --json --changedSince=$(git rev-parse origin/master) --passWithNoTests` still returns `[]` locally after the revert. Co-Authored-By: Claude Opus 4.7 (1M context) --- jest.config.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/jest.config.ts b/jest.config.ts index 81bfa6152746..03c34f6c609b 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -323,15 +323,7 @@ const config: Config.InitialOptions = { '/tests/js/setupFramework.ts', ], testMatch: testMatch || ['/(static|tests/js)/**/?(*.)+(spec|test).[jt]s?(x)'], - testPathIgnorePatterns: [ - '/tests/sentry/lang/javascript/', - // ESM-style helper scripts (e.g. scripts/genPlatformProductInfo.ts use - // `const __dirname = path.dirname(fileURLToPath(import.meta.url))`) that - // SWC's CJS transform redeclares — collides with Node's module wrapper. - // None of these are tests; keep them out of Jest's discovery entirely. - '/scripts/', - ], - modulePathIgnorePatterns: ['/scripts/'], + testPathIgnorePatterns: ['/tests/sentry/lang/javascript/'], unmockedModulePathPatterns: [ '/node_modules/react',