Skip to content

Fix iOS Codegen fallback for libraries without an iOS config - #57790

Closed
RealBhupesh wants to merge 1 commit into
react:mainfrom
RealBhupesh:agent/55308-codegen-ios-components
Closed

RealBhupesh wants to merge 1 commit into
react:mainfrom
RealBhupesh:agent/55308-codegen-ios-components

Conversation

@RealBhupesh

@RealBhupesh RealBhupesh commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep component libraries in the iOS third-party component crawl even when their Codegen config has no ios block.
  • Add a regression test covering a component library without iOS configuration.

Changelog:

[iOS] [FIXED] - iOS Codegen now discovers third-party component libraries without an iOS configuration.

Fixes #55308

Test plan

  • Targeted Jest test passes:
    yarn jest packages/react-native/scripts/codegen/__tests__/generate-artifacts-executor-test.js --runInBand --testNamePattern="crawls component libraries without an iOS config"
  • The full test file executes all 44 tests successfully, but Jest exits from an existing Node 26 cleanup-hook incompatibility with fs.rmdirSync(..., {recursive: true}).

@meta-cla

meta-cla Bot commented Aug 2, 2026

Copy link
Copy Markdown

Hi @RealBhupesh!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@RealBhupesh

Copy link
Copy Markdown
Contributor Author

Hi React Native maintainers, I’ve completed the Meta CLA for this contribution. This PR is ready for review when convenient. It includes a regression test covering component libraries without an iOS Codegen config. Thank you!

@RealBhupesh

Copy link
Copy Markdown
Contributor Author

signed it

@RealBhupesh
RealBhupesh marked this pull request as ready for review August 2, 2026 07:31
@meta-cla

meta-cla Bot commented Aug 2, 2026

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 2, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Aug 2, 2026
@meta-codesync

meta-codesync Bot commented Aug 2, 2026

Copy link
Copy Markdown

@fabriziocucci has imported this pull request. If you are a Meta employee, you can view this in D114523918.

@cortinico cortinico left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review automatically exported from Phabricator review in Meta.

@meta-codesync meta-codesync Bot closed this in 917d97e Aug 3, 2026
@meta-codesync meta-codesync Bot added the Merged This PR has been merged. label Aug 3, 2026
@meta-codesync

meta-codesync Bot commented Aug 3, 2026

Copy link
Copy Markdown

@fabriziocucci merged this pull request in 917d97e.

meta-codesync Bot pushed a commit that referenced this pull request Sep 15, 2026
…ents (#58518)

Summary:
`findFilesWithExtension` walks a library's directory looking for `.mm` files that declare a Fabric component. The walk descends into every subdirectory, `node_modules` included, resolves symlinks through `statSync`, and keeps no visited set.

This got broken after #57790 because `parseiOSAnnotations` now enters every library that declares a `codegenConfig` without an `ios` key into its map with an empty `components` object, so nothing removes it from `librariesToCrawl`. Previously such libraries were filtered before crawling.

An app that declares `codegenConfig` with `"type": "all"` and no `ios` key now gets treated as a component library, so the walk covers the entire project.

What we notice in the [expo repo](expo/expo#50134) is that under pnpm, the traversal never terminates. Workspace packages link into each other's `node_modules` and form cycles. Because symlinks are followed, the walk only stops once paths hit the 1023 byte limit. CocoaPods progress stops right after the "Using React Native Core and React Native Dependencies prebuilt versions" line while a `generate-codegen-artifacts.js` child sits at 100% CPU.

Under npm and yarn, the walk completes but with the wrong result. In those cases, `node_modules` holds real directories, but the walk covers the whole dependency tree. Crawling one app of roughly 1100 packages turned up 382 `.mm` files, 43 of which declare a component, among them React core views such as `RCTImageComponentView` and `RCTScrollViewComponentView` from `react-native-macos`. Each one is written into the app's entry in `RCTThirdPartyComponentsProvider.mm`. The existing `/react-native/` path filter does not exclude them, since it requires a trailing separator and `react-native-macos` has none.

## Changelog:

[IOS] [FIXED] - Codegen no longer crawls `node_modules` or follows symlinks when discovering components

Pull Request resolved: #58518

Test Plan:
Two cases added to `packages/react-native/scripts/codegen/__tests__/generate-artifacts-executor-test.js`. The three existing `findFilesWithExtension` mocks move from `statSync` to `lstatSync`.

The symlink case builds a link pointing back at its own parent, so the pre-fix walk never terminates.

**Negative control:** with the `generateRCTThirdPartyComponents.js` change reverted and the tests left in place, both new cases fail. All 24 existing snapshots pass unchanged, so the change is additive for projects that already declare an `ios` config.

Measured by crawling the app directory of two real projects:

| Project | Before | After |
| --- | --- | --- |
| `apps/bare-expo`, pnpm | 116,800 reads in 30s, still running | 34 files, 1.1s |
| yarn app, ~1100 packages | 382 files, 5.8s | 8 files, 0.3s |

Reviewed By: fabriziocucci

Differential Revision: D120122552

Pulled By: vzaidman

fbshipit-source-id: 233b8dc338b92372a34a0855f12a549e52513200
fabriziocucci pushed a commit that referenced this pull request Sep 15, 2026
…ents (#58518)

Summary:
`findFilesWithExtension` walks a library's directory looking for `.mm` files that declare a Fabric component. The walk descends into every subdirectory, `node_modules` included, resolves symlinks through `statSync`, and keeps no visited set.

This got broken after #57790 because `parseiOSAnnotations` now enters every library that declares a `codegenConfig` without an `ios` key into its map with an empty `components` object, so nothing removes it from `librariesToCrawl`. Previously such libraries were filtered before crawling.

An app that declares `codegenConfig` with `"type": "all"` and no `ios` key now gets treated as a component library, so the walk covers the entire project.

What we notice in the [expo repo](expo/expo#50134) is that under pnpm, the traversal never terminates. Workspace packages link into each other's `node_modules` and form cycles. Because symlinks are followed, the walk only stops once paths hit the 1023 byte limit. CocoaPods progress stops right after the "Using React Native Core and React Native Dependencies prebuilt versions" line while a `generate-codegen-artifacts.js` child sits at 100% CPU.

Under npm and yarn, the walk completes but with the wrong result. In those cases, `node_modules` holds real directories, but the walk covers the whole dependency tree. Crawling one app of roughly 1100 packages turned up 382 `.mm` files, 43 of which declare a component, among them React core views such as `RCTImageComponentView` and `RCTScrollViewComponentView` from `react-native-macos`. Each one is written into the app's entry in `RCTThirdPartyComponentsProvider.mm`. The existing `/react-native/` path filter does not exclude them, since it requires a trailing separator and `react-native-macos` has none.

## Changelog:

[IOS] [FIXED] - Codegen no longer crawls `node_modules` or follows symlinks when discovering components

Pull Request resolved: #58518

Test Plan:
Two cases added to `packages/react-native/scripts/codegen/__tests__/generate-artifacts-executor-test.js`. The three existing `findFilesWithExtension` mocks move from `statSync` to `lstatSync`.

The symlink case builds a link pointing back at its own parent, so the pre-fix walk never terminates.

**Negative control:** with the `generateRCTThirdPartyComponents.js` change reverted and the tests left in place, both new cases fail. All 24 existing snapshots pass unchanged, so the change is additive for projects that already declare an `ios` config.

Measured by crawling the app directory of two real projects:

| Project | Before | After |
| --- | --- | --- |
| `apps/bare-expo`, pnpm | 116,800 reads in 30s, still running | 34 files, 1.1s |
| yarn app, ~1100 packages | 382 files, 5.8s | 8 files, 0.3s |

Reviewed By: fabriziocucci

Differential Revision: D120122552

Pulled By: vzaidman

fbshipit-source-id: 233b8dc338b92372a34a0855f12a549e52513200
(cherry picked from commit 39751d8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Codegen] Third-party components missing when library lacks ios config

2 participants