Microfrontends
Microfrontends는 웹 애플리케이션을 더 작고 독립적으로 개발 및 배포되어 함께 작동하는 애플리케이션으로 분해하는 아키텍처 패턴입니다.
Turborepo는 통합 프록시 서버를 통해 개발 중 수직 microfrontends(때로는 "zones"라고 함)를 로컬에서 실행하기 위한 기본 지원을 제공합니다. 프록시는 여러 애플리케이션을 조정하고 그들 간의 트래픽을 라우팅합니다.
여러 프론트엔드 애플리케이션이 있는 모노레포가 있다고 가정해 봅시다:
프로덕션 환경에서 이러한 애플리케이션은 개별적으로 배포되고 리버스 프록시 또는 엣지 라우팅을 사용하여 함께 구성될 수 있습니다. 하지만 개발 중에는 다음을 원합니다:
- 단일 명령으로 모든 애플리케이션을 동시에 실행
- 통합 URL(예:
http://localhost:3024)을 통해 액세스 - 경로 패턴을 기반으로 올바른 애플리케이션으로 요청 라우팅
- 핫 모듈 리로딩 및 WebSocket 연결 지원
- 포트 충돌 및 수동 조정 방지
시작하기
Turborepo는 개발 중 microfrontend 애플리케이션 간의 트래픽을 자동으로 라우팅하는 내장 프록시 서버를 제공합니다. 프록시는 microfrontends.json 설정 파일을 읽고 turbo dev를 실행할 때 시작됩니다.
npx create-turbo@latest -e with-microfrontends로 생성된 모노레포로 다음
지침을 시도할 수 있습니다.
microfrontends.json 생성
상위 애플리케이션에 microfrontends.json 파일을 생성합니다. 이 애플리케이션은 다른 애플리케이션과 일치하지 않을 때 모든 요청이 대체되는 애플리케이션입니다.
애플리케이션 포트 설정
다음으로 TURBO_MFE_PORT 환경 변수를 사용하여 애플리케이션의 개발 스크립트에서 포트를 설정합니다. 예를 들어:
베이스 경로 처리
프레임워크를 사용하는 경우 프레임워크의 요구 사항에 따라 베이스 경로를 설정합니다.
프레임워크별 지침은 프레임워크의 Microfrontends 섹션을 참조하세요.
turbo dev 실행
turbo dev를 실행하면 Turborepo는 다음을 수행합니다:
- 구성된 포트에서 프록시 서버 시작(기본값:
3024) - 작업에
TURBO_MFE_PORT환경 변수 주입하여 애플리케이션의 포트 설정 - 모든 구성된 애플리케이션에 대한 개발 작업 실행
- 경로 패턴을 기반으로 적절한 애플리케이션으로 수신 요청 라우팅
이제 http://localhost:3024에서 모든 microfrontends 애플리케이션에 액세스할 수 있습니다.
설정
applications 객체의 각 애플리케이션은 다음 속성을 가질 수 있습니다:
제공되지 않으면 애플리케이션 키가 package.json의 이름과 일치하도록 사용됩니다.
development.local
애플리케이션이 로컬에서 실행되는 포트입니다. 다음과 같이 지정할 수 있습니다:
- 숫자:
3000 - 포트가 있는 호스트명:
"localhost:3000" - URL:
"http://localhost:3000"
development.fallback
애플리케이션이 로컬에서 실행되지 않을 때 프록시할 대상을 선택적으로 제공합니다. 이는 애플리케이션의 하위 집합만 실행하는 turbo dev --filter=web와 같은 명령을 원활하게 만들기 위해 프로덕션으로 라우팅하는 데 가장 자주 사용됩니다.
완전히 정규화된 URL이어야 합니다.
routing
이 애플리케이션으로 라우팅해야 하는 경로 그룹의 배열입니다. 라우팅이 제공되지 않으면 애플리케이션은 일치하지 않는 모든 경로를 포착하는 기본 애플리케이션이 됩니다.
하나의 애플리케이션만 routing 설정을 가지지 않을 수 있습니다. 이것이 다른 애플리케이션과 일치하지 않는 모든 경로를 처리하는 "루트" 애플리케이션입니다.
정확한 일치
이러한 경로는 작성된 대로 정확하게 일치합니다.
매개변수
:로 시작하는 세그먼트는 단일 경로 세그먼트와 일치합니다. 예를 들어, /blog/:slug는 /blog/hello와 일치하지만 /blog/hello/world와는 일치하지 않습니다.
와일드카드
*로 끝나는 매개변수는 0개 이상의 경로 세그먼트와 일치합니다. 예를 들어, /docs/:path*는 /docs, /docs/intro, /docs/api/reference와 일치합니다.
그룹 레이블
더 나은 유지 관리를 위해 경로를 논리적 그룹으로 구성합니다:
group 필드는 구성 목적을 위한 것이며 라우팅 동작에 영향을 주지 않습니다.
복잡한 라우팅 패턴
중첩된 매개변수로 정교한 라우팅을 정의할 수 있습니다:
packageName
워크스페이스에서 package.json의 패키지 이름을 선택적으로 사용합니다.
options.localProxyPort
localProxyPort 옵션을 사용하여 선택적으로 프록시 포트를 변경합니다.
기본값은 3024입니다.
프로덕션과 통합
Turborepo microfrontends 프록시는 로컬 사용만을 위한 것입니다. 프로덕션 microfrontends를 구현하고 통합하는 방법은 프로덕션 인프라에 따라 다릅니다. 그러나 로컬 및 프로덕션 환경을 통합하여 환경 전반에 걸쳐 원활한 경험을 만들 수 있습니다.
시작하기 위해 Turborepo의 로컬 프록시를 Vercel의 microfrontends와 통합하도록 구축했습니다. 통합하고자 하는 모든 인프라 제공업체와 협력하기를 기대합니다.
Vercel의 Microfrontends
Vercel은 다음을 제공하는 microfrontends에 대한 기본 지원을 제공합니다:
- 향상된 성능의 프로덕션 프록시 구현
- 환경 전반의 대체 URL 지원
- Vercel 툴바 통합
- 기능 플래그 지원
- 애셋 접두사 처리
@vercel/microfrontends로 마이그레이션
패키지에 @vercel/microfrontends를 설치하거나 워크스페이스에 추가하면 Turborepo가 내장 프록시 대신 자동으로 이를 사용합니다. 이를 통해 점진적인 마이그레이션 경로가 가능합니다.
Turborepo와 동일한 microfrontends.json 설정을 사용할 수 있습니다. Turborepo의 microfrontends.json 스키마는 Vercel 스키마의 하위 집합이므로 @vercel/microfrontends와 호환됩니다.
@vercel/microfrontends에 대해 자세히 알아보려면 npm의 패키지를 방문하세요.
문제 해결
포트가 이미 사용 중
기본적으로 microfrontends 프록시는 포트 3024를 사용하려고 시도합니다. 다른 목적으로 해당 포트를 이미 사용 중인 경우 options.localProxyPort를 사용하여 Turborepo의 포트를 변경할 수 있습니다.
CSS, 이미지 또는 기타 애셋 누락 또는 경로가 일치하지 않음
microfrontends가 routing 설정에서 일치시키는 경로에 애셋에 대한 경로가 포함되어 있는지 확인합니다. 네트워크 탭을 확인하여 예상대로 일치하거나 일치하지 않는 경로를 찾으세요.
애플리케이션 간 링크로 인한 오류
애플리케이션 간 링크에 Single-Page Application(SPA) 링크(Next.js <Link> 컴포넌트 등)를 사용하면 오류가 발생할 수 있습니다. 포트와 도메인은 동일하게 유지되지만 애플리케이션은 다릅니다. 이는 라우팅이 정의상 "단일 페이지 애플리케이션"이 아님을 의미합니다.
프록시된 포트 방문 시 리디렉션되지 않음
프록시된 포트에 여전히 직접 접근할 수 있습니다. 예를 들어, localhost:3000이 localhost:3042로 프록시되어 있어도 브라우저에서 여전히 localhost:3000을 방문할 수 있습니다.
localhost:3000이 localhost:3024로 리디렉션되도록 하려면 애플리케이션에서 수동으로 설정해야 합니다.
애플리케이션이 시작되지 않음
다음을 확인하세요:
packageName이 실제 패키지 이름과 일치하는지- 지정된
task가 패키지의package.json에 존재하는지 - 각 애플리케이션의 포트가 사용 가능한지
- 모든 종속성이 설치되어 있는지
전체 예제
다음은 전자 상거래 플랫폼을 위한 microfrontends 설정의 전체 예제입니다:
이 설정을 사용하면:
web앱은 홈페이지 및 일치하지 않는 모든 경로를 처리합니다docs앱은 모든 문서를 처리합니다blog앱은 블로그 게시물 및 저자 페이지를 처리합니다shop앱은 전자 상거래 기능을 처리합니다