fix(codegen): skip node_modules and symlinks when crawling for components - #58518
Closed
gabrieldonadel wants to merge 1 commit into
Closed
gabrieldonadel wants to merge 1 commit into
gabrieldonadel wants to merge 1 commit into
Conversation
|
@vzaidman has imported this pull request. If you are a Meta employee, you can view this in D120122552. |
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
findFilesWithExtensionwalks a library's directory looking for.mmfiles that declare a Fabric component. The walk descends into every subdirectory,node_modulesincluded, resolves symlinks throughstatSync, and keeps no visited set.This got broken after #57790 because
parseiOSAnnotationsnow enters every library that declares acodegenConfigwithout anioskey into its map with an emptycomponentsobject, so nothing removes it fromlibrariesToCrawl. Previously such libraries were filtered before crawling.An app that declares
codegenConfigwith"type": "all"and noioskey now gets treated as a component library, so the walk covers the entire project.What we notice in the expo repo is that under pnpm, the traversal never terminates. Workspace packages link into each other's
node_modulesand 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 agenerate-codegen-artifacts.jschild sits at 100% CPU.Under npm and yarn, the walk completes but with the wrong result. In those cases,
node_modulesholds real directories, but the walk covers the whole dependency tree. Crawling one app of roughly 1100 packages turned up 382.mmfiles, 43 of which declare a component, among them React core views such asRCTImageComponentViewandRCTScrollViewComponentViewfromreact-native-macos. Each one is written into the app's entry inRCTThirdPartyComponentsProvider.mm. The existing/react-native/path filter does not exclude them, since it requires a trailing separator andreact-native-macoshas none.Changelog:
[IOS] [FIXED] - Codegen no longer crawls
node_modulesor follows symlinks when discovering componentsTest Plan:
Two cases added to
packages/react-native/scripts/codegen/__tests__/generate-artifacts-executor-test.js. The three existingfindFilesWithExtensionmocks move fromstatSynctolstatSync.The symlink case builds a link pointing back at its own parent, so the pre-fix walk never terminates.
Negative control: with the
generateRCTThirdPartyComponents.jschange 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 aniosconfig.Measured by crawling the app directory of two real projects:
apps/bare-expo, pnpm