@@ -306,7 +306,126 @@ tasks.named("generateMetadataFileForMavenAarPublication") {
306306}
307307```
308308
309- ## 7. Set up RNEF for AAR generation
309+ ## 7. Extra steps for Expo CLI and Expo Modules
310+
311+ 1 . Make ` ReactNativeHostManager ` aware with expo modules:
312+ ``` diff
313+ @@ -11,6 +11,8 @@ import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
314+ import com.facebook.react.defaults.DefaultReactNativeHost
315+ import com.facebook.react.soloader.OpenSourceMergedSoMapping
316+ import com.facebook.soloader.SoLoader
317+ + import expo.modules.ApplicationLifecycleDispatcher
318+ + import expo.modules.ReactNativeHostWrapper
319+
320+ class ReactNativeHostManager {
321+ companion object {
322+ @@ -37,21 +39,23 @@ class ReactNativeHostManager {
323+ // If you opted-in for the New Architecture, we load the native entry point for this app.
324+ load()
325+ }
326+ + ApplicationLifecycleDispatcher.onApplicationCreate(application)
327+
328+
329+ /**
330+ * If your project is using ExpoModules, you can use `index` instead.
331+ *
332+ * Below module name is used when your project is using Expo CLI
333+ */
334+ + val jsMainModuleName = ".expo/.virtual-metro-entry"
335+
336+ val reactApp = object : ReactApplication {
337+ - override val reactNativeHost: ReactNativeHost = object : DefaultReactNativeHost(application) {
338+ + override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(application,
339+ + object : DefaultReactNativeHost(application) {
340+ override fun getPackages(): MutableList<ReactPackage> {
341+ return PackageList(application).packages
342+ }
343+
344+ - override fun getJSMainModuleName(): String = "index"
345+ + override fun getJSMainModuleName(): String = jsMainModuleName
346+ override fun getBundleAssetName(): String = "index.android.bundle"
347+
348+ override fun getUseDeveloperSupport() = BuildConfig.DEBUG
349+
350+ override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
351+ override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
352+ - }
353+ + })
354+
355+ override val reactHost: ReactHost
356+ get() = getDefaultReactHost(application, reactNativeHost)
357+ ```
358+
359+ 2 . Update your ` rnbrownfield/build.gradle ` :
360+
361+ ``` diff
362+
363+ + reactBrownfield {
364+ /**
365+ * This will be available from `com.callstack.react.brownfield` version > 3.0.0
366+ * It takes care of linking expo dependencies like expo-image with your AAR module.
367+ *
368+ * Default value is false.
369+ */
370+ + isExpo = true
371+ + }
372+
373+ react {
374+ autolinkLibrariesWithApp()
375+ }
376+
377+ @@ -76,6 +76,18 @@ dependencies {
378+ androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
379+ }
380+
381+ /**
382+ * This function is used in the places where we:
383+ *
384+ * Remove the `expo` dependency from the `module.json` and `pom.xml file. Otherwise, the
385+ * gradle will try to resolve this and will throw an error, since this dependency won't
386+ * be available from a remote repository.
387+ *
388+ * Your AAR does not need this dependency.
389+ */
390+ + fun isExpoArtifact(group: String, artifactId: String): Boolean {
391+ + return group == "host.exp.exponent" && artifactId == "expo"
392+ + }
393+
394+ publishing {
395+ publications {
396+ @@ -97,7 +109,12 @@ publishing {
397+ val dependenciesNode = (asNode().get("dependencies") as groovy.util.NodeList).first() as groovy.util.Node
398+ dependenciesNode.children()
399+ .filterIsInstance<groovy.util.Node>()
400+ - .filter { (it.get("groupId") as groovy.util.NodeList).text() == rootProject.name }
401+ + .filter {
402+ + val artifactId = (it["artifactId"] as groovy.util.NodeList).text()
403+ + val group = (it["groupId"] as groovy.util.NodeList).text()
404+ +
405+ + (isExpoArtifact(group, artifactId) || group == rootProject.name)
406+ + }
407+ .forEach { dependenciesNode.remove(it) }
408+ }
409+ }
410+ @@ -121,7 +138,12 @@ tasks.register("removeDependenciesFromModuleFile") {
411+ file("$moduleBuildDir/publications/mavenAar/module.json").run {
412+ val json = inputStream().use { JsonSlurper().parse(it) as Map<String, Any> }
413+ (json["variants"] as? List<MutableMap<String, Any>>)?.forEach { variant ->
414+ - (variant["dependencies"] as? MutableList<Map<String, Any>>)?.removeAll { it["group"] == rootProject.name }
415+ + (variant["dependencies"] as? MutableList<Map<String, Any>>)?.removeAll {
416+ + val module = it["module"] as String
417+ + val group = it["group"] as String
418+ +
419+ + (isExpoArtifact(group, module) || group == rootProject.name)
420+ + }
421+ }
422+ writer().use { it.write(JsonOutput.prettyPrint(JsonOutput.toJson(json))) }
423+ }
424+ ```
425+
426+ That is all you need to change. Step 8.i is not required with Expo, you can skip it. See Step 8.ii to generate AAR.
427+
428+ ## 8.i Set up RNEF for AAR generation (not required for Expo)
310429
3114301 . Add ` @rnef/plugin-brownfield-android ` to your dependencies
3124311 . Update your ` rnef.config.mjs ` :
@@ -331,7 +450,12 @@ tasks.named("generateMetadataFileForMavenAarPublication") {
331450 rnef publish-local:aar --module-name rnbrownfield
332451 ```
333452
334- ## 8. Add the AAR to Your Android App
453+ ## 8.ii Generate AAR when using Expo
454+
455+ Here you can see how to generate AAR. The link uses a script which first builds the AAR and then publish to to ` mavenLocal ` .
456+ [ see here] ( https://github.com/callstackincubator/modern-brownfield-ref/blob/b23641f3ff7c278743d35013841d5494905ba190/package.json#L14 )
457+
458+ ## 9. Add the AAR to Your Android App
335459
336460> Note: You'll need an existing Android app or create a new one in Android Studio.
337461
@@ -365,7 +489,7 @@ tasks.named("generateMetadataFileForMavenAarPublication") {
365489 }
366490 ```
367491
368- ## 9 . Show the React Native UI
492+ ## 10 . Show the React Native UI
369493
370494Create a new ` RNAppFragment.kt ` :
371495
0 commit comments