Include preset dependencies in main cache keys (#58251)

Summary:
Development `-main` builds compute the Babel preset transformer cache key from preset JavaScript sources, but omit `package.json`. React Native regularly updates parser and Babel plugin dependencies without changing those source files, so a dependency-only update can preserve the cache key and reuse transforms produced by an older dependency set.

Include the preset package metadata bytes in the existing MD5 input. This adds one small file read only to the memoized `-main` slow path; published releases remain keyed directly by their immutable package version.

## Changelog:

[INTERNAL] [FIXED] - Invalidate React Native Babel preset development caches when dependency metadata changes.

Pull Request resolved: https://github.com/react/react-native/pull/58251

Test Plan:
- Added an isolated-module regression that supplies two package metadata contents with identical preset source contents; pristine main returns the same key, while the fix returns different keys.
- Full preset Jest passes: 5/5 suites, 111/111 tests, 16 snapshots.
- Fresh Flow check reports 0 errors.
- Targeted no-ignore ESLint, Prettier, and `git diff --check` pass.

No transform output, public API, published-release cache behavior, or UI changes.

Reviewed By: christophpurrer

Differential Revision: D118440621

Pulled By: vzaidman

fbshipit-source-id: 21d4df2d5bc0428d6cf2138b2f5230d777b7ddb0
This commit is contained in:
Oskar Eichler
2026-09-02 14:32:29 -07:00
committed by meta-codesync[bot]
parent 9ad8c830bd
commit 9c6efa25c1
2 changed files with 30 additions and 0 deletions
@@ -0,0 +1,29 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @noflow
*/
'use strict';
function getCacheKey(packageContents) {
jest.resetModules();
jest.doMock('node:fs', () => ({
readFileSync: filename =>
filename.endsWith('package.json')
? Buffer.from(packageContents)
: Buffer.from(filename),
}));
return require('../index').getCacheKey();
}
test('cache key includes package metadata for main builds', () => {
expect(getCacheKey('{"dependency":"1.0.0"}')).not.toBe(
getCacheKey('{"dependency":"2.0.0"}'),
);
});
+1
View File
@@ -35,6 +35,7 @@ module.exports.getCacheKey = () => {
const {readFileSync} = require('node:fs');
const key = createHash('md5');
[
readFileSync(require.resolve('../package.json')),
readFileSync(__filename),
readFileSync(require.resolve('./configs/main.js')),
readFileSync(require.resolve('./configs/hmr.js')),