Skip to content

Codegen not respecting ignored linked dependencies in react-native.config.js  #47550

Closed as not planned

Description

@mrbrentkelly

Description

When a third party react-native dependency exists in an app's package.json but has been disabled from auto-linking in the react-native.config.js file, react-native-codegen still generates native Objective-C code for the unlinked dependency, leading to build failures.

Steps to reproduce

Create a new RN project and add a third party library that contains native code (e.g. react-native-screens)

npx @react-native-community/cli@latest init VerifyCodegen --skip-install --version 0.76.1
cd VerifyCodegen
yarn install
yarn add react-native-screens

Create a react-native.config.js file and disable react-native-screens from auto-linking on iOS...

module.exports = {
  dependencies: {
    'react-native-screens': {
      platforms: {
        ios: null,
        android: null,
      },
    },
  },
};

Run pod install and try and build/run the iOS app

npx pod-install
yarn ios

Build will fail because the generated RCTThirdPartyFabricComponentsProvider files reference things that are linked in the project (e.g. _RNSScreenCls).

React Native Version

0.76.1

Affected Platforms

Runtime - iOS

Areas

Codegen

Output of npx react-native info

info Fetching system and libraries information...
System:
  OS: macOS 14.6.1
  CPU: (10) arm64 Apple M1 Max
  Memory: 190.97 MB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.18.0
    path: ~/.nvm/versions/node/v18.18.0/bin/node
  Yarn:
    version: 1.22.19
    path: ~/.nvm/versions/node/v18.15.0/bin/yarn
  npm:
    version: 9.8.1
    path: ~/.nvm/versions/node/v18.18.0/bin/npm
  Watchman:
    version: 2024.04.01.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /Users/brent.kelly/.rvm/gems/ruby-2.7.5/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.5
      - iOS 17.5
      - macOS 14.5
      - tvOS 17.5
      - visionOS 1.2
      - watchOS 10.5
  Android SDK: Not Found
IDEs:
  Android Studio: 2024.2 AI-242.23339.11.2421.12550806
  Xcode:
    version: 15.4/15F31d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.13
    path: /usr/bin/javac
  Ruby:
    version: 2.7.5
    path: /Users/brent.kelly/.rvm/rubies/ruby-2.7.5/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.0
    wanted: 15.0.0
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.76.1
    wanted: 0.76.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true


### Stacktrace or Logs

```text
Undefined symbols for architecture arm64:
  "_RNSFullWindowOverlayCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSModalScreenCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSScreenCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSScreenContainerCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSScreenContentWrapperCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSScreenFooterCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSScreenNavigationContainerCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSScreenStackCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSScreenStackHeaderConfigCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSScreenStackHeaderSubviewCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
  "_RNSSearchBarCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Reproducer

https://github.com/mrbrentkelly/rn-codegen-linking-bug

Screenshots and Videos

No response

Activity

  1. cipolleschi commented on Nov 11, 2024

    @cipolleschi
    Contributor

    Thanks for reporting the issue, @mrbrentkelly.

    I'll try to work on this asap. 0.76.2 is planned for tomorrow, so it's unlikely that the fix would be out. I'll make my best to have it out for 0.76.3.

    Meanwhile, you should be able to unblock yourself by manually removing the lines from Xcode.

  2. cipolleschi commented on Nov 17, 2024

    @cipolleschi
    Contributor

    Hi @mrbrentkelly, I was thinking about this issue more deeply, and I am not sure whether disabling Codegen if the library is excluded from autolinking is the right thing.

    Let me try to explain:

    • Autolinking is a step that crawl your node modules and make sure that the app depends on a specific library (linking the library)
    • If you exclude a library from autolinking, your app cannot access any of the code shipped. You can however link it manually by adding the pod <library name> line in your Podfile, if you need some specific customization (use_modular_header for example)
    • In both case, if you are using the New Architecture, you'll need the code generated by Codegen. Without that code, the library cannot build.
    • If we proceed with the fix you suggested (skipping codegen if the package is excluded from autolinking) we are going to break the use case of manual linking into the app
    • If the library don't need to run codegen, they can explicitly state it in their package.json setting the property codegenConfig.includesGeneratedCode to true, these are some example libraries doing that.

    A couple of clarification questions:

    • If you are not linking the library, why can't you just uninstall the dependency instead?
    • Could you explain better your use case?
  3. mrbrentkelly commented on Nov 17, 2024

    @mrbrentkelly
    ContributorAuthor

    If you are not linking the library, why can't you just uninstall the dependency instead?

    Uninstalling isn't always an option... Say for example an app wants to use a particular RN library on Android and not iOS (or vice versa)... typically the approach would then be to disable the library for the intended platform in the react-native.config.js so that it doesn't get auto-linked. In my opinion the codegen should not happen if a library hasn't been linked (to avoid compilation errors).

    Another example would be you're using a RN library like Sentry where linking the native side is optional depending on which APIs you want to use.

    Or perhaps you're in a monorepo of multiple apps and node_modules contains all dependencies for all apps.

    Another example would be an RN library that you link for debug builds but not release builds (perhaps via an environment var in utilised in the react-native.config.js).

    If we proceed with the fix you suggested (skipping codegen if the package is excluded from autolinking) we are going to break the use case of manual linking into the app

    It sounds like the codegen for iOS should be looking at linked pods (after RN auto-linking), instead of relying on what's contained in node_modules. That would then work for manually linked libs and auto-linked ones...

    node_modules aren't the single source of truth for a React Native app, and as I've noted above there's multiple variables to consider. So I think we are going to need better control over when the codegen happens?

  4. cipolleschi commented on Nov 19, 2024

    @cipolleschi
    Contributor

    So I think we are going to need better control over when the codegen happens?

    Yes, I believe that codegen and autolinking should be decoupled.

    For completeness' sake, autolinking works by asking for some configuration to get a list of libraries that needs to be linked. For projects with the CLI, thats react-native info command. Expo provides their own commands with the same format.

    Codegen, instead, looks at both libraries in your dependencies, peerDependencies, devDependencies and into the react-native.config.js file to decide what to generate and what not.

    Also, starting from 0.77 we will not generate the xxxCls anymore, so the problem will be probably fix itself.

    Given that autolinking is using that file to decide what to link in the app, we can patch 0.76 to remove the library from the list of libraries if the react-native.config.js exclude the library from linking.

  5. react-native-bot commented on May 19, 2025

    @react-native-bot
    Collaborator

    This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

  6. added
    StaleThere has been a lack of activity on this issue and it may be closed soon.
    on May 19, 2025
  7. react-native-bot commented on May 26, 2025

    @react-native-bot
    Collaborator

    This issue was closed because it has been stalled for 7 days with no activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Resolution: PR SubmittedA pull request with a fix has been provided.StaleThere has been a lack of activity on this issue and it may be closed soon.Type: New ArchitectureIssues and PRs related to new architecture (Fabric/Turbo Modules)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions