본문 바로가기

React Native

React Native에서 하나의 코드베이스로 Multitenant 앱 만들기

반응형

React Native로 여러 브랜드나 클라이언트를 위한 Multitenant 앱을 하나의 코드베이스로 관리하는 방법을 알아보겠습니다. 환경 설정 분리, 브랜드별 리소스 관리, 빌드 스크립트 활용 등 Multitenant 앱 개발의 주요 방법들을 살펴보겠습니다.

 

Multitenant 앱이란 무엇인가?

React Native로 모바일 앱을 개발하다 보면, 하나의 코드베이스로 여러 브랜드나 클라이언트를 위한 앱을 만들어야 하는 경우가 종종 있습니다. 이를 Multitenant 앱이라고 부르며, 여러 고객이나 브랜드를 하나의 플랫폼에서 지원하는 구조입니다. 이 글에서는 React Native를 사용해 Multitenant 앱을 구축하고 관리하는 방법을 자세히 설명하려고 합니다. 하나의 코드베이스로 여러 앱을 관리하는 것은 복잡해 보일 수 있지만, 효과적인 전략을 사용하면 효율적으로 처리할 수 있습니다.

Multitenancy 개념 이해하기

Multitenancy는 하나의 애플리케이션 인스턴스를 여러 고객(테넌트)이 사용할 수 있도록 하는 소프트웨어 아키텍처입니다. 각 테넌트는 자신만의 데이터와 설정을 가지고 있으나, 애플리케이션의 기본 코드는 공유합니다. 이를 통해 개발, 유지보수, 배포의 효율성을 높일 수 있습니다. 예를 들어, 여러 브랜드가 각각의 앱을 필요로 할 때, 각 브랜드별로 별도의 앱을 개발하는 대신, 하나의 코드베이스로 여러 브랜드를 지원하는 것이 Multitenancy의 핵심입니다.

여러 앱을 하나의 코드베이스로 관리하는 이유

Multitenant 앱 구조는 많은 이점을 제공합니다. 가장 큰 장점은 유지보수의 간소화입니다. 모든 앱이 하나의 코드베이스를 공유하기 때문에, 버그를 수정하거나 새로운 기능을 추가할 때 하나의 코드만 수정하면 됩니다. 이렇게 하면 개발 시간과 비용을 크게 절감할 수 있습니다. 또한, 각 브랜드별로 일관된 사용자 경험을 제공하면서도, 브랜드 특화된 기능을 구현하는 유연성을 유지할 수 있습니다.

 

React Native에서 Multitenant 앱 구조 설계하기

React Native에서 Multitenant 앱을 설계하려면 먼저 환경 설정을 분리하고, 각 브랜드에 맞춘 설정을 관리하는 것이 중요합니다.

환경 설정 분리하기

각 브랜드나 클라이언트마다 서로 다른 환경 설정이 필요합니다. 예를 들어, API 엔드포인트, 브랜드 색상, 로고 등이 달라질 수 있습니다. 이를 위해 .env 파일을 사용하여 환경 변수를 정의하고, react-native-config와 같은 라이브러리를 사용해 브랜드별 설정을 간편하게 관리할 수 있습니다.

API_URL=https://api.brand1.com
BRAND_COLOR=#ff0000

 

이렇게 브랜드마다 별도의 환경 파일을 만들어 관리하면, 빌드 시점에 해당 브랜드에 맞는 설정을 적용할 수 있습니다.

구성 파일을 통한 브랜드별 설정 관리

브랜드별 설정을 관리하기 위해 JSON 구성 파일을 사용할 수 있습니다. 각 브랜드에 대한 로고, 색상, 텍스트 등을 JSON 파일에 정의하고, 앱이 실행될 때 해당 브랜드에 맞는 설정을 로드하도록 할 수 있습니다. 이렇게 하면 코드베이스를 공유하면서도 각 브랜드에 맞춤화된 설정을 제공할 수 있습니다.

 

Multitenant 앱의 구현 방법

Multitenant 앱을 구현할 때 중요한 것은 각 브랜드의 리소스를 분리하고, 이를 빌드 스크립트와 디플로이 전략으로 효율적으로 관리하는 것입니다.

브랜드별 리소스와 스타일 분리하기

각 브랜드의 로고, 이미지, 스타일 시트를 별도로 관리해야 합니다. 예를 들어, assets/brand1, assets/brand2와 같은 폴더 구조를 통해 브랜드별 리소스를 분리할 수 있습니다. 또한, 스타일 파일도 brand1Styles.js, brand2Styles.js와 같이 분리하여 각 브랜드의 UI가 고유한 느낌을 줄 수 있도록 해야 합니다.

import brand1Styles from './styles/brand1Styles';
import brand2Styles from './styles/brand2Styles';

const styles = isBrand1 ? brand1Styles : brand2Styles;

 

이렇게 스타일을 분리하면 각 브랜드에 맞춤형 UI를 쉽게 제공할 수 있습니다.

빌드 스크립트 활용하기

브랜드별로 다른 빌드를 생성하려면 빌드 스크립트를 활용하는 것이 좋습니다. fastlane과 같은 도구를 사용하면 빌드 프로세스를 자동화하고 효율적으로 관리할 수 있습니다. 다음은 fastlane을 사용해 브랜드별 빌드를 자동화하는 단계별 가이드입니다.

  1. Fastlane 설치하기: 먼저 Fastlane을 설치해야 합니다. 터미널에서 다음 명령어를 사용해 설치합니다.
sudo gem install fastlane -NV
  1. Fastlane 초기화: 프로젝트 루트 디렉토리에서 Fastlane을 초기화합니다. 다음 명령어를 사용하세요.
fastlane init

 

        이 명령어는 Fastlane 설정 파일을 생성하고, 빌드에 필요한 초기 구성을 합니다.

  1. 브랜드별 빌드 lane 생성: 각 브랜드에 대한 빌드를 관리하기 위해 Fastfile에 lane을 추가합니다. 예를 들어, 브랜드1과 브랜드2를 위한 lane을 아래와 같이 설정할 수 있습니다.
lane :build_brand1 do
	increment_version_number
	gym(scheme: "Brand1Scheme")
	app_store_connect_api_key(
		key_id: "YOUR_KEY_ID",
		issuer_id: "YOUR_ISSUER_ID",
		key_filepath: "./AuthKey.p8"
	)
end

lane :build_brand2 do
	increment_version_number
	gym(scheme: "Brand2Scheme")
	app_store_connect_api_key(
		key_id: "YOUR_KEY_ID",
		issuer_id: "YOUR_ISSUER_ID",
		key_filepath: "./AuthKey.p8"
	)
end

 

        이렇게 각 브랜드에 대해 별도의 lane을 정의하면, 브랜드별로 다른 아이콘, 이름, 패키지 ID를 쉽게 적용할 수 있습니다.

  1. 브랜드별 빌드 실행: 터미널에서 다음 명령어로 특정 브랜드의 빌드를 실행할 수 있습니다.
fastlane build_brand1

 

       이 명령어를 실행하면 설정된 스크립트에 따라 브랜드1의 빌드가 자동으로 진행됩니다.

  1. OS 간 차이점: iOS와 Android 모두 Fastlane을 사용할 수 있지만, 각 플랫폼에 맞는 설정이 필요합니다. iOS의 경우 gym을 사용해 .ipa 파일을 빌드하고, Android의 경우 gradle을 사용해 .apk 파일을 빌드합니다. 예를 들어, Android용 lane은 다음과 같이 설정할 수 있습니다.
lane :build_brand1_android do
	gradle(task: "assembleBrand1Release")
end

 

       이렇게 Fastlane을 활용하면 여러 브랜드의 앱을 간편하게 빌드하고, 일관된 프로세스로 관리할 수 있습니다.

디플로이 전략 설정

디플로이 과정에서도 각 브랜드별로 다른 설정을 적용해야 합니다. 이를 위해 Firebase와 같은 백엔드 서비스를 각 브랜드에 맞게 분리하여 설정할 수 있습니다. 아래는 Firebase를 예시 들어, 단계별로 브랜드별 디플로이 설정을 구현하는 방법입니다.

  1. Firebase 프로젝트 분리: 각 브랜드별로 별도의 Firebase 프로젝트를 생성하여 데이터베이스, 인증, 스토리지를 독립적으로 관리합니다. 이를 통해 각 브랜드의 데이터가 독립적으로 유지되며 보안성을 강화할 수 있습니다.
  2. 환경 파일 구성: .env 파일을 사용해 각 브랜드에 대한 Firebase 설정을 관리합니다. 예를 들어, 브랜드별 API 키와 데이터베이스 URL을 각각의 .env 파일에 정의합니다.
# .env.brand1
FIREBASE_API_KEY=YOUR_FIREBASE_API_KEY_BRAND1
FIREBASE_DATABASE_URL=https://brand1.firebaseio.com

# .env.brand2
FIREBASE_API_KEY=YOUR_FIREBASE_API_KEY_BRAND2
FIREBASE_DATABASE_URL=https://brand2.firebaseio.com

 

       이렇게 환경 파일을 분리하면 빌드 시점에 해당 브랜드에 맞는 Firebase 설정을 적용할 수 있습니다.

  1. Firebase 초기화: 앱이 시작될 때 브랜드에 맞는 Firebase 설정을 초기화합니다. 예를 들어, 다음과 같이 환경 변수에 따라 Firebase를 초기화할 수 있습니다.
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';

const firebaseConfig = {
	apiKey: process.env.FIREBASE_API_KEY,
	authDomain: `${process.env.FIREBASE_PROJECT_ID}.firebaseapp.com`,
	databaseURL: process.env.FIREBASE_DATABASE_URL,
	projectId: process.env.FIREBASE_PROJECT_ID,
};

if (!firebase.apps.length) {
	firebase.initializeApp(firebaseConfig);
}

 

  1. CI/CD 파이프라인 설정: 각 브랜드별로 자동화된 배포를 위해 CI/CD 도구를 활용합니다. 예를 들어, GitHub Actions나 Jenkins와 같은 도구를 사용하여 브랜드별 .env 파일을 로드하고, 각 브랜드의 Firebase 프로젝트로 배포할 수 있습니다. 예시 GitHub Actions 워크플로는 다음과 같습니다.
name: Deploy Brand1

on:
	push:
		branches:
			- main
jobs:
	deploy:
		runs-on: ubuntu-latest
		steps:
			- name: Checkout repository
			  uses: actions/checkout@v2

			- name: Set up Node.js
			  uses: actions/setup-node@v2
			  with:
				node-version: '14'

			- name: Install dependencies
			  run: npm install

			- name: Set environment variables
			  run: echo "FIREBASE_API_KEY=${{ secrets.FIREBASE_API_KEY_BRAND1 }}" >> .env
              
			- name: Build and deploy
			  run: |
				npm run build
				firebase deploy --project brand1

 

       이렇게 CI/CD 파이프라인을 통해 각 브랜드에 대한 디플로이를 자동화하면, 개발자는 수동 작업 없이도 빠르고 일관된 배포를 진행할 수 있습니다.

효율적인 Multitenant 앱 관리 팁

Multitenant 앱을 개발하고 유지보수하는 과정에서 코드 재사용성과 클라이언트 맞춤형 기능 구현 사이의 균형을 유지하는 것이 중요합니다.

코드 재사용성 극대화

공통 기능은 최대한 재사용 가능한 형태로 만들어야 합니다. 예를 들어, 공통 UI 컴포넌트를 별도로 정의하고, 각 브랜드가 이 컴포넌트를 상속하거나 확장하여 사용할 수 있도록 합니다. 이렇게 하면 중복되는 코드를 최소화하고, 유지보수를 쉽게 할 수 있습니다.

각 클라이언트 맞춤형 기능 구현하기

각 클라이언트에 특화된 기능이 필요할 때는 조건부 렌더링이나 플래그를 사용해 특정 기능을 활성화하거나 비활성화할 수 있습니다. 예를 들어, 클라이언트 A만 사용하는 특정 버튼을 추가하려면 다음과 같이 조건부 렌더링을 사용할 수 있습니다.

{isClientA && <Button title="Special Feature" />}

 

이렇게 하면 공통 코드베이스를 유지하면서도 클라이언트 맞춤형 기능을 쉽게 구현할 수 있습니다.

 

마무리하며

React Native로 Multitenant 앱을 개발하는 것은 하나의 코드베이스로 여러 클라이언트를 지원할 수 있는 매우 효율적인 방법입니다. 이 글에서는 환경 설정 분리, 브랜드별 리소스 관리, 빌드 스크립트 활용 등 Multitenant 앱을 구현하고 관리하는 방법을 소개했습니다. 유지보수의 복잡성을 줄이고, 고객 맞춤형 기능을 효과적으로 구현하는 것이 성공적인 Multitenant 앱의 핵심입니다. 앞으로의 개발 과정에서 이러한 전략을 활용해 더 효율적이고 확장 가능한 앱을 만드는데 도움이 되길 바랍니다.

반응형