Skip to content

Expose ReactNativeFeatureFlags through react-private-interface - #57940

Open
giaBaoJS wants to merge 1 commit into
react:mainfrom
giaBaoJS:fix-57933-virtualized-lists-exports
Open

Expose ReactNativeFeatureFlags through react-private-interface#57940
giaBaoJS wants to merge 1 commit into
react:mainfrom
giaBaoJS:fix-57933-virtualized-lists-exports

Conversation

@giaBaoJS

@giaBaoJS giaBaoJS commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary:

Fixes #57933.

@react-native/virtualized-lists is published separately and imported ReactNativeFeatureFlags through react-native/src/private/featureflags/ReactNativeFeatureFlags, which is not listed in react-native's "exports". Metro therefore warned and fell back to file-based resolution whenever an app rendered a virtualized list.

Thanks @huntie for the patch and the direction — this PR now applies it instead of the original approach:

  • ReactNativeFeatureFlags is exposed on the existing private package boundary, react-native/react-private-interface (both the runtime getter and the .js.flow re-export);
  • VirtualizedList.js and VirtualizeUtils.js import it from there.

No new src/private/* subpath is exported, and the feature-flag singleton is unchanged.

Per your review, the scripts/monorepo-tests/__tests__/check-packages-test.js and scripts/shared/monorepoUtils.js changes have been dropped — the PR is now just the patch above. Happy to look at enabling @react-native/no-deep-imports on virtualized-lists as a follow-up if that's wanted.

VirtualizeUtils.js is included alongside VirtualizedList.js because it carried the same runtime deep import. The remaining occurrences are out of scope: the four in @react-native/jest-preset are all import type and are erased before resolution, and the one in VirtualizeUtils-test.js is not shipped (virtualized-lists excludes **/__tests__/** from files).

Changelog:

[GENERAL] [FIXED] - Fix the Metro package-exports warning caused by @react-native/virtualized-lists importing an unexported React Native subpath.

Test Plan:

No new test is added. The existing virtualized-lists suites already cover this route, because VirtualizeUtils/VirtualizedList read the flags at runtime through the new boundary.

Counterfactual — dropping only the ReactNativeFeatureFlags getter and its import typeof from react-private-interface.js, keeping the two virtualized-lists imports:

TypeError: Cannot read properties of undefined (reading 'fixVirtualizeListCollapseWindowSize')

      182 |     let lastWillAddMore;
      183 |
    > 184 |     if (ReactNativeFeatureFlags.fixVirtualizeListCollapseWindowSize()) {
          |                                ^

      at computeWindowedRenderLimits (packages/virtualized-lists/Lists/VirtualizeUtils.js:184:32)
      at Object.<anonymous> (packages/virtualized-lists/Lists/__tests__/VirtualizeUtils-test.js:261:47)

Test Suites: 2 failed, 6 passed, 8 total
Tests:       20 failed, 1 skipped, 151 passed, 172 total

Restoring the getter makes it green again.

$ yarn jest packages/virtualized-lists scripts/monorepo-tests packages/react-native/Libraries/ReactPrivate --runInBand
Test Suites: 9 passed, 9 total
Tests:       1 skipped, 176 passed, 177 total
Snapshots:   69 passed, 69 total

$ yarn flow-check
Found 0 errors

$ yarn lint
$ eslint --max-warnings 0 .
Done in 10.23s.

@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 13, 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 13, 2026
@huntie

huntie commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Great spot! We'll need to solve this slightly differently however, I think by adding this API to react-private-interface.

import {ReactNativeFeatureFlags} from 'react-native/react-private-interface';

Patch here: https://gist.github.com/huntie/0523e2dd114dacf904d28211ad6b67be. Can you apply/retitle this PR to match? :)

@giaBaoJS
giaBaoJS force-pushed the fix-57933-virtualized-lists-exports branch from 7cfe4fb to 3c68fe8 Compare August 18, 2026 15:14
@giaBaoJS giaBaoJS changed the title Export the ReactNativeFeatureFlags subpath used by virtualized-lists Route virtualized-lists feature flags through react-private-interface Aug 18, 2026
});
});

// Files matching these patterns are excluded from every published package via

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.

Can we drop or separate out the changes from this file?

At minimum, we've reimplemented ESLint and should instead reuse it — should be a case of enabling the react-native/no-deep-imports rule directly on the virtualized-lists codebase. (But also, we're probably fine without adding new checks.)

@giaBaoJS
giaBaoJS force-pushed the fix-57933-virtualized-lists-exports branch from 3c68fe8 to 7deb545 Compare August 22, 2026 08:47
@giaBaoJS giaBaoJS changed the title Route virtualized-lists feature flags through react-private-interface Expose ReactNativeFeatureFlags through react-private-interface Aug 22, 2026
@giaBaoJS

Copy link
Copy Markdown
Contributor Author

Thanks for the patch @huntie — applied and retitled. ReactNativeFeatureFlags now comes from react-native/react-private-interface, and I've dropped the check-packages-test.js/monorepoUtils.js changes entirely as you suggested. Happy to do the @react-native/no-deep-imports enablement on virtualized-lists as a separate PR if you'd like it.

I also routed VirtualizeUtils.js through the same boundary since it had the identical deep import. yarn flow-check, yarn lint and the virtualized-lists suites are green.

@huntie huntie 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.

Thanks for the edits :)

cursor Bot pushed a commit to huntie/react-native that referenced this pull request Aug 22, 2026
Hardcode support for the react-native/react-private-interface package
export ("types": null) so build-types does not expand src/private/*
dependencies into types_generated.

This unblocks exposing ReactNativeFeatureFlags through
react-private-interface (react#57940).

- Skip the import in simpleResolve
- Do not follow src/private deps from react-private-interface.js.flow
- Strip ./private/* re-exports from the generated .d.ts
- Give api-extractor a minimal temp exports map for this subpath

Co-authored-by: Alex Hunt <huntie@users.noreply.github.com>
cursor Bot pushed a commit to huntie/react-native that referenced this pull request Aug 22, 2026
Minimum fix for react#57940: when
react-private-interface gains a ReactNativeFeatureFlags export,
do not translate src/private/featureflags/* into types_generated.

- Skip react-native/react-private-interface in simpleResolve
- Block feature-flags deps from react-private-interface.js.flow
- Strip the feature-flags re-export from the generated .d.ts

Co-authored-by: Alex Hunt <huntie@users.noreply.github.com>
@huntie

huntie commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

@giaBaoJS The failing build_js_types job is likely due to @microsoft/api-extractor not reading package.json "exports" — I've drafted #58075 to fix this, which will need to land first (once finished, eta Monday). Sorry for the blocker!

@giaBaoJS

Copy link
Copy Markdown
Contributor Author

No problem at all — thanks for digging into the root cause and drafting #58075 rather than asking me to work around it. I'll leave this as-is and rebase once that lands; ping me if you want the @react-native/no-deep-imports enablement for virtualized-lists as a follow-up.

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. 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.

[0.87.0] VirtualizedList triggers Metro package-exports warning

2 participants