Cli: Ability to skip autolinking for dependency for specific ios target

Created on 27 May 2020  路  7Comments  路  Source: react-native-community/cli

Describe the Feature

We use the same codebase for different apps in appstore, so we have different targets in pod file. For some of the apps we need to remove specific dependencies (for instance, we can't use firebase admob library in target that is aiming for kids due to appstore policy).

Currently in react-native.config.js I can disable autolinking only for specific platfrom, but it would be good to be able to skip dependency for specific pod targets as well

Possible Implementations

I can imagine that it could be a specific property in react-native.config.jsin dependency configuration where I can putt targets that should be excluded from autolinking

module.exports = {
  assets: ['res/fonts'],
  dependencies: {
    'react-native-code-push': {
      platforms: {
        ios: {
          excludeFor: ['Target1'],
        },
        android: null,
        web: null,
      }
    }
  }
}

I think in ../node_modules/@react-native-community/cli-platform-ios/native_modules it could be possible to get this property for dependency and skip installation if current target is listed

feature request

Most helpful comment

I ended up patching native_modules.rb to take packages_to_skip in use_native_modules!, so I can do this in my Podfile:

abstract_target 'Main' do
  # common dependencies, around 20
  use_native_modules!(packages_to_skip: ['RNFBAdMob'])

  target "InAppAddAllowed" do
    pod 'RNFBAdMob', :path => '../node_modules/@react-native-firebase/admob'
  end

  target "AppWithoutAdd" do
  end
end

here is the content of my patches/@react-native-community+cli-platform-ios+4.13.0.patch file

```diff
diff --git a/node_modules/@react-native-community/cli-platform-ios/native_modules.rb b/node_modules/@react-native-community/cli-platform-ios/native_modules.rb
index 2254158..397ca0a 100644
--- a/node_modules/@react-native-community/cli-platform-ios/native_modules.rb
+++ b/node_modules/@react-native-community/cli-platform-ios/native_modules.rb
@@ -12,7 +12,7 @@
require 'pathname'
require 'cocoapods'

-def use_native_modules!(config = nil)
+def use_native_modules!(config = nil, packages_to_skip: [])
if (config.is_a? String)
Pod::UI.warn("Passing custom root to use_native_modules! is deprecated.",
[
@@ -44,6 +44,10 @@ def use_native_modules!(config = nil)

packages.each do |package_name, package|
next unless package_config = package["platforms"]["ios"]

  • if skipped_pod = packages_to_skip.find { |pod_name| package["platforms"]["ios"]["podspecPath"].include? "#{pod_name}.podspec" }
  • Pod::UI.notice "Skipping pod: #{skipped_pod}"
  • next
  • end
 podspec_path = package_config["podspecPath"]

```

All 7 comments

cc @grabbou @alloy

In my opinion, which is very strong when it comes to options/configuration 馃槄, auto-linking should be as simple as it can be _without_ the need for configuration. Any further customisation should be done entirely through normal CocoaPods [or Gradle] means.

The reason I feel this way is that I think it ends up hurting the user if we try to abstract away things that are already well covered by the amount of docs/issues/stackoverflow/blogs that exist for the underlying tool鈥搃n this case CocoaPods. Instead we would have to write and maintain new rn-cli specific documentation, meaning maintainers need to do more work and end-users have less chance of finding the right solution; which is a lose-lose situation.

In short, I think auto-linking should:

  1. not ever try include dependencies on platforms the pod doesn鈥檛 support (added in https://github.com/react-native-community/cli/pull/1126)
  2. auto-linking should skip pods that were already explicitly activated by the user _prior_ to invoking auto-linking, thus allowing the user to provide custom configuration for that pod (already works this way)
  3. auto-linking can be invoked from within specific targets, thus not affecting other targets (should already work this way)

Thus, I don鈥檛 think we should add this feature, furthermore I believe we should remove the ability to exclude pods for specific platforms. It would also be good to outline the above design in the auto-linking doc.

@anta-semenov So coming back to your original issue, I think your best recourse would be to follow the strategy outlined in point 3 above; which is to:

  • invoke use_native_modules! in the targets where you want auto-linking to do its work
  • manually define the pods in those targets where you want total control over them.

If this doesn't work, then please let us know! 馃檹

Not sure if this will work well with my user case.
My use case is following (pod file):

abstract_target 'Main' do
  <React native pods>
  <Common dependencies, around 20>

  target InAppAddAllowed do
    pod pod 'RNFBAdMob', :path => '../node_modules/@react-native-firebase/admob'
  end
  target AppWithoutAdd
end

I would like to use autolinking to install common dependencies, but according to my understanding if I add use_native_modules! into Main target level it will also add RNFBAdMob, because it will find it in node_modules (or maybe I'm wrong in my understanding how the whole thing work). I can use use_native_modules! only inside InAppAddAllowed to add one dependency which obviously doesn't have any sense.
And it's not very easy to remove dependency from target with cocoapods (at least there is no docs around this), so I can't use cocopods hooks for that

But I got your point. Will patch this locally.

I have one question in how merging of react-native.config.js works.
Is there any merging at all, meaning if I define dependencies in my local react-native.config.js and there is already some config in package, will it merge configs or will it select only one of them?
And if it merges, will it merge only known properties or all of them?

And in my proposal, I didn't mean that there should be the need for configuration, but ability for configuration

Can you check what this does?

abstract_target 'Main' do
  <Common dependencies, around 20>

  target "InAppAddAllowed" do
    pod 'RNFBAdMob', :path => '../node_modules/@react-native-firebase/admob'
    use_native_modules!
  end

  target "AppWithoutAdd" do
    use_native_modules!
  end
end

If this does not already omit RNFBAdMob from the AppWithoutAdd target, then we should update it to do so, as that鈥檚 the way I would prefer configuration to be done.

And in my proposal, I didn't mean that there should be the need for configuration, but ability for configuration

To be clear, my first comment wasn鈥檛 necessarily addressed at you, more so to the other maintainers of this tool and for posterity.

I think we are on the same page, we want to be able to control these things in as easy a way as possible.

Will try today or on monday. But according to code in @react-native-community/cli-platform-ios/native_modules.rb it checks dependencies only for current target, so inside AppWithoutAdd it most likely won't check dependencies of InAppAddAllowed (or maybe I completely don't understand how cocoapods works)

I ended up patching native_modules.rb to take packages_to_skip in use_native_modules!, so I can do this in my Podfile:

abstract_target 'Main' do
  # common dependencies, around 20
  use_native_modules!(packages_to_skip: ['RNFBAdMob'])

  target "InAppAddAllowed" do
    pod 'RNFBAdMob', :path => '../node_modules/@react-native-firebase/admob'
  end

  target "AppWithoutAdd" do
  end
end

here is the content of my patches/@react-native-community+cli-platform-ios+4.13.0.patch file

```diff
diff --git a/node_modules/@react-native-community/cli-platform-ios/native_modules.rb b/node_modules/@react-native-community/cli-platform-ios/native_modules.rb
index 2254158..397ca0a 100644
--- a/node_modules/@react-native-community/cli-platform-ios/native_modules.rb
+++ b/node_modules/@react-native-community/cli-platform-ios/native_modules.rb
@@ -12,7 +12,7 @@
require 'pathname'
require 'cocoapods'

-def use_native_modules!(config = nil)
+def use_native_modules!(config = nil, packages_to_skip: [])
if (config.is_a? String)
Pod::UI.warn("Passing custom root to use_native_modules! is deprecated.",
[
@@ -44,6 +44,10 @@ def use_native_modules!(config = nil)

packages.each do |package_name, package|
next unless package_config = package["platforms"]["ios"]

  • if skipped_pod = packages_to_skip.find { |pod_name| package["platforms"]["ios"]["podspecPath"].include? "#{pod_name}.podspec" }
  • Pod::UI.notice "Skipping pod: #{skipped_pod}"
  • next
  • end
 podspec_path = package_config["podspecPath"]

```

Was this page helpful?
0 / 5 - 0 ratings