expo-brownfield 55.0.13 → 55.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/android/build.gradle +2 -2
- package/gradle-plugins/publish/src/main/kotlin/expo/modules/plugin/extensions.kt +7 -6
- package/gradle-plugins/publish/src/main/kotlin/expo/modules/plugin/publishing.kt +7 -21
- package/gradle-plugins/publish/src/main/kotlin/expo/modules/plugin/utils.kt +64 -21
- package/package.json +2 -2
- package/plugin/templates/android/ReactNativeFragment.kt +8 -4
- package/plugin/templates/android/ReactNativeHostManager.kt +2 -2
- package/plugin/templates/android/ReactNativeViewFactory.kt +2 -6
- package/plugin/templates/ios/ReactNativeHostManager.swift +1 -1
- package/plugin/templates/ios/ReactNativeView.swift +1 -1
- package/plugin/templates/ios/ReactNativeViewController.swift +1 -1
- package/plugin/templates/patches/ReactNativeHostManager.patch +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 55.0.14 — 2026-03-11
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- Align using custom components between the platforms ([#43633](https://github.com/expo/expo/pull/43633) by [@pmleczek](https://github.com/pmleczek))
|
|
18
|
+
|
|
19
|
+
### 💡 Others
|
|
20
|
+
|
|
21
|
+
- [android] set react native version for all published artifacts ([#43693](https://github.com/expo/expo/pull/43693) by [@pmleczek](https://github.com/pmleczek))
|
|
22
|
+
|
|
13
23
|
## 55.0.13 — 2026-03-05
|
|
14
24
|
|
|
15
25
|
### 🛠 Breaking changes
|
package/android/build.gradle
CHANGED
|
@@ -4,7 +4,7 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'expo.modules.brownfield'
|
|
7
|
-
version = '55.0.
|
|
7
|
+
version = '55.0.14'
|
|
8
8
|
|
|
9
9
|
expoModule {
|
|
10
10
|
canBePublished false
|
|
@@ -14,7 +14,7 @@ android {
|
|
|
14
14
|
namespace "expo.modules.brownfield"
|
|
15
15
|
defaultConfig {
|
|
16
16
|
versionCode 1
|
|
17
|
-
versionName '55.0.
|
|
17
|
+
versionName '55.0.14'
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -179,11 +179,14 @@ internal fun PublishingExtension.createPublication(
|
|
|
179
179
|
from: String,
|
|
180
180
|
project: Project,
|
|
181
181
|
libraryExtension: LibraryExtension,
|
|
182
|
-
rnVersion: String?,
|
|
183
|
-
hermesVersion: String?,
|
|
184
182
|
) {
|
|
183
|
+
val rnVersion = getReactNativeVersion(project)
|
|
184
|
+
val hermesVersion = getHermesVersion(project)
|
|
185
|
+
|
|
186
|
+
val isBrownfieldProject = project.plugins.hasPlugin("expo-brownfield-setup")
|
|
187
|
+
|
|
185
188
|
val _artifactId =
|
|
186
|
-
if (
|
|
189
|
+
if (isBrownfieldProject) {
|
|
187
190
|
project.name
|
|
188
191
|
} else {
|
|
189
192
|
requireNotNull(libraryExtension.namespace)
|
|
@@ -198,9 +201,7 @@ internal fun PublishingExtension.createPublication(
|
|
|
198
201
|
|
|
199
202
|
pom.withXml { xml ->
|
|
200
203
|
removeReactNativeDependencyPom(xml)
|
|
201
|
-
|
|
202
|
-
setReactNativeVersionPom(xml, rnVersion, hermesVersion)
|
|
203
|
-
}
|
|
204
|
+
setReactNativeVersionPom(xml, rnVersion, hermesVersion)
|
|
204
205
|
}
|
|
205
206
|
}
|
|
206
207
|
}
|
|
@@ -30,24 +30,11 @@ internal fun setupPublishing(project: Project) {
|
|
|
30
30
|
return@afterEvaluate
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
val rnVersion =
|
|
34
|
-
if (project.name == configExtension.libraryName.get()) {
|
|
35
|
-
getReactNativeVersion(project)
|
|
36
|
-
} else {
|
|
37
|
-
null
|
|
38
|
-
}
|
|
39
|
-
val hermesVersion =
|
|
40
|
-
if (project.name == configExtension.libraryName.get()) {
|
|
41
|
-
getHermesVersion(project)
|
|
42
|
-
} else {
|
|
43
|
-
null
|
|
44
|
-
}
|
|
45
|
-
|
|
46
33
|
variants.forEach { variant ->
|
|
47
|
-
publicationExtension.createPublication(variant, project, libraryExtension
|
|
34
|
+
publicationExtension.createPublication(variant, project, libraryExtension)
|
|
48
35
|
}
|
|
49
36
|
|
|
50
|
-
createModuleRelatedTasks(project
|
|
37
|
+
createModuleRelatedTasks(project)
|
|
51
38
|
setupRepositories(publicationExtension, project, configExtension)
|
|
52
39
|
}
|
|
53
40
|
}
|
|
@@ -89,13 +76,11 @@ internal fun setupRepositories(
|
|
|
89
76
|
* @param project The project to remove react-native dependency from.
|
|
90
77
|
* @param isBrownfieldProject Whether the project is the brownfield project.
|
|
91
78
|
*/
|
|
92
|
-
internal fun createModuleRelatedTasks(project: Project
|
|
79
|
+
internal fun createModuleRelatedTasks(project: Project) {
|
|
93
80
|
val variants = listOf("brownfieldDebug", "brownfieldRelease", "brownfieldAll")
|
|
94
81
|
variants.forEach { variant ->
|
|
95
82
|
createRemoveReactNativeDependencyModuleTask(project, variant)
|
|
96
|
-
|
|
97
|
-
createSetReactNativeVersionModuleTask(project, variant, rnVersion, hermesVersion)
|
|
98
|
-
}
|
|
83
|
+
createSetReactNativeVersionModuleTask(project, variant)
|
|
99
84
|
}
|
|
100
85
|
}
|
|
101
86
|
|
|
@@ -147,9 +132,10 @@ internal fun createRemoveReactNativeDependencyModuleTask(project: Project, varia
|
|
|
147
132
|
internal fun createSetReactNativeVersionModuleTask(
|
|
148
133
|
project: Project,
|
|
149
134
|
variant: String,
|
|
150
|
-
rnVersion: String,
|
|
151
|
-
hermesVersion: String,
|
|
152
135
|
) {
|
|
136
|
+
val rnVersion = getReactNativeVersion(project)
|
|
137
|
+
val hermesVersion = getHermesVersion(project)
|
|
138
|
+
|
|
153
139
|
val setVersionTask =
|
|
154
140
|
project.tasks.register("setRNDependencyVersionInModuleFile$variant") { task ->
|
|
155
141
|
task.doLast {
|
|
@@ -8,8 +8,12 @@ import java.io.File
|
|
|
8
8
|
import org.gradle.api.Project
|
|
9
9
|
import org.gradle.api.XmlProvider
|
|
10
10
|
import org.gradle.api.publish.PublishingExtension
|
|
11
|
+
import org.gradle.api.plugins.ExtraPropertiesExtension
|
|
11
12
|
import org.json.JSONObject
|
|
12
13
|
|
|
14
|
+
private const val EXPO_BROWNFIELD_RN_VERSION_KEY = "expoBrownfieldRnVersion"
|
|
15
|
+
private const val EXPO_BROWNFIELD_HERMES_VERSION_KEY = "expoBrownfieldHermesVersion"
|
|
16
|
+
|
|
13
17
|
/**
|
|
14
18
|
* Find the app project in the root project.
|
|
15
19
|
*
|
|
@@ -105,13 +109,31 @@ internal fun getConfigExtension(project: Project): ExpoPublishExtension {
|
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
/**
|
|
108
|
-
*
|
|
112
|
+
* Return cached React Native version for the project.
|
|
113
|
+
*
|
|
114
|
+
* @param project The project to get the React Native version for.
|
|
115
|
+
* @return The cached React Native version for the project.
|
|
116
|
+
*/
|
|
117
|
+
internal fun getReactNativeVersion(project: Project): String {
|
|
118
|
+
val rootProject = project.rootProject
|
|
119
|
+
val ext = rootProject.extensions.getByType(ExtraPropertiesExtension::class.java)
|
|
120
|
+
if (!ext.has(EXPO_BROWNFIELD_RN_VERSION_KEY)) {
|
|
121
|
+
val version = getReactNativeVersionInternal(project)
|
|
122
|
+
ext.set(EXPO_BROWNFIELD_RN_VERSION_KEY, version)
|
|
123
|
+
return version
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return ext.get(EXPO_BROWNFIELD_RN_VERSION_KEY) as String
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get the React Native version from the project.
|
|
109
131
|
*
|
|
110
132
|
* @param project The project to get the React Native version for.
|
|
111
133
|
* @return The React Native version for the project.
|
|
112
134
|
* @throws IllegalStateException if the React Native version cannot be inferred.
|
|
113
135
|
*/
|
|
114
|
-
internal fun
|
|
136
|
+
internal fun getReactNativeVersionInternal(project: Project): String {
|
|
115
137
|
return try {
|
|
116
138
|
val process =
|
|
117
139
|
ProcessBuilder("node", "--print", "require('react-native/package.json').version")
|
|
@@ -134,30 +156,48 @@ internal fun getReactNativeVersion(project: Project): String {
|
|
|
134
156
|
}
|
|
135
157
|
}
|
|
136
158
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Return cached Hermes version for the project.
|
|
161
|
+
*
|
|
162
|
+
* @param project The project to get the Hermes version for.
|
|
163
|
+
* @return The cached Hermes version for the project.
|
|
164
|
+
*/
|
|
165
|
+
internal fun getHermesVersion(project: Project): String {
|
|
166
|
+
val rootProject = project.rootProject
|
|
167
|
+
val ext = rootProject.extensions.getByType(ExtraPropertiesExtension::class.java)
|
|
168
|
+
if (!ext.has(EXPO_BROWNFIELD_HERMES_VERSION_KEY)) {
|
|
169
|
+
val version = getHermesVersionInternal(project)
|
|
170
|
+
ext.set(EXPO_BROWNFIELD_HERMES_VERSION_KEY, version)
|
|
171
|
+
return version
|
|
172
|
+
}
|
|
150
173
|
|
|
151
|
-
|
|
152
|
-
|
|
174
|
+
return ext.get(EXPO_BROWNFIELD_HERMES_VERSION_KEY) as String
|
|
175
|
+
}
|
|
153
176
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
177
|
+
/**
|
|
178
|
+
* Get the Hermes version for the project.
|
|
179
|
+
*
|
|
180
|
+
* @param project The project to get the Hermes version for.
|
|
181
|
+
* @return The Hermes version for the project.
|
|
182
|
+
* @throws IllegalStateException if the Hermes version cannot be inferred.
|
|
183
|
+
*/
|
|
184
|
+
internal fun getHermesVersionInternal(project: Project): String {
|
|
185
|
+
val process =
|
|
186
|
+
ProcessBuilder("node", "--print", "require('hermes-compiler/package.json').version")
|
|
187
|
+
.directory(project.rootProject.projectDir)
|
|
188
|
+
.redirectErrorStream(true)
|
|
189
|
+
.start()
|
|
190
|
+
|
|
191
|
+
val version = process.inputStream.bufferedReader().readText().trim()
|
|
192
|
+
process.waitFor()
|
|
157
193
|
|
|
158
|
-
|
|
194
|
+
if (process.exitValue() == 0 && version.isNotEmpty()) {
|
|
195
|
+
return version
|
|
159
196
|
}
|
|
160
197
|
|
|
198
|
+
throw IllegalStateException("Failed to infer Hermes version via Node")
|
|
199
|
+
}
|
|
200
|
+
|
|
161
201
|
/**
|
|
162
202
|
* Get the React Native version from the package.json file.
|
|
163
203
|
*
|
|
@@ -219,6 +259,9 @@ internal fun removeReactNativeDependencyPom(xml: XmlProvider) {
|
|
|
219
259
|
if (dependency.groupId() == "com.facebook.react" && dependency.artifactId() == "react-native") {
|
|
220
260
|
toRemove.add(dependency)
|
|
221
261
|
}
|
|
262
|
+
if (dependency.groupId() == "com.facebook.react" && dependency.artifactId() == "hermes-android") {
|
|
263
|
+
toRemove.add(dependency)
|
|
264
|
+
}
|
|
222
265
|
}
|
|
223
266
|
|
|
224
267
|
val dependenciesNode = xml.dependenciesNode()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-brownfield",
|
|
3
|
-
"version": "55.0.
|
|
3
|
+
"version": "55.0.14",
|
|
4
4
|
"description": "Toolkit and APIs for adding brownfield setup to Expo projects",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"expo": "*",
|
|
68
68
|
"react": "*"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "bcdd2c239f8a92cdf5140e35cde768352630acd6"
|
|
71
71
|
}
|
|
@@ -15,17 +15,18 @@ class ReactNativeFragment : Fragment() {
|
|
|
15
15
|
container: ViewGroup?,
|
|
16
16
|
savedInstanceState: Bundle?,
|
|
17
17
|
): FrameLayout {
|
|
18
|
+
val rootComponent = arguments?.getString("rootComponentName") ?: "main"
|
|
18
19
|
return ReactNativeViewFactory.createFrameLayout(
|
|
19
20
|
requireContext(),
|
|
20
21
|
requireActivity(),
|
|
21
|
-
|
|
22
|
+
rootComponent,
|
|
22
23
|
)
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
companion object {
|
|
26
27
|
private const val TAG = "ReactNativeFragment"
|
|
27
28
|
|
|
28
|
-
fun createFragmentHost(activity: Activity): ViewGroup {
|
|
29
|
+
fun createFragmentHost(activity: Activity, rootComponent: String = "main"): ViewGroup {
|
|
29
30
|
val layout =
|
|
30
31
|
object : FrameLayout(activity) {
|
|
31
32
|
init {
|
|
@@ -33,7 +34,7 @@ class ReactNativeFragment : Fragment() {
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
val fragment = createAndCommit(activity, layout)
|
|
37
|
+
val fragment = createAndCommit(activity, layout, rootComponent)
|
|
37
38
|
|
|
38
39
|
return layout
|
|
39
40
|
}
|
|
@@ -41,10 +42,13 @@ class ReactNativeFragment : Fragment() {
|
|
|
41
42
|
internal fun createAndCommit(
|
|
42
43
|
activity: Activity,
|
|
43
44
|
container: ViewGroup,
|
|
45
|
+
rootComponent: String = "main",
|
|
44
46
|
): ReactNativeFragment {
|
|
45
47
|
val fragmentManager = (activity as FragmentActivity).supportFragmentManager
|
|
46
48
|
|
|
47
|
-
val fragment = ReactNativeFragment()
|
|
49
|
+
val fragment = ReactNativeFragment().apply {
|
|
50
|
+
arguments = Bundle().apply { putString("rootComponentName", rootComponent) }
|
|
51
|
+
}
|
|
48
52
|
|
|
49
53
|
fragmentManager.commit(true) {
|
|
50
54
|
setReorderingAllowed(true)
|
|
@@ -64,9 +64,9 @@ class ReactNativeHostManager {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
fun Activity.showReactNativeFragment() {
|
|
67
|
+
fun Activity.showReactNativeFragment(rootComponent: String = "main") {
|
|
68
68
|
ReactNativeHostManager.shared.initialize(this.application)
|
|
69
|
-
val fragment = ReactNativeFragment.createFragmentHost(this)
|
|
69
|
+
val fragment = ReactNativeFragment.createFragmentHost(this, rootComponent)
|
|
70
70
|
setContentView(fragment)
|
|
71
71
|
setUpNativeBackHandling()
|
|
72
72
|
}
|
|
@@ -10,19 +10,15 @@ import com.facebook.react.ReactDelegate
|
|
|
10
10
|
import com.facebook.react.ReactInstanceManager
|
|
11
11
|
import com.facebook.react.ReactRootView
|
|
12
12
|
|
|
13
|
-
enum class RootComponent(val key: String) {
|
|
14
|
-
Main("main")
|
|
15
|
-
}
|
|
16
|
-
|
|
17
13
|
object ReactNativeViewFactory {
|
|
18
14
|
fun createFrameLayout(
|
|
19
15
|
context: Context,
|
|
20
16
|
activity: FragmentActivity,
|
|
21
|
-
rootComponent:
|
|
17
|
+
rootComponent: String,
|
|
22
18
|
launchOptions: Bundle? = null,
|
|
23
19
|
): FrameLayout {
|
|
24
20
|
val reactHost = ReactNativeHostManager.shared.getReactHost()
|
|
25
|
-
val reactDelegate = ReactDelegate(activity, reactHost!!, rootComponent
|
|
21
|
+
val reactDelegate = ReactDelegate(activity, reactHost!!, rootComponent, launchOptions)
|
|
26
22
|
|
|
27
23
|
activity.lifecycle.addObserver(
|
|
28
24
|
object : DefaultLifecycleObserver {
|
|
@@ -37,7 +37,7 @@ public class ReactNativeHostManager {
|
|
|
37
37
|
* Creates the React Native view using RCTReactNativeFactory
|
|
38
38
|
*/
|
|
39
39
|
public func loadView(
|
|
40
|
-
moduleName: String,
|
|
40
|
+
moduleName: String = "main",
|
|
41
41
|
initialProps: [AnyHashable: Any]?,
|
|
42
42
|
launchOptions: [AnyHashable: Any]?
|
|
43
43
|
) throws -> UIView {
|
|
@@ -36,9 +36,9 @@ index a9fbbe7d70..f7561327e7 100644
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
fun Activity.showReactNativeFragment() {
|
|
39
|
+
fun Activity.showReactNativeFragment(rootComponent: String = "main") {
|
|
40
40
|
ReactNativeHostManager.shared.initialize(this.application)
|
|
41
|
-
- val fragment = ReactNativeFragment.createFragmentHost(this)
|
|
41
|
+
- val fragment = ReactNativeFragment.createFragmentHost(this, rootComponent)
|
|
42
42
|
- setContentView(fragment)
|
|
43
43
|
+
|
|
44
44
|
+ if (BuildConfig.DEBUG) {
|
|
@@ -51,7 +51,7 @@ index a9fbbe7d70..f7561327e7 100644
|
|
|
51
51
|
+ val reactNativeView = ReactNativeViewFactory.createFrameLayout(
|
|
52
52
|
+ this,
|
|
53
53
|
+ this as androidx.fragment.app.FragmentActivity,
|
|
54
|
-
+
|
|
54
|
+
+ rootComponent
|
|
55
55
|
+ )
|
|
56
56
|
+ fragmentHost.addView(reactNativeView, ViewGroup.LayoutParams.MATCH_PARENT)
|
|
57
57
|
+ setContentView(fragmentHost)
|
|
@@ -59,7 +59,7 @@ index a9fbbe7d70..f7561327e7 100644
|
|
|
59
59
|
+ }
|
|
60
60
|
+ } else {
|
|
61
61
|
+ setContentView(
|
|
62
|
-
+ ReactNativeFragment.createFragmentHost(this)
|
|
62
|
+
+ ReactNativeFragment.createFragmentHost(this, rootComponent)
|
|
63
63
|
+ )
|
|
64
64
|
+ }
|
|
65
65
|
+
|