From a1dae1f6d062d2731cc5d95b6c1f551e9e461bd5 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 15 Feb 2026 00:01:15 +0000 Subject: [PATCH 1/3] fix(metro-core): escape babel transformer path Co-authored-by: Zack Jackson --- packages/metro-core/project.json | 8 ++++ packages/metro-core/src/babel/transformer.js | 2 +- .../__tests__/babel-transformer.test.ts | 41 +++++++++++++++++++ .../src/plugin/babel-transformer.ts | 5 ++- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts diff --git a/packages/metro-core/project.json b/packages/metro-core/project.json index c8fa094939f..84878be8481 100644 --- a/packages/metro-core/project.json +++ b/packages/metro-core/project.json @@ -18,6 +18,14 @@ "options": { "lintFilePatterns": ["packages/metro-core/**/*.{ts,tsx,js,jsx}"] } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/packages/metro-core"], + "options": { + "jestConfig": "packages/metro-core/jest.config.ts", + "passWithNoTests": true + } } } } diff --git a/packages/metro-core/src/babel/transformer.js b/packages/metro-core/src/babel/transformer.js index bff4e037199..497370ba9f3 100644 --- a/packages/metro-core/src/babel/transformer.js +++ b/packages/metro-core/src/babel/transformer.js @@ -1,5 +1,5 @@ /* eslint-disable no-undef */ -const babelTransformer = require('__BABEL_TRANSFORMER_PATH__'); +const babelTransformer = require(__BABEL_TRANSFORMER_PATH__); const babelPlugins = __BABEL_PLUGINS__; /* eslint-enable no-undef */ diff --git a/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts b/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts new file mode 100644 index 00000000000..fe562e904e4 --- /dev/null +++ b/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts @@ -0,0 +1,41 @@ +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { createBabelTransformer } from '../babel-transformer'; +import type { ModuleFederationConfigNormalized } from '../../types'; + +function createConfig(): ModuleFederationConfigNormalized { + return { + name: 'test-app', + filename: 'remote.js', + remotes: {}, + exposes: {}, + shared: {}, + shareStrategy: 'loaded-first', + plugins: [], + }; +} + +describe('createBabelTransformer', () => { + it('escapes Windows paths for require()', () => { + const tmpDirPath = fs.mkdtempSync( + path.join(os.tmpdir(), 'mf-metro-'), + ); + const windowsPath = + 'C:\\Users\\someone\\project\\node_modules\\metro-babel-transformer\\src\\index.js'; + + const outputPath = createBabelTransformer({ + blacklistedPaths: [], + federationConfig: createConfig(), + originalBabelTransformerPath: windowsPath, + tmpDirPath, + enableInitializeCorePatching: false, + enableRuntimeRequirePatching: false, + }); + + const output = fs.readFileSync(outputPath, 'utf-8'); + expect(output).toContain(`require(${JSON.stringify(windowsPath)})`); + + fs.rmSync(tmpDirPath, { recursive: true, force: true }); + }); +}); diff --git a/packages/metro-core/src/plugin/babel-transformer.ts b/packages/metro-core/src/plugin/babel-transformer.ts index ecd1723b53c..72a86b0e573 100644 --- a/packages/metro-core/src/plugin/babel-transformer.ts +++ b/packages/metro-core/src/plugin/babel-transformer.ts @@ -41,7 +41,10 @@ export function createBabelTransformer({ ].filter(Boolean); const babelTransformer = transformerTemplate - .replaceAll('__BABEL_TRANSFORMER_PATH__', originalBabelTransformerPath) + .replaceAll( + '__BABEL_TRANSFORMER_PATH__', + JSON.stringify(originalBabelTransformerPath), + ) .replaceAll('__BABEL_PLUGINS__', JSON.stringify(plugins)); fs.writeFileSync(outputPath, babelTransformer, 'utf-8'); From 8735d3db497a43dbb67945c36a98484a404a333c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 15 Feb 2026 01:16:25 +0000 Subject: [PATCH 2/3] chore(metro-core): format babel transformer test --- .../metro-core/src/plugin/__tests__/babel-transformer.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts b/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts index fe562e904e4..6548824546c 100644 --- a/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts +++ b/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts @@ -18,9 +18,7 @@ function createConfig(): ModuleFederationConfigNormalized { describe('createBabelTransformer', () => { it('escapes Windows paths for require()', () => { - const tmpDirPath = fs.mkdtempSync( - path.join(os.tmpdir(), 'mf-metro-'), - ); + const tmpDirPath = fs.mkdtempSync(path.join(os.tmpdir(), 'mf-metro-')); const windowsPath = 'C:\\Users\\someone\\project\\node_modules\\metro-babel-transformer\\src\\index.js'; From fe538e7e8ca2c6449bcdb960a4f46091b182bebf Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 24 Feb 2026 11:17:16 -0800 Subject: [PATCH 3/3] fix(metro-core): align test target and memfs usage Keep metro-core on the vitest Nx executor and remove the stale jest target. Switch babel-transformer Windows path tests to memfs-backed file operations. Co-authored-by: Cursor --- packages/metro-core/project.json | 8 ----- .../__tests__/babel-transformer.test.ts | 31 ++++++++++++++++--- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/packages/metro-core/project.json b/packages/metro-core/project.json index 1e8d4cfe9f2..d15db81236e 100644 --- a/packages/metro-core/project.json +++ b/packages/metro-core/project.json @@ -25,14 +25,6 @@ "options": { "lintFilePatterns": ["packages/metro-core/**/*.{ts,tsx,js,jsx}"] } - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/packages/metro-core"], - "options": { - "jestConfig": "packages/metro-core/jest.config.ts", - "passWithNoTests": true - } } } } diff --git a/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts b/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts index 6548824546c..1124533c537 100644 --- a/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts +++ b/packages/metro-core/src/plugin/__tests__/babel-transformer.test.ts @@ -1,6 +1,7 @@ import fs from 'node:fs'; -import os from 'node:os'; import path from 'node:path'; +import { vol } from 'memfs'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import { createBabelTransformer } from '../babel-transformer'; import type { ModuleFederationConfigNormalized } from '../../types'; @@ -17,8 +18,32 @@ function createConfig(): ModuleFederationConfigNormalized { } describe('createBabelTransformer', () => { + afterEach(() => { + vol.reset(); + vi.restoreAllMocks(); + }); + it('escapes Windows paths for require()', () => { - const tmpDirPath = fs.mkdtempSync(path.join(os.tmpdir(), 'mf-metro-')); + const realReadFileSync = fs.readFileSync.bind(fs); + vi.spyOn(fs, 'readFileSync').mockImplementation(((filePath, options) => { + const targetPath = filePath.toString(); + if (vol.existsSync(targetPath)) { + return vol.readFileSync(targetPath, options as never); + } + return realReadFileSync(filePath, options as never); + }) as typeof fs.readFileSync); + vi.spyOn(fs, 'writeFileSync').mockImplementation((( + filePath, + data, + options, + ) => { + const targetPath = filePath.toString(); + vol.mkdirSync(path.dirname(targetPath), { recursive: true }); + vol.writeFileSync(targetPath, data, options as never); + }) as typeof fs.writeFileSync); + + const tmpDirPath = path.join('/virtual', '.mf'); + vol.mkdirSync(tmpDirPath, { recursive: true }); const windowsPath = 'C:\\Users\\someone\\project\\node_modules\\metro-babel-transformer\\src\\index.js'; @@ -33,7 +58,5 @@ describe('createBabelTransformer', () => { const output = fs.readFileSync(outputPath, 'utf-8'); expect(output).toContain(`require(${JSON.stringify(windowsPath)})`); - - fs.rmSync(tmpDirPath, { recursive: true, force: true }); }); });