IT 개발자가 되기위한 여정

컴퓨터 공부를 시작함에 앞서 계획 및 개발에 대한 내용을 풀어나갈 생각입니다.

IT 학습/프레임워크

MFA (Micro Frontend Architecture)란? 도입 하기

제로시엘 2023. 8. 14. 14:17

MFA(Micro Frontend Architecture)란

웹 프론트엔드를 작은 독립적인 단위로 나누어 개발하고 배포하는 아키텍처 패턴을 의미합니다. 이는 마이크로 서비스 아키텍처의 원칙을 웹 프론트엔드에 적용한 것으로, 애플리케이션을 작은 모듈 또는 마이크로 프론트엔드로 분리하여 개발하고 관리하는 방식입니다.

MFA 개요

MFA는 하나의 대규모 단일 애플리케이션 대신, 작은 프론트엔드 모듈을 개발하고 각 모듈을 독립적으로 배포하고 실행함으로써 애플리케이션을 구성합니다. 이는 여러 개발 팀이 동시에 작업하고 독립적으로 배포하여 개발 생산성을 향상시킬 수 있게 해줍니다.

MFA 적용시 장점

  • 독립적인 개발 및 배포: 각 마이크로 프론트엔드는 독립적으로 개발되며, 필요한 경우 개별적으로 배포할 수 있습니다.
  • 기술 스택 선택의 자유: 각 마이크로 프론트엔드는 다른 기술 스택을 사용할 수 있어, 최적의 도구와 언어를 선택할 수 있습니다.
  • 팀 간 협업 용이: 다수의 개발 팀이 동시에 작업하고, 각 팀이 관리하는 마이크로 프론트엔드를 조합하여 애플리케이션을 구성할 수 있습니다.
  • 유연한 업데이트: 개별 프론트엔드 모듈의 업데이트가 전체 애플리케이션에 미치는 영향이 최소화되어, 업데이트 프로세스가 유연하고 안정적입니다.

MFA 적용시 단점

  • 커뮤니케이션 오버헤드: 다수의 마이크로 프론트엔드 모듈을 관리하고 조율하기 위한 추가적인 커뮤니케이션이 필요할 수 있습니다.
  • 루팅 및 상태 관리의 어려움: 애플리케이션 내부에서 라우팅 및 전역 상태 관리에 복잡성이 증가할 수 있습니다.
  • 런타임 성능 영향: 클라이언트 측에서 여러 프론트엔드 모듈을 조합하는 데 필요한 추가 로딩 및 초기화 시간이 발생할 수 있습니다.

MFA 도입 사례

  • Spotify: Spotify의 웹 애플리케이션은 MFA를 사용하여 여러 팀이 독립적으로 작업하고 배포하는 방식으로 개발됩니다.
  • Zalando: Zalando는 MFA를 사용하여 쇼핑 웹사이트를 작은 모듈로 나누어 개발하고, 필요한 경우 독립적으로 배포합니다.
  • NHN Cloud: 향후 마이크로 프런트엔드로의 변경을 위해 시험적 으로 도입 추진 중입니다.
  • Kakao : 카카오의 공통 플랫폼게발 파트와 카카오워크 팀이 최근 MFA로 마이그레이션 했습니다.
  • TOSS : 모놀리식 Django를 최근 MFA 인프라로 변경하였습니다.
  • 비즈넵 : 자사 서비스를 MFA로 마이그레이션 했습니다.

Micro Frontends 아키텍처를 구현하는 5가지 방법

  1. Server-side template Composition
  2. Build-time Integration
  3. Run-time Integration via iframes
  4. Run-time Integration via web-components
  5. Run-time Integration via javascript

실 도입을 고려한 MFA

1. Server-side template Composition

각각 다른 앱에 맞는 HTML을 서빙하는 서버를 뒤에 두고, 요청한 URL에 따라 맞는 HTML들을 라우팅해주는 nginx 서버를 그 앞에다가 놓아서, 맞는 HTML을 응답으로 보내주는 구조입니다.

웹 개발 트랜드에 좀 더 맞게 말하면, 특정 페이지 단위의 앱을 가지고 있는 여러개의 Next.js앱 서버를 배포해놓고, Route53이나 Cloud Front같은 인프라단에서 특정 앱에 해당되는 basePath로 요청이 들어왔을 때 해당 앱이 응답하는 HTML과 JS를 보내주어 웹앱을 그리는 방식입니다.

결국, 아까 설명했던 “웹앱 단위 이상으로 배포단위를 쪼개는 것” 과 같습니다.

어느정도 구현이 완료된 솔루션으로는 Next.js + Vercel을 사용한 multi-zones가 있습니다.

2. Run-time Integration via javascript

이 방법은 UI 컴포넌트를 자바스크립트 번들 단위로 배포 단위를 나누고, 필요할 때 번들을 로딩 하여 런타임에 통합 시키는 방식입니다.

React를 사용한다고 가정한다면 이 방법에서는 “정의한 컴포넌트들을 그냥 툭 떼서 별도의 배포단위로 만들고 런타임에서 합치는 것” 이 가능합니다. 해당 컴포넌트부터 런타임에 만들 수 있는 독립된 번들로 만드는 거죠.

https://maxkim-j.github.io/static/b24f629481b2779ccd0464eb571d9f28/c1b63/6.png

당연히 배포 단위별 공유되는 상태의 관리는 React에서 제공하는 API들을 통해 앱 안에서 자연스럽게 가능합니다. 미리 로딩된 앱이 가져온 CSS와 같은 자원들도 바로 사용할 수 있습니다.

이 방법이 주는 가장 큰 장점은 배포 단위를 유연하게 가져갈 수 있게 한다는 것입니다. 배포단위간 상태 공유를 위한 작업이 앞선 두 런타임 통합 방법보다 많거나 이질적이지 않고, 모두 웹 앱 내부에서 가능하니 기존 배포 단위를 합치거나 나누는 것이 비교적 간편합니다.

webpack 5가 제공하는 Module Federation Plugin이 이 방식에 해당하는 솔루션입니다. 해당 플러그인은 분리된 배포 단위의 웹앱이 모이는 일명 host, 각각 분리된 배포 단위인 remote 앱을 정의하고 런타임에 합칠 수 있는 빌드 옵션을 제공합니다.

MFA의 방식에 대한 선택

MFA 도입하기

1. 비트

Bit를 사용하면 독립적인 구성 요소에서 프런트엔드를 구성하고 관리할 수 있습니다.

bit.dev 홈페이지를 살펴보면 서로 다른 팀에서 서로 다른 코드베이스로 구축한 독립적인 구성 요소로 구성되어 있으며 모두 함께 통합되어 응집력 있는 제품을 생성한다는 것을 알 수 있습니다.

 

Bit를 사용하면 여러 팀이 구성 요소를 독립적으로 구축, 게시 및 노출하는 동시에 다른 팀과 협력하여 웹 개발 프로세스를 기능 및 구성 요소의 모듈식 구성으로 전환할 수 있습니다.

2. Webpack 5

webpack 5가 제공하는 Module Federation Plugin을 통해 Microfrontends를 구현할 수 있습니다. 해당 플러그인은 분리된 배포 단위의 웹앱이 모이는 일명 host, 각각 분리된 배포 단위인 remote 앱을 정의하고 런타임에 합칠 수 있는 빌드 옵션을 제공합니다.

 

즉, Module Federation을 사용하면 JavaScript 애플리케이션이 런타임에 다른 애플리케이션에서 동적으로 코드를 가져올 수 있습니다. 이 모듈은 Webpack 구성을 설정하여 다른 애플리케이션에서 다운로드할 수 있는 고유한 JavaScript 항목 파일을 빌드 합니다.

 

또한 종속성 공유를 활성화하여 코드 종속성 및 증가된 번들 크기 문제를 해결합니다. 예를 들어 React 구성 요소를 다운로드하는 경우 애플리케이션은 React 코드를 두 번 가져오지 않습니다. 모듈은 이미 가지고 있는 React 소스를 현명하게 사용하고 구성 요소 코드만 가져옵니다. 마지막으로 React.lazy 및 React.suspense를 사용하여 가져온 코드가 어떤 이유로 실패하는 경우 대비책을 제공하여 빌드 실패로 인해 사용자 경험이 중단되지 않도록 할 수 있습니다.

 

도입하기

MFA 설계하기

MFA(Micro Frontend Architecture)를 구현하기 위해서는 애플리케이션의 구조, 개발 및 배포 프로세스, 라우팅 및 상태 관리 등 다양한 측면을 고려해야 합니다. 아래는 MFA 구현 설계에 관련한 상세한 설명입니다.

1. 애플리케이션 구조 설계:
애플리케이션은 주로 메인 애플리케이션과 여러 개의 마이크로 프론트엔드로 구성됩니다. 각 마이크로 프론트엔드는 독립적인 디렉토리 및 프로젝트로 관리되며, 공통 컴포넌트 및 유틸리티는 필요에 따라 별도의 모듈로 분리합니다.

2. 개발 및 배포 프로세스 설계:
각 마이크로 프론트엔드는 독립적으로 개발 및 테스트되며, 버전 관리 시스템을 통해 관리됩니다. 배포 시에는 CI/CD 도구를 활용하여 개별 마이크로 프론트엔드를 빌드하고 배포합니다.

3. 라우팅 설계:
각 마이크로 프론트엔드는 독립적인 라우팅을 가지고 있을 수 있습니다. 메인 애플리케이션은 주로 라우터를 통해 요청된 URL에 따라 적절한 마이크로 프론트엔드를 렌더링하도록 조절합니다. 라우팅을 조율하기 위한 중앙 집중식 라우터 또는 미들웨어를 사용하는 방식을 선택할 수 있습니다.

4. 상태 관리 설계:
전역 상태 관리는 각 마이크로 프론트엔드 간의 데이터 공유 및 통신에 중요한 역할을 합니다. 상태 관리 라이브러리(예: Redux, MobX) 또는 Context API와 같은 React의 내장 기능을 활용하여 상태 관리를 구현합니다.

5. 공통 컴포넌트 및 스타일 가이드 설계:
여러 마이크로 프론트엔드 간에 공통적으로 사용되는 컴포넌트와 스타일을 정의하여 중복을 줄이고 일관성을 유지할 수 있습니다. 이를 위해 공통 라이브러리, 컴포넌트 스타일링 도구(예: styled-components)을 사용할 수 있습니다.

6. 통신 및 데이터 교환 설계:
마이크로 프론트엔드 간에 데이터 교환을 위해 이벤트 버스, Pub/Sub 패턴, HTTP API 호출 등을 활용할 수 있습니다. 각 마이크로 프론트엔드가 자체적으로 데이터를 관리하거나 필요에 따라 다른 마이크로 프론트엔드와 상호 작용할 수 있도록 설계합니다.

7. 보안 및 인증 설계:
보안적인 측면에서 각 마이크로 프론트엔드 간의 데이터 분리 및 보호, 인증 및 권한 부여 등을 고려해야 합니다. 중요한 데이터의 경우 인증 및 보안 전략을 구현하여 민감한 정보가 노출되지 않도록 합니다.

8. 모니터링 및 디버깅 설계:
마이크로 프론트엔드 간의 통신 및 동작을 모니터링하고, 오류 디버깅을 위한 로깅 시스템을 구축합니다. 필요한 경우 모니터링 및 디버깅 도구를 통합하여 애플리케이션의 안정성과 성능을 유지합니다.

9. 성능 최적화 설계:
마이크로 프론트엔드를 로딩하고 조합하는 과정에서 발생하는 초기 로딩 시간 및 런타임 성능을 최적화합니다. 코드 스플리팅, 레이지 로딩, 캐싱 전략 등을 활용하여 사용자 경험을 향상시킵니다.

10. 테스트 및 QA 전략 설계:
개별 마이크로 프론트엔드 단위 테스트와 통합 테스트를 수행하여 안정성을 검증합니다. QA 프로세스에서는 여러 마이크로 프론트엔드 간의 통합 및 사용자 시나리오를 테스트하여 전체 애플리케이션의 동작을 확인합니다.

MFA 구현은 애플리케이션의 복잡성과 요구 사항에 따라 다양한 설계 패턴과 도구를 활용하여 수행될 수 있습니다. 이 과정에서 개발자 및 팀 간의 협력과 의사소통이 핵심 역할을 하며, 지속적인 개선과 최적화를 통해 유연하고 확장 가능한 마이크로 프론트엔드 아키텍처를 구축할 수 있습니다.

MFA 도입에 대한 개인적인 생각

MFA(Micro Frontend Architecture)를 도입하여 개발할 때, 기존의 메인 페이지(호스트)가 이미 존재한다면 MFA를 구현하는 과정이 크게 어려울 것은 없을 것입니다. MFA를 사용하면 각 페이지나 앱을 독립적으로 개발하고 구축할 수 있기 때문에, 기존의 인프라나 설정을 연결하는 작업만 수행하면 됩니다. 따라서 개발자들이 이미 익숙한 방식으로 개발할 수 있을 것입니다.

다만, 만약 새로운 메인 페이지(호스트)부터 개발을 시작해야 한다면 기존의 개발 시간이 늘어날 수 있습니다. MSA(Microservices Architecture)와 비슷한 접근 방식으로, 각각의 컴포넌트나 모듈을 연결하고 웹팩 설정을 구성해야 할 것입니다.

구체적으로 시도할 수 있는 두 가지 방법을 생각해보면:

1. Next.js 템플릿 사용 및 스타터 생성:
Vercel의 Next.js 템플릿을 활용하여 시작하고, 이를 기반으로 스타터 킷을 만들어서 사용하는 방법입니다. 이 방식은 시작 단계에서 설정을 간편하게 할 수 있지만, Next.js의 서버 사이드 템플릿 방식에 의존하게 될 수 있습니다.

2. Webpack 5부터 단계적 설계:
Webpack 5부터 시작하여 MFA 서비스를 설계해 나가는 방법입니다. 초기 개발 단계에서는 메인 페이지(호스트)의 구축에 시간이 걸릴 수 있지만, 그 후에 추가적인 기능이나 새로운 페이지를 개발하고 연결하는 과정은 훨씬 쉬워질 것입니다.

첫 번째 방법은 시작하기 쉬울 수 있지만 Next.js에 종속적일 수 있다는 단점이 있습니다. 반면 두 번째 방법은 초기 설정에 시간이 들 수 있지만, 이후의 개발은 유연하고 확장 가능할 것입니다. 이 두 가지 방법 중에서 개발 팀의 선호와 프로젝트의 목표에 맞게 선택하면 됩니다.

참고자료