마이크로 프론트엔드에서 라우팅 관리

Adam Kim·2025년 12월 22일

angular

목록 보기
91/102

Angular 마이크로프론트엔드(MFE) 환경에서 여러 애플리케이션을 동시에 운영하다 보면 예상치 못한 난관에 부딪히곤 합니다. 그중 하나가 바로 '라우터(Router) 관리'입니다.

이번 글에서는 메인 애플리케이션 위에 팝업 형태로 다른 Angular 앱을 띄우고, 그 팝업 안에서 독립적으로 라우팅을 처리하는 아주 흥미로운 문제와 그 해결 과정을 살펴보겠습니다.

무엇이 문제인가? - 두 개의 집, 하나의 주소

우리가 마주한 상황은 이렇습니다. 사용자가 메인 앱(http://my-app.com/dashboard)을 사용하던 중, 간단한 양식을 작성하기 위해 팝업을 띄웁니다. 이 팝업은 사실 별개의 Angular 프로젝트로 만들어진 마이크로프론트엔드 앱입니다.

문제는 이 팝업 앱 내부에도 여러 페이지(/form/step1, /form/step2)가 존재하고, 이 페이지들을 자유롭게 이동해야 한다는 점입니다.

만약 팝업 앱의 라우터가 평소처럼 동작한다면 어떻게 될까요? 팝업 안에서 페이지를 이동할 때마다 브라우저의 전체 URL이 http://my-app.com/form/step2 와 같이 변경되어 버립니다. 결국 뒤에 있던 메인 앱의 dashboard 페이지는 사라지고, 원치 않는 전체 페이지 이동이 발생합니다.

우리의 목표: 메인 앱의 URL은 그대로 유지하면서, 팝업 앱 안에서만 URL이 바뀌는 것처럼 동작하게 만들자!

해결의 실마리: Angular 라우터의 작동 방식

이 문제를 해결하려면 Angular 라우터가 어떻게 브라우저와 소통하는지 이해해야 합니다. 아주 간단히 비유해 보겠습니다.

  • Router: 내비게이션 앱 (목적지: /form/step2)
  • Location / LocationStrategy: 운전자 (내비게이션의 지시를 받아 실제로 핸들을 돌리고 페달을 밟음)
  • 브라우저 API: 실제 자동차와 도로 (핸들 조작에 따라 차가 움직이고 주소가 바뀜)

평소에는 Router가 "/form/step2로 가!"라고 명령하면, LocationStrategy가 이 명령을 받아 브라우저의 주소창을 직접 변경합니다. 우리는 이 '운전자'가 실제 자동차를 운전하지 않고, 시뮬레이터(가상 환경)를 운전하게 만들어야 합니다.

핵심 도구: 테스트 라이브러리의 재발견

놀랍게도 이 문제의 해답은 Angular의 테스트 도구 안에 있었습니다. 바로 MockLocationStrategy와 SpyLocation입니다.

1. MockLocationStrategy란?

이름 그대로 '가짜' LocationStrategy입니다. 원래는 테스트 코드에서 라우팅이 잘 동작하는지 확인할 때 사용됩니다.

이 가짜 운전자는 Router로부터 "/form/step2로 가!"라는 명령을 받아도 실제 브라우저의 핸들을 돌리지 않습니다. 대신, 자신의 머릿속(메모리)에 "현재 위치는 /form/step2야"라고 기록만 해둡니다. 브라우저 URL은 전혀 바뀌지 않죠.

2. SpyLocation이란?

'스파이'처럼 위치 변화를 엿보는 역할을 합니다. MockLocationStrategy가 머릿속으로만 경로를 변경할 때, SpyLocation은 그 변경 사항을 감지하고 "어, 지금 내부 경로가 /form/step2로 바뀌었어!"라고 알려주는 이벤트를 발생시킬 수 있습니다. 이를 통해 메인 앱은 팝업 앱 내부에서 어떤 일이 일어나는지 알 수 있습니다.

실제 구현: 팝업 앱의 '운전자' 바꿔치기

이제 팝업으로 띄울 마이크로프론트엔드 앱의 설정을 변경해 보겠습니다. Angular의 의존성 주입(Dependency Injection) 시스템을 이용해 기본 '운전자'를 우리의 '가짜 운전자'로 바꿔치기할 수 있습니다.

팝업 앱의 main.ts 또는 bootstrapApplication 설정에 아래 providers를 추가합니다.

// 팝업으로 사용할 Angular 앱의 main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { Location, LocationStrategy, SpyLocation } from '@angular/common';
import { MockLocationStrategy } from '@angular/common/testing'; // 👈 테스트용 모듈에서 가져옴
import { AppComponent } from './app/app.component';
import { routes } from './app/app.routes';

bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(routes),

    // 👇 이 부분이 반드시 정의되어야 합니다.
    { provide: Location, useClass: SpyLocation },
    { provide: LocationStrategy, useClass: MockLocationStrategy }
  ]
});

providers 설정은 어떻게 동작할까요?

  • { provide: LocationStrategy, useClass: MockLocationStrategy }: 이 코드는 "이 애플리케이션 안에서 누군가 LocationStrategy(기본 운전자)를 찾으면, 우리가 지정한 MockLocationStrategy(가짜 운전자)를 대신 줘!"라는 규칙을 정하는 것입니다.
  • { provide: Location, useClass: SpyLocation }: 마찬가지로, Location 서비스를 요청하면 SpyLocation을 제공하여 경로 변경을 감지할 수 있게 합니다.

이 설정을 통해 팝업 앱은 이제 브라우저의 주소창과 완전히 분리된, 자신만의 가상 라우팅 세계를 갖게 됩니다.

동작 과정 정리

  1. 사용자가 팝업 앱 내부의 <a routerLink="/form/step2"></a> 링크를 클릭합니다.
  2. 팝업 앱의 Router는 LocationStrategy에게 경로 변경을 요청합니다.
  3. 우리가 MockLocationStrategy를 '운전자'로 설정해두었기 때문에, 이 요청은 브라우저로 전달되지 않고 메모리상에서만 처리됩니다.
  4. SpyLocation은 이 내부 경로 변경을 감지합니다.
  5. 결과: 브라우저의 URL은 http://my-app.com/dashboard로 그대로 있고, 팝업 앱은 성공적으로 /form/step2 컴포넌트를 화면에 렌더링합니다.

결론

Angular 라우터의 내부 동작 방식을 활용하고, 본래 테스트 목적으로 만들어진 도구들을 창의적으로 사용하여 '한 페이지 속 여러 개의 독립적인 라우터'라는 복잡한 문제를 해결할 수 있었습니다.

이 방법은 마이크로프론트엔드 아키텍처에서 사용자 경험을 해치지 않으면서도 각 앱의 독립성을 보장하는 매우 강력한 솔루션이 될 수 있습니다.

물론, 프로덕션 환경에서 테스트용 라이브러리를 사용하는 것에 대한 유지보수 측면의 고민은 필요하지만, Angular의 유연성과 확장성을 엿볼 수 있는 훌륭한 사례입니다.

profile
Angular2+ Developer

0개의 댓글