Fix new codegen API disabling behaviour of the old one (#51867)

Summary:
Hey, I'm bumping `react-native-screens` to 0.80.0-rc.4 right now & noticed that codegen does not work as expected. It crawls whole library, file by file (when working on a library it also includes nodemodules etc), despite `componentProvider` field being defined in `codegenConfig` in `package.json`.

Namely https://github.com/facebook/react-native/issues/49941 introduced a regression for libraries that stick to the old codegen config format due to compatibility reasons. Take a look at [this code](https://github.com/facebook/react-native/blob/78caa07ff867255724e4b0ce3557ff5793b6ce1b/packages/react-native/scripts/codegen/generate-artifacts-executor/generateRCTThirdPartyComponents.js#L60-L103). We first do a pass for "old API", [removing libraries with `componentProvider` in their codegen config from `librariesToCrawl`](https://github.com/facebook/react-native/blob/78caa07ff867255724e4b0ce3557ff5793b6ce1b/packages/react-native/scripts/codegen/generate-artifacts-executor/generateRCTThirdPartyComponents.js#L66-L75), just to later [add **ALL** libraries](https://github.com/facebook/react-native/blob/78caa07ff867255724e4b0ce3557ff5793b6ce1b/packages/react-native/scripts/codegen/generate-artifacts-executor/generateRCTThirdPartyComponents.js#L86-L89) that do not support new codegen config format back again to `librariesToCrawl`.

This PR improves the filtering condition, to parse codegen annotations only for libraries that have defined any of the fields from the new config format (opted in for new system).

I want to emphasise that this is a significant regression, because it ruins experience of library maintenance, vastly increasing pods installation time.

## Changelog:

[IOS] [FIXED] - Fix codegen crawling all library code with `componentProvider` defined in config

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests

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

Test Plan:
1. Setup an application with any third party library, that uses "old" codegen config format, e.g. `react-native-screens@4.11.1`
2. `cd ios && bundle exec pod install`
3. Observe the codegen logs - it crawles the library instead of using provided information.

Reviewed By: cortinico

Differential Revision: D76126649

Pulled By: cipolleschi

fbshipit-source-id: 6f9c9dffcdca7204a78b4b55db10249240146141
This commit is contained in:
Kacper Kafara
2025-06-09 14:02:39 +00:00
committed by React Native Bot
parent a1bad641bc
commit 4b65d0ee34
2 changed files with 18 additions and 8 deletions
@@ -291,9 +291,7 @@ exports[`execute test-app "RCTThirdPartyComponentsProvider.mm" should match snap
dispatch_once(&nativeComponentsToken, ^{
thirdPartyComponents = @{
@\\"TestAppDeprecatedComponent\\": NSClassFromString(@\\"RCTTestAppDeprecatedComponentClass\\"), // test-app
@\\"TestAppComponent\\": NSClassFromString(@\\"RCTTestAppComponent\\"), // test-app
@\\"TestLibraryDeprecatedComponent\\": NSClassFromString(@\\"RCTTestLibraryDeprecatedComponentClass\\"), // test-library
@\\"TestLibraryComponent\\": NSClassFromString(@\\"RCTTestLibraryComponent\\"), // test-library
};
});
@@ -778,7 +776,7 @@ exports[`execute test-app-legacy "RCTThirdPartyComponentsProvider.mm" should mat
dispatch_once(&nativeComponentsToken, ^{
thirdPartyComponents = @{
@\\"TestAppDeprecatedComponent\\": NSClassFromString(@\\"RCTTestAppDeprecatedComponentClass\\"), // test-app-legacy
};
});
@@ -52,8 +52,23 @@ function generateRCTThirdPartyComponents(libraries, outputDir) {
const librariesToCrawl = {};
// Using new API explicitly or not using any config field to define components.
const componentLibrariesUsingNewApi = [];
const componentLibrariesUsingOldApi = [];
for (const library of componentLibraries) {
if (
library.config.ios?.components ||
!library.config.ios?.componentProvider
) {
componentLibrariesUsingNewApi.push(library);
} else {
componentLibrariesUsingOldApi.push(library);
}
}
// Old API
componentLibraries.forEach(library => {
componentLibrariesUsingOldApi.forEach(library => {
const {config, libraryPath} = library;
const libraryName = JSON.parse(
fs.readFileSync(path.join(libraryPath, 'package.json')),
@@ -62,9 +77,6 @@ function generateRCTThirdPartyComponents(libraries, outputDir) {
librariesToCrawl[libraryName] = library;
const componentsProvider = config.ios?.componentProvider;
if (!componentsProvider) {
return;
}
delete librariesToCrawl[libraryName];
componentsInLibraries[libraryName] =
@@ -79,7 +91,7 @@ function generateRCTThirdPartyComponents(libraries, outputDir) {
});
// New API
const iosAnnotations = parseiOSAnnotations(componentLibraries);
const iosAnnotations = parseiOSAnnotations(componentLibrariesUsingNewApi);
for (const [libraryName, annotationMap] of Object.entries(iosAnnotations)) {
const {library, components} = annotationMap;
librariesToCrawl[libraryName] = library;