거의 알고리즘 일기장
Monorepo 환경에 react native 추가하기(with turborepo) 본문
필자는 개인적으로 프로젝트에 기능을 추가할때, 미니 프로젝트를 만들어서 테스트를 충분히 해본 이후 적용하는것을 선호한다.
하지만, 미니 프로젝트를 너무 여러개 만들다보니 예전에 만들었던것을 잊고 새로 세팅하고 새로 세팅하는 금붕어 같은 짓으로 시간을 쓰곤했다.
그래서 떠올린게 최근에 만든 turborepo가 no configuration 수준으로 설정이 간편해서 이걸 이용해 모노레포 환경을 만들면 관리하기 편하지 않을까? 생각해서 시간이 남을때 조금씩 해보게 되었다.
솔직히 Next, react, expo 까지는 문서에 적혀있기도하고 example 보고 세팅하기 편했다.
근데, react native cli는 세팅하면서 자료도 없고 몇가지 짜증난 부분이 있었어서 정리해둔다.
변경해야 할 사항은 크게 세가지 부분이다.
1. metro config
2. ios node_module 상대경로로 쓰여있는 부분 수정
3. android node_module 상대경로로 쓰여있는 부분 수정
metro config
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const path = require('path');
// Find the workspace root, this can be replaced with `find-yarn-workspace-root`
const workspaceRoot = path.resolve(__dirname, '../..');
const projectRoot = __dirname;
/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
const config = getDefaultConfig(projectRoot);
// 1. Watch all files within the monorepo
config.watchFolders = [workspaceRoot];
// 2. Let Metro know where to resolve packages, and in what order
config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, 'node_modules'),
path.resolve(workspaceRoot, 'node_modules'),
];
// 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
config.resolver.disableHierarchicalLookup = true;
module.exports = config;
root와 project의 node_module 둘다 추가해주는 부분이 들어간다. 해당 내용은 expo 문서에 Monorepo 환경에서 metro config 변경하는 부분 참고해서 변경했다.
https://docs.expo.dev/guides/monorepos/
Ios
아마 이 상태로 실행하면, react native code and images 과정에서 적절하게 node_modules 파일을 찾아가지 못하는 현상이 있을텐데, 아래와 같이 경로를 수정해주면 된다.
android
1. project/settings.gradle
rootProject.name = 'rn-bare-app'
apply from: file("../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
includeBuild('../../../node_modules/@react-native/gradle-plugin')
2. app/build.gradle
아래부분 참고하센
//...
react {
/* Folders */
// The root of your project, i.e. where "package.json" lives. Default is '..'
// root = file("../")
// The folder where the react-native NPM package is. Default is ../node_modules/react-native
reactNativeDir = file("../../../../node_modules/react-native")
// The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
codegenDir = file("../../../../node_modules/@react-native/codegen")
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
cliFile = file("../../../../node_modules/react-native/cli.js")
//...
}
//...
apply from: file("../../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
3. (option) react-native-gesture-handler 쓰는 경우에 해당 내용안에 react-native를 상대경로로 찾아가는 부분이 있다 ㅡㅡ 이 부분은 환경변수에 값을 추가해주면 됨 (gradle.properties)
REACT_NATIVE_NODE_MODULES_DIR=../../../../../node_modules/react-native
근거는 다음과 같다.
//react-native-gesture-handler/android/build.gradle중
//...
def resolveReactNativeDirectory() {
//여기보면 REACT_NATIVE_NODE_MODULES_DIR 이렇게 경로를 환경변수로 보면 이걸 먼저 읽으므로 이걸 사용해서 해결하는게 나이스해보임
//근데 gesture handler docs에 저 환경변수에 대한 내용이 검색이 안되는데ㅠ 알잘딱깔센 해야하는듯
def reactNativeLocation = safeExtGet("REACT_NATIVE_NODE_MODULES_DIR", null)
if (reactNativeLocation != null) {
return file(reactNativeLocation)
}
// monorepo workaround
// react-native can be hoisted or in project's own node_modules
def reactNativeFromProjectNodeModules = file("${rootProject.projectDir}/../node_modules/react-native")
if (reactNativeFromProjectNodeModules.exists()) {
return reactNativeFromProjectNodeModules
}
def reactNativeFromNodeModulesWithReanimated = file("${projectDir}/../../react-native")
if (reactNativeFromNodeModulesWithReanimated.exists()) {
return reactNativeFromNodeModulesWithReanimated
}
throw new Exception(
"[react-native-gesture-handler] Unable to resolve react-native location in " +
"node_modules. You should add project extension property (in app/build.gradle) " +
"`REACT_NATIVE_NODE_MODULES_DIR` with path to react-native."
)
}
//...
결과
성공적
해보면 별거아니지만, 왠지 react native 처음 하거나 익숙하지 않은 사람들은 세팅할때 혐오증 걸릴수도 있을것 같은 느낌을 살짝 받았다.
참고
https://github.com/byCedric/expo-monorepo-example/blob/main/apps/mobile/metro.config.js
'react-native' 카테고리의 다른 글
RCTView, RCTText를 직접적으로 사용하면 더 빠르다? (1) | 2024.05.19 |
---|---|
fastlane ci/cd 환경상에서 실행시 주의할 사항 (react native) (0) | 2023.11.28 |
react native에서 android target sdk를 33이상으로 올릴경우 주의할점 (권한 정책 변경으로 인한 문제 해결) (2) | 2023.09.06 |
React Native를 이용한 사이드 프로젝트 만들기 2 - 1. 새로운 프로젝트를 기획하다! (0) | 2023.08.14 |
요즘 expo 괜찮은가요?? (react native) (0) | 2023.08.14 |