본문 바로가기

번역글/Medium

[번역] 마이크로 프론트 아키텍쳐에 대하여

https://levelup.gitconnected.com/micro-frontend-architecture-b14b3a2c39a0

 

Micro Frontend Architecture

As web applications grow in complexity, teams seek scalable, modular approaches to frontend development. One such approach, Micro Frontend…

levelup.gitconnected.com

Rohit S 님의 24.09.16일자 포스트를 번역한 글입니다.

프론트엔드의 진화

 

 

웹 애플리케이션의 복잡성이 증가함에 따라 팀은 확장 가능한 모듈식 프런트엔드 개발 접근 방식을 모색하고 있습니다. 이러한 접근 방식 중 하나인 마이크로 프론트엔드 아키텍처는 백엔드 시스템을 혁신한 마이크로서비스와 유사하게 모놀리식 프론트엔드를 독립적으로 개발 및 배포되는 소규모 단위로 세분화할 수 있게 해줍니다. 이 블로그에서는 프론트엔드 개발의 진화, 마이크로 프론트엔드의 원리, 마이크로 프론트엔드의 이점, 모듈 페더레이션 및 라우팅과 같은 주요 개념이 마이크로 프론트엔드에서 어떻게 관리되는지 살펴보겠습니다.

 

프론트엔드 개발의 진화

 

웹 개발 초창기에는 프론트엔드 애플리케이션이 비교적 단순했습니다. 일반적으로 개발자는 HTML, CSS, 약간의 JavaScript를 사용하여 정적인 웹사이트를 구축했습니다. 하지만 동적이고 풍부한 웹 경험에 대한 수요가 증가함에 따라 웹 애플리케이션의 복잡성도 함께 증가했습니다.

Angular, React, Vue.js 같은 프레임워크의 등장은 보다 상호작용적이고 데이터 중심의 애플리케이션을 구축하는 도구를 제공함으로써 큰 도약을 가져왔죠. 그러나 이러한 프론트엔드 애플리케이션은 종종 모놀리식 아키텍처로 개발되었는데, 팀이 확장되고 기능 복잡성이 증가함에 따라 유지 관리가 어려워지는 대규모의 긴밀하게 결합된 코드베이스였습니다.

이러한 문제를 해결하기 위해 개발자들은 백엔드에서 마이크로서비스로 전환하여 모놀리스를 독립적으로 배포 가능한 소규모 서비스로 나누었습니다. 백엔드 아키텍처의 확장성이 높아지면서 동일한 원칙을 프론트엔드에도 적용할 수 있다는 것이 분명해졌습니다. 마이크로 프론트엔드 아키텍처.

 

마이크로 프론트엔드 아키텍처란 무엇인가요?

 

마이크로 프론트엔드는 마이크로서비스의 프론트엔드에 대응하는 개념입니다. 마이크로 서비스가 백엔드 모놀리스를 느슨하게 결합된 서비스로 분해하는 것처럼, 마이크로 프론트엔드는 대규모 웹 애플리케이션을 더 작고 독립적인 조각으로 분해하여 서로 원활하게 작동하여 완전한 앱을 형성합니다.

마이크로 프론트엔드를 사용하면 사용자 인터페이스(UI)의 각 부분을 개별적으로 개발 및 유지 관리할 수 있습니다. 팀은 자율적으로 작업할 수 있으므로 더 빠른 릴리스, 더 나은 확장성 및 향상된 성능을 보장할 수 있습니다.

 

마이크로 프론트엔드 아키텍처를 사용해야 하는 이유

 

  1. 독립적인 개발 및 배포: 각 마이크로 프론트엔드는 독립적인 모듈로, 다른 팀에 영향을 주지 않고 기능을 개발, 테스트 및 배포할 수 있습니다.
  2. 기술 불가지론: 서로 다른 프레임워크(예: 한 부분에는 React, 다른 부분에는 Vue.js)를 사용하여 서로 다른 마이크로 프론트엔드를 구축할 수 있습니다.
  3. 고립된 팀: 각 팀은 경계와 책임이 잘 정의된 앱의 특정 기능이나 섹션을 관리합니다.
  4. 원활한 사용자 경험: 마이크로 프론트엔드는 개별적으로 개발되었지만, 사용자는 이를 하나의 일관된 애플리케이션으로 경험합니다.

예시: 넷플릭스

마이크로 프론트엔드 아키텍처의 실제 사례는 Netflix입니다. 이 웹사이트는 홈페이지, 검색, 사용자 프로필 설정 등 여러 섹션으로 나뉘어 있으며, 각 섹션은 별도의 마이크로 프론트엔드로 구동됩니다. 이 접근 방식은 전체 웹사이트에 영향을 주지 않고 각 섹션을 독립적으로 캐시하고 필요에 따라 업데이트할 수 있기 때문에 넷플릭스가 로드 시간을 단축하는 데 도움이 됩니다. 또한 하나의 마이크로 프론트엔드를 변경해도 다른 마이크로 프론트엔드가 중단되지 않으므로 개발 및 릴리스 주기를 빠르게 진행할 수 있습니다.

 

마이크로 프론트엔드 대 마이크로 서비스

 

마이크로서비스는 백엔드 기능을 독립적인 서비스로 세분화하는 데 중점을 두는 반면, 마이크로 프론트엔드는 이 개념을 사용자 인터페이스에 적용합니다.

  • 마이크로서비스는 백엔드 기능(데이터베이스 운영, API)을 처리합니다.
  • 마이크로 프론트엔드는 사용자 상호 작용 및 프레젠테이션 계층을 처리하는 UI를 관리합니다.

이러한 차이에도 불구하고 두 가지 모두 공통된 목표를 공유합니다:

  • 자유로운 결합: 각 마이크로서비스/마이크로 프론트엔드는 독립적으로 작동합니다.
  • 자율성: 팀은 다른 팀과 조율할 필요 없이 개발 및 배포할 수 있습니다.
  • 확장성: 각 서비스 또는 프론트엔드는 사용자 수요를 충족하기 위해 독립적으로 확장할 수 있습니다.

 

마이크로 프론트엔드 - 통합 기술:

 

  1. 자산 저장소: 중앙 저장소에 공유 자산(예: CSS, JavaScript)을 저장하여 마이크로 프론트엔드가 애플리케이션 전체에서 공통 자산을 재사용하고 공유할 수 있도록 합니다.
  2. 모듈 페더레이션: 이 웹팩 5 기능을 사용하면 마이크로 프론트엔드가 런타임에 모듈을 공유하고 동적으로 로드할 수 있으므로 독립적인 마이크로 프론트엔드가 서로 상호 작용할 수 있습니다.
  3. iFrame 및 웹 컴포넌트: 진정한 마이크로 프론트엔드 기술은 아니지만 이러한 접근 방식은 특히 레거시 시스템에 캡슐화 및 격리를 제공합니다.

 

모듈 페더레이션에 대해 자세히 알아보기

 

모듈 페더레이션은 마이크로 프론트엔드가 런타임에 자바스크립트 모듈을 서로 동적으로 공유할 수 있게 해주는 webpack 5의 강력한 기능입니다. 이 개념은 종속성 공유, 중복성 감소, 상호운용성 개선 등 마이크로 프론트엔드 아키텍처의 주요 과제를 해결합니다.

작동 방식:

  • 각 마이크로 프론트엔드는 모듈을 노출하고 다른 마이크로 프론트엔드의 모듈을 사용할 수 있습니다.
  • 모듈은 런타임에 비동기적으로 로드되므로 애플리케이션의 초기 로드 시간이 개선됩니다.
  • React와 같은 공유 종속성은 한 번 로드된 후 여러 마이크로 프론트엔드에서 재사용됩니다.

장점:

  1. 동적 모듈 로드: 마이크로 프런트엔드는 필요에 따라 모듈을 동적으로 로드하여 초기 로드 시간을 줄이고 성능을 향상시킬 수 있습니다.
  2. 분산형 아키텍처: 각 팀은 다른 팀과 조율할 필요 없이 자체 모듈을 독립적으로 관리합니다.
  3. 공유 종속성: 종속성을 마이크로 프론트엔드 간에 공유하여 중복을 최소화하고 앱 전체에서 일관성을 유지할 수 있습니다.

 

React와 Webpack을 사용한 간단한 구현

 

Webpack의 모듈 페더레이션을 사용하여 React에서 마이크로 프론트엔드가 어떻게 작동하는지 시연해 보겠습니다. 간단한 앱 두 개를 만들어 보겠습니다:

  • 호스트 앱: 기본 애플리케이션입니다.
  • 원격 앱: 호스트 앱이 동적으로 로드할 마이크로 프론트엔드입니다.

1단계: 원격 앱 설정하기

 

  1. HelloWorld 컴포넌트를 생성합니다(src/components/HelloWorld.js).
const HelloWorld = () => <h1>Hello from the Micro Frontend!</h1>;
export default HelloWorld;

 

2. webpack.config.js를 업데이트합니다:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  mode: 'development',
  devServer: { port: 3001 },
  plugins: [
    new ModuleFederationPlugin({
      name: 'remoteApp',
      filename: 'remoteEntry.js',
      exposes: { './HelloWorld': './src/components/HelloWorld' },
      shared: { react: { singleton: true }, 'react-dom': { singleton: true } },
    }),
    new HtmlWebpackPlugin({ template: './public/index.html' }),
  ],
};

 

3. 원격 앱 실행

npm start

 

2단계: 호스트 앱 설정

  1. 종속 요소를 설치하고 Webpack을 구성합니다:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  mode: 'development',
  devServer: { port: 3000 },
  plugins: [
    new ModuleFederationPlugin({
      name: 'hostApp',
      remotes: { remoteApp: 'remoteApp@http://localhost:3001/remoteEntry.js' },
      shared: { react: { singleton: true }, 'react-dom': { singleton: true } },
    }),
    new HtmlWebpackPlugin({ template: './public/index.html' }),
  ],
};

 

2. src/App.js에서 원격 컴포넌트를 로드합니다:

const HelloWorld = React.lazy(() => import('remoteApp/HelloWorld'));

function App() {
  return (
    <div>
      <h1>Host App</h1>
      <React.Suspense fallback="Loading...">
        <HelloWorld />
      </React.Suspense>
    </div>
  );
}
export default App;

 

3. 호스트 앱을 실행합니다:

npm start

적용 방법

이 예시는 모듈 페더레이션을 통해 앱(호스트 등)이 런타임에 마이크로 프론트엔드 모듈(예: HelloWorld 구성 요소)을 동적으로 로드하고 통합할 수 있도록 함으로써 프론트엔드 모놀리스를 무너뜨리는 방법을 보여 줍니다. 이를 통해 팀을 분리하고 독립적인 배포를 가능하게 하며 유연성과 재사용성을 유지하면서 확장 가능한 모듈식 프런트엔드 아키텍처를 구축할 수 있습니다.

이러한 경량 모듈식 접근 방식은 마이크로서비스가 백엔드 개발에 혁신을 가져온 방식을 반영합니다. 동일한 원칙이 프론트엔드에도 적용되어 대규모 애플리케이션 전반에서 성능, 개발 속도 및 확장성을 개선합니다.

 

마이크로 프론트엔드 아키텍처에서 라우팅 처리하기

 

라우팅은 모든 웹 애플리케이션의 중요한 측면이며, 마이크로 프론트엔드에서 라우팅을 관리하려면 원활한 경험을 보장하기 위해 특별한 주의가 필요합니다. 라우팅을 처리하는 두 가지 일반적인 접근 방식이 있습니다:

  1. 단일 라우팅 레이어(셸): 중앙 '셸' 애플리케이션이 모든 라우팅을 관리합니다. 각 마이크로 프론트엔드의 경로를 인식하고 필요한 경우 적절한 프론트엔드에 탐색을 위임합니다.
  2. 독립 라우팅: 각 마이크로 프론트엔드가 내부적으로 자체 라우팅을 관리하므로 자율성이 향상됩니다. 셸 애플리케이션은 여전히 최상위 경로를 관리하지만 더 깊은 경로는 각 마이크로 프론트엔드에 위임할 수 있습니다.

 

마이크로 프론트엔드에서 컨텍스트 및 상태 공유

 

마이크로 프론트엔드 아키텍처의 과제 중 하나는 여러 마이크로 프론트엔드에서 상태와 컨텍스트를 공유하는 것입니다. 다음은 이를 관리하기 위한 몇 가지 전략입니다:

  1. 글로벌 상태 관리: 마이크로 프런트엔드 전반에서 작동하는 상태 관리 도구(예: Redux, Zustand)를 사용하여 글로벌 컨텍스트를 공유할 수 있도록 합니다.
  2. 이벤트 및 게시/서브 시스템: 마이크로 프론트엔드는 이벤트 기반 시스템 또는 게시/구독 패턴을 통해 서로 통신할 수 있으므로 분리된 상호 작용 모델을 사용할 수 있습니다.
  3. 공유 서비스: 공유 서비스 계층(예: API 게이트웨이 또는 GraphQL)을 사용하여 모든 마이크로 프런트엔드에 공통 기능을 제공합니다.

 

마이크로 프론트엔드 아키텍처를 사용해야 하는 경우

 

마이크로 프론트엔드는 모듈화 및 독립적인 개발이 필요한 크고 복잡한 애플리케이션에 가장 적합합니다. 다음은 마이크로 프론트엔드가 빛을 발하는 주요 시나리오입니다:

  1. 대규모의 복잡한 애플리케이션: 마이크로 프론트엔드는 대규모 애플리케이션을 관리하기 쉬운 부분으로 분할하여 조직을 개선하고 빌드 시간을 단축하는 데 도움이 됩니다.
  2. 복수의 팀: 팀은 앱의 여러 부분에서 독립적으로 작업할 수 있으므로 병렬 개발 및 독립 배포가 가능합니다.
  3. 독립 배포: 마이크로 프론트엔드를 사용하면 전체 앱을 다시 배포하지 않고도 특정 기능을 업데이트할 수 있으므로 배포 위험이 줄어듭니다.
  4. 다양한 기술 스택: 앱의 여러 부분에 서로 다른 프레임워크(예: React, Vue)를 사용할 수 있으므로 기술 선택의 유연성을 확보할 수 있습니다.
  5. 확장성: 마이크로 프론트엔드는 앱의 각 부분이 분리되어 있고 독립적으로 성장할 수 있기 때문에 확장 및 유지 관리가 더 쉽습니다.
  6. 레거시 현대화: 레거시 시스템을 전면 재작성하지 않고 점진적으로 교체하여 최신 기술로 점진적으로 전환할 수 있습니다.
  7. 성능 개선: 앱의 여러 부분을 캐싱하거나 지연 로딩하여 로드 시간을 최적화합니다.

소규모 앱이나 글로벌 상태 공유가 필요한 프로젝트에 마이크로 프론트엔드를 사용하면 복잡성이 증가하므로 노력할 가치가 없을 수 있습니다.

결론

마이크로 프론트엔드 아키텍처는 최신 웹 애플리케이션을 위한 자연스러운 진화이며, 이를 통해 팀은 확장 가능하고 유지 관리가 가능한 모듈식 프론트엔드를 구축할 수 있습니다. 프론트엔드를 독립적으로 배포 가능한 단위로 분할함으로써 팀은 자율적으로 작업하고 종속성을 보다 효율적으로 관리하며 보다 유연한 아키텍처를 구축할 수 있습니다.

모듈 페더레이션과 같은 도구와 신중한 라우팅 및 상태 관리 전략을 갖춘 마이크로 프론트엔드는 모놀리식 애플리케이션의 한계를 극복하고자 하는 개발자에게 흥미로운 길을 제시합니다. 대규모 웹 앱을 개발하든 이제 막 프론트엔드 개발을 시작하든 마이크로 프론트엔드는 보다 확장 가능하고 유지 관리가 용이한 시스템을 구축할 수 있는 방법을 제공합니다.