feat: Monorepo support (#704)

* fix: Find node_modules dynamically

* Update build.gradle

* Update build.gradle

* fix: Remove `findNodeModulePath` function
This commit is contained in:
Marc Rousavy 2022-01-03 12:23:19 +01:00 committed by GitHub
parent fc4ed60f7c
commit d2dbcdd09d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,11 +2,26 @@ import groovy.json.JsonSlurper
import org.apache.tools.ant.filters.ReplaceTokens
import java.nio.file.Paths
def nodeModulesPath = "$projectDir/../node_modules"
def reactNative = new File("$nodeModulesPath/react-native")
static def findNodeModules(baseDir) {
def basePath = baseDir.toPath().normalize()
// Node's module resolution algorithm searches up to the root directory,
// after which the base path will be null
while (basePath) {
def candidatePath = Paths.get(basePath.toString(), "node_modules")
if (candidatePath.toFile().exists()) {
return candidatePath.toString()
}
basePath = basePath.getParent()
}
throw new GradleException("VisionCamera: Failed to find node_modules/ path!")
}
def nodeModules = findNodeModules(projectDir)
logger.warn("VisionCamera: node_modules/ found at: ${nodeModules}")
def reactNative = new File("$nodeModules/react-native")
def reactProperties = new Properties()
file("$nodeModulesPath/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger()
def FOR_HERMES = System.getenv("FOR_HERMES") == "True"
@ -16,41 +31,6 @@ rootProject.getSubprojects().forEach({project ->
}
})
/**
* Finds the path of the installed npm package with the given name using Node's
* module resolution algorithm, which searches "node_modules" directories up to
* the file system root. This handles various cases, including:
*
* - Working in the open-source RN repo:
* Gradle: /path/to/react-native/ReactAndroid
* Node module: /path/to/react-native/node_modules/[package]
*
* - Installing RN as a dependency of an app and searching for hoisted
* dependencies:
* Gradle: /path/to/app/node_modules/react-native/ReactAndroid
* Node module: /path/to/app/node_modules/[package]
*
* - Working in a larger repo (e.g., Facebook) that contains RN:
* Gradle: /path/to/repo/path/to/react-native/ReactAndroid
* Node module: /path/to/repo/node_modules/[package]
*
* The search begins at the given base directory (a File object). The returned
* path is a string.
*/
static def findNodeModulePath(baseDir, packageName) {
def basePath = baseDir.toPath().normalize()
// Node's module resolution algorithm searches up to the root directory,
// after which the base path will be null
while (basePath) {
def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
if (candidatePath.toFile().exists()) {
return candidatePath.toString()
}
basePath = basePath.getParent()
}
return null
}
buildscript {
// Buildscript is evaluated before everything else so we can't use getExtOrDefault
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['VisionCamera_kotlinVersion']
@ -86,7 +66,7 @@ def getExtOrIntegerDefault(name) {
}
// REA Common/ folder only exists since REA v2.
def hasReanimated2 = file("${nodeModulesPath}/react-native-reanimated/plugin.js").exists()
def hasReanimated2 = file("${nodeModules}/react-native-reanimated/plugin.js").exists()
def disableFrameProcessors = rootProject.ext.has("disableFrameProcessors") ? rootProject.ext.get("disableFrameProcessors").asBoolean() : false
def ENABLE_FRAME_PROCESSORS = hasReanimated2 && !disableFrameProcessors
@ -116,7 +96,7 @@ android {
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
arguments '-DANDROID_STL=c++_shared',
"-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
"-DNODE_MODULES_DIR=${nodeModulesPath}",
"-DNODE_MODULES_DIR=${nodeModules}",
"-DFOR_HERMES=${FOR_HERMES}"
}
}
@ -246,16 +226,16 @@ dependencies {
//noinspection GradleDynamicVersion
extractJNI("com.facebook.fbjni:fbjni:+")
def rnAAR = fileTree("${nodeModulesPath}/react-native/android").matching({ it.include "**/**/*.aar" }).singleFile
def jscAAR = fileTree("${nodeModulesPath}/jsc-android/dist/org/webkit/android-jsc").matching({ it.include "**/**/*.aar" }).singleFile
def rnAAR = fileTree("${nodeModules}/react-native/android").matching({ it.include "**/**/*.aar" }).singleFile
def jscAAR = fileTree("${nodeModules}/jsc-android/dist/org/webkit/android-jsc").matching({ it.include "**/**/*.aar" }).singleFile
def inputFile = file("${nodeModulesPath}/react-native/package.json")
def inputFile = file("${nodeModules}/react-native/package.json")
def json = new JsonSlurper().parseText(inputFile.text)
def reactNativeVersion = json.version as String
def (major, minor, patch) = reactNativeVersion.tokenize('.')
def jsEngine = FOR_HERMES ? "hermes" : "jsc"
def reaAAR = "${nodeModulesPath}/react-native-reanimated/android/react-native-reanimated-${minor}-${jsEngine}.aar"
def reaAAR = "${nodeModules}/react-native-reanimated/android/react-native-reanimated-${minor}-${jsEngine}.aar"
extractJNI(files(rnAAR, jscAAR, reaAAR))
}
@ -282,7 +262,7 @@ if (ENABLE_FRAME_PROCESSORS) {
def downloadsDir = new File("$buildDir/downloads")
def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
def thirdPartyVersionsFile = new File("${nodeModulesPath}/react-native/ReactAndroid/gradle.properties")
def thirdPartyVersionsFile = new File("${nodeModules}/react-native/ReactAndroid/gradle.properties")
def thirdPartyVersions = new Properties()
thirdPartyVersions.load(new FileInputStream(thirdPartyVersionsFile))
@ -414,8 +394,8 @@ if (ENABLE_FRAME_PROCESSORS) {
task prepareHermes() {
doLast {
def hermesPackagePath = findNodeModulePath(projectDir, "hermes-engine")
if (!hermesPackagePath) {
def hermesPackagePath = file("${nodeModules}/hermes-engine")
if (!hermesPackagePath.exists()) {
throw new GradleScriptException("Could not find the hermes-engine npm package", null)
}
@ -438,8 +418,8 @@ if (ENABLE_FRAME_PROCESSORS) {
task prepareJSC {
doLast {
def jscPackagePath = findNodeModulePath(projectDir, "jsc-android")
if (!jscPackagePath) {
def jscPackagePath = file("${nodeModules}/jsc-android")
if (!jscPackagePath.exists()) {
throw new GradleScriptException("Could not find the jsc-android npm package", null)
}