From 7fd512afedf0e54a9572c2c31545ca61e5a59aed Mon Sep 17 00:00:00 2001 From: Krystof Woldrich <31292499+krystofwoldrich@users.noreply.github.com> Date: Thu, 21 Nov 2024 10:30:16 +0100 Subject: [PATCH] fix(metro): Use env for default Babel transformer path (#4298) --- CHANGELOG.md | 7 +++ packages/core/src/js/tools/metroconfig.ts | 7 +-- .../js/tools/sentryBabelTransformerUtils.ts | 52 +++++-------------- packages/core/test/tools/metroconfig.test.ts | 43 ++------------- .../test/tools/sentryBabelTransformer.test.ts | 12 ++--- 5 files changed, 27 insertions(+), 94 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 135738a416..6e7c417a42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ > make sure you follow our [migration guide](https://docs.sentry.io/platforms/react-native/migration/) first. +## Unreleased + +### Fixes + +- Remove `.sentry` tmp directory and use environmental variables instead to save default Babel transformer path ([#4298](https://github.com/getsentry/sentry-react-native/pull/4298)) + - This resolves concurrency issues when running multiple bundle processes + ## 6.3.0-beta.1 ### Features diff --git a/packages/core/src/js/tools/metroconfig.ts b/packages/core/src/js/tools/metroconfig.ts index 6749c5d988..1acec9d378 100644 --- a/packages/core/src/js/tools/metroconfig.ts +++ b/packages/core/src/js/tools/metroconfig.ts @@ -5,7 +5,7 @@ import * as process from 'process'; import { env } from 'process'; import { enableLogger } from './enableLogger'; -import { cleanDefaultBabelTransformerPath, saveDefaultBabelTransformerPath } from './sentryBabelTransformerUtils'; +import { setSentryDefaultBabelTransformerPathEnv } from './sentryBabelTransformerUtils'; import { createSentryMetroSerializer, unstable_beforeAssetSerializationPlugin } from './sentryMetroSerializer'; import type { DefaultConfigOptions } from './vendor/expo/expoconfig'; export * from './sentryMetroSerializer'; @@ -143,10 +143,7 @@ export function withSentryBabelTransformer(config: MetroConfig): MetroConfig { } if (defaultBabelTransformerPath) { - saveDefaultBabelTransformerPath(defaultBabelTransformerPath); - process.on('exit', () => { - cleanDefaultBabelTransformerPath(); - }); + setSentryDefaultBabelTransformerPathEnv(defaultBabelTransformerPath); } return { diff --git a/packages/core/src/js/tools/sentryBabelTransformerUtils.ts b/packages/core/src/js/tools/sentryBabelTransformerUtils.ts index dd04d2f67b..29cb715e52 100644 --- a/packages/core/src/js/tools/sentryBabelTransformerUtils.ts +++ b/packages/core/src/js/tools/sentryBabelTransformerUtils.ts @@ -1,62 +1,34 @@ import { logger } from '@sentry/utils'; -import * as fs from 'fs'; -import * as path from 'path'; import * as process from 'process'; import type { BabelTransformer } from './vendor/metro/metroBabelTransformer'; -/** - * Saves default Babel transformer path to the project root. - */ -export function saveDefaultBabelTransformerPath(defaultBabelTransformerPath: string): void { - try { - fs.mkdirSync(path.join(process.cwd(), '.sentry'), { recursive: true }); - fs.writeFileSync(getDefaultBabelTransformerPath(), defaultBabelTransformerPath); - logger.debug('Saved default Babel transformer path'); - } catch (e) { - // eslint-disable-next-line no-console - console.error('[Sentry] Failed to save default Babel transformer path:', e); - } -} +export const SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH = 'SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH'; /** - * Reads default Babel transformer path from the project root. + * Sets default Babel transformer path to the environment variables. */ -export function readDefaultBabelTransformerPath(): string | undefined { - try { - return fs.readFileSync(getDefaultBabelTransformerPath()).toString(); - } catch (e) { - // eslint-disable-next-line no-console - console.error('[Sentry] Failed to read default Babel transformer path:', e); - } - return undefined; +export function setSentryDefaultBabelTransformerPathEnv(defaultBabelTransformerPath: string): void { + process.env[SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH] = defaultBabelTransformerPath; + logger.debug(`Saved default Babel transformer path ${defaultBabelTransformerPath}`); } /** - * Cleans default Babel transformer path from the project root. + * Reads default Babel transformer path from the environment variables. */ -export function cleanDefaultBabelTransformerPath(): void { - try { - fs.unlinkSync(getDefaultBabelTransformerPath()); - logger.debug('Cleaned default Babel transformer path'); - } catch (e) { - // We don't want to fail the build if we can't clean the file - // eslint-disable-next-line no-console - console.error('[Sentry] Failed to clean default Babel transformer path:', e); - } -} - -function getDefaultBabelTransformerPath(): string { - return path.join(process.cwd(), '.sentry/.defaultBabelTransformerPath'); +export function getSentryDefaultBabelTransformerPathEnv(): string | undefined { + return process.env[SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH]; } /** * Loads default Babel transformer from `@react-native/metro-config` -> `@react-native/metro-babel-transformer`. */ export function loadDefaultBabelTransformer(): BabelTransformer { - const defaultBabelTransformerPath = readDefaultBabelTransformerPath(); + const defaultBabelTransformerPath = getSentryDefaultBabelTransformerPathEnv(); if (!defaultBabelTransformerPath) { - throw new Error('Default Babel Transformer Path not found in `.sentry` directory.'); + throw new Error( + `Default Babel transformer path environment variable ${SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH} is not set.`, + ); } logger.debug(`Loading default Babel transformer from ${defaultBabelTransformerPath}`); diff --git a/packages/core/test/tools/metroconfig.test.ts b/packages/core/test/tools/metroconfig.test.ts index 24135932d8..3c8a9a10b3 100644 --- a/packages/core/test/tools/metroconfig.test.ts +++ b/packages/core/test/tools/metroconfig.test.ts @@ -1,16 +1,5 @@ -jest.mock('fs', () => { - return { - readFile: jest.fn(), - mkdirSync: jest.fn(), - writeFileSync: jest.fn(), - unlinkSync: jest.fn(), - }; -}); - import type { getDefaultConfig } from 'expo/metro-config'; -import * as fs from 'fs'; import type { MetroConfig } from 'metro'; -import * as path from 'path'; import * as process from 'process'; import { @@ -19,6 +8,7 @@ import { withSentryFramesCollapsed, withSentryResolver, } from '../../src/js/tools/metroconfig'; +import { SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH } from '../../src/js/tools/sentryBabelTransformerUtils'; type MetroFrame = Parameters['symbolicator']>['customizeFrame']>[0]; @@ -69,43 +59,16 @@ describe('metroconfig', () => { }, ); - test.each([ - [{ transformer: { babelTransformerPath: 'babelTransformerPath' }, projectRoot: 'project/root' }], - [{ transformer: { babelTransformerPath: 'babelTransformerPath' } }], - ])('save default babel transformer path to a file', () => { + test('save default babel transformer path to environment variable', () => { const defaultBabelTransformerPath = '/default/babel/transformer'; withSentryBabelTransformer({ transformer: { babelTransformerPath: defaultBabelTransformerPath, }, - projectRoot: 'project/root', }); - expect(fs.mkdirSync).toHaveBeenCalledWith(path.join(process.cwd(), '.sentry'), { recursive: true }); - expect(fs.writeFileSync).toHaveBeenCalledWith( - path.join(process.cwd(), '.sentry/.defaultBabelTransformerPath'), - defaultBabelTransformerPath, - ); - }); - - test('clean default babel transformer path file on exit', () => { - const processOnSpy: jest.SpyInstance = jest.spyOn(process, 'on'); - - const defaultBabelTransformerPath = 'defaultBabelTransformerPath'; - - withSentryBabelTransformer({ - transformer: { - babelTransformerPath: defaultBabelTransformerPath, - }, - projectRoot: 'project/root', - }); - - const actualExitHandler: () => void | undefined = processOnSpy.mock.calls[0][1]; - actualExitHandler?.(); - - expect(processOnSpy).toHaveBeenCalledWith('exit', expect.any(Function)); - expect(fs.unlinkSync).toHaveBeenCalledWith(path.join(process.cwd(), '.sentry/.defaultBabelTransformerPath')); + expect(process.env[SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH]).toBe(defaultBabelTransformerPath); }); test('return config with sentry babel transformer path', () => { diff --git a/packages/core/test/tools/sentryBabelTransformer.test.ts b/packages/core/test/tools/sentryBabelTransformer.test.ts index 3c888d1195..cc61691616 100644 --- a/packages/core/test/tools/sentryBabelTransformer.test.ts +++ b/packages/core/test/tools/sentryBabelTransformer.test.ts @@ -1,14 +1,8 @@ -jest.mock('fs', () => { - return { - readFileSync: jest.fn(), - }; -}); +import * as process from 'process'; -import * as fs from 'fs'; +import { SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH } from '../../src/js/tools/sentryBabelTransformerUtils'; -// needs to be defined before sentryBabelTransformer is imported -// the transformer is created on import (side effect) -(fs.readFileSync as jest.Mock).mockReturnValue(require.resolve('./fixtures/mockBabelTransformer.js')); +process.env[SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH] = require.resolve('./fixtures/mockBabelTransformer.js'); import * as SentryBabelTransformer from '../../src/js/tools/sentryBabelTransformer'; import type { BabelTransformerArgs } from '../../src/js/tools/vendor/metro/metroBabelTransformer';