【2】 Micro Front-ends : kt NexR 기술블로그 ‘21 테크리포트

생성일
2021/12/09 04:51
태그
2021년
상반기
테크리포트
kt NexR
기술블로그
글쓴이
josh.kim
속성
ktNexR_techreport_Micro Front-ends.pdf
속성 1

I. 서론

근대의 프론트엔드 기술은 과거에 비해, 시간이 흐를수록 점점 복잡한 기능을 요구하게 되었고, 이러한 대규모 엔터프라이즈 애플리케이션을 개발한다고 가정할 때, 각각의 기능을 개발하는 여러 팀이 필요하게 되었다. 이렇게 각기 다른 팀이 독립적으로 기능을 제공하게 되면, 이를 통합하기 위한 기술과 전략이 필요해졌고, Micro Frontends 아이디어를 도입하면 각 팀별 또는 업무단위에 대해 Backend + Frontend 개발 후 통합하는 이슈를 줄일 수 있다. Micro Frontends 라는 개념이 무엇인지? 적용가능할만한 것인지 알아보도록 한다.

II. 본론

Micro Front-ends란?

Micro Frontends 라는 용어는 2016년 말에 ThoughtWorks Technology Radar 에서 처음 등장했다. 이는 마이크로 서비스의 개념을 프론트엔드 세계로 확장한것으로, 오늘날에는 기능이 풍부하고 파워풀한 브라우저 애플리케이션, 즉 마이크로 서비스 아키텍처 위에 단일 페이지 앱(SPA)을 구축하는 것이 유행이다. 시간이 지남에 따라, 프론트엔드는 여러 분리된 팀에 의해 개발되는 경우가 자주 생기다보니 프론트엔드 계층은 커지고 유지 관리가 더 어려워지고 있다. 이것을 프론트엔드 모노리스(Frontend Monolith) 라고 부른다.

프론트엔드 모노리스 개념 (Monolith frontend)

이를 해결하고자 나온게 Micro Frontends로 이는 개별 팀들이 소유하고있는 웹사이트나 웹앱을 하나의 기능으로 보고, 그 기능(features)을 구성(composition) 하자는 방식의 아이디어다. 각 팀 별로 팀에서 담당하는 뚜렷한 비즈니스 영역 역할이 있을 것이다. 각 팀내 에서는 데이터베이스에서 사용자 인터페이스에 이르기까지 상호 기능(cross functional) 을 통해 end-to-end 기능을 개발한다.

수직화된 프론트엔드 통합 개념(Organisation in Verticlas)

이러한 아이디어는 새롭게 등장한 것이 아니다. Self-contained Systems 컨셉과 굉장히 공통점이 많다. 과거에는 이러한 접근 방식을 수직화(Verticalised) 된 시스템을 위한 Frontend Integration라는 이름으로 불리기도 했다.
마이크로 서비스 아키텍쳐와 마이크로 프론트엔드의 차이를 간략하게 보자면, 마이크로 서비스의 개별화된 기능 모듈이 각각의새로운 서비스로 동작한다면, 마이크로 프론트엔드는 최종적으로 고객이 사용하는 화면을 기준으로 하였을때, 각각의 개별화된 기능을 프론트엔드 내부에서의통합으로 이루어진다는 점이다.

Micro Frontends의 핵심 아이디어는?

기술 불가지론자(agnostic)

각 팀은 다른 팀과 조정하지 않고도 기술 스택을 선택하고 업그레이드할 수 있어야 한다. 즉 각각 팀마다 각기 다른 프론트엔드 기술 스택을 사용하여도, Custom Elements는 구현 세부 정보를 숨기면서 다른 사용자에게 중립적인 인터페이스를 제공하는 좋은 방법이다.

팀 코드 분리를 통한 자율적인 팀 개발

코드 베이스와, 배포 주기까지 모두 분리함으로써 얻는 커다란 이점중의 하나는, 그렇게 이루어진 팀은 고객에게 가치를 제공하는 대 있어서 필요한 모든것을 제공한다는 주인의식을 갖게 한다는 점이다. 이를 위해서는 팀을 기술적 역량이 아니라, 비지니스 기능 중심으로 구성해야 한다. 이렇게 만들어진 팀은 고객이 사용하는 화면을 기반으로 제품을 분할하여 개발이 가능 할 수 있게 되며, style이나 form들 validation등을다른 팀과 신경쓰지 않아도 되기에 작업에 있어서 응집력이 높아지게 한다. 하지만 모든 팀이 동일한 프레임워크를 사용하더라도 런타임은 공유하지 말아야 한다. 공유 상태(shared state) 또는 전역 변수에 의존하지 말고 자체 독립 앱을 구축 하자.

팀 접두사 설정

명명 규칙(naming conventions)을 유지하는것은 중요하다. 충돌을 피하고 소유권을 명확히 하기 위해 CSS, Events, Local Storage,Cookies에 namespace를 사용하자.

Custom APIs보다 기본 브라우저 기능 선호

글로벌 Pub/Sub 시스템을 구축하는 대신 통신을 위한 브라우저 이벤트(Browser Events for communication)를 사용하자. 만약 당신이 정말로 크로스 팀 API를 구축해야 한다면, 가능한 간단하게 하도록 노력 하자.

탄력있는 사이트 구축

JavaScript에서 에러가 나거나 아직 실행되지 않은 경우에도 기능(feature) 사용이 가능 해야 한다. 눈에 띄는 성능 향상을 위해 범용 렌더링(Universal Rendering)과 점진적 향상(Progressive Enhancement)을 사용하자.

독립적인 개발 및 배포

마이크로 서비스 처럼 독립적인 배포는 Micro Frontends의 중요한 요소이다. 이는 위험을 줄이고 각각의 배포 사이즈 또한 줄어들 수 있도록 한다. 기존의 방식으로 개발을 진행하여 만약 다른팀이 문제가 있는 코드를 마스터 브랜치에 push 하였다 하더라도 커다란 문제가 되지는 않고,유지 배포하는 팀에 달려있게 된다.

Micro Frontends 장단점을 알아보자.

장점
● 작고, 응집력 있고 유지보수성을 가지는 코드베이스를 가질 수 있다. (Simple, decoupled codebase) ● 분리배포가 용이하고, 자율적인 팀 조직운영이 수월해진다. (Independent deployment, Autonomous teams) ● 프론트앤드 개발을 점진적 업그레이드 또는 재작성이 수월해진다. (Incremental upgrades)
단점
● 전체 배포 번들 사이즈가 커질 수 있다. (Payload size) ● 서로간의 개발 환경의 차이로 복잡도가 올라간다. (Environment differences) ● 운영 및 거버넌스도 당연히 복잡해진다. (Operational governance complexity)

Micro frontends를 활용한 분리와 통합 예제 웹페이지

분리
다음과 같이 고객이 음식 배달을 주문하는 웹 페이지를 개발한다고 하자. 언뜻 보기에는 간단해 보이는 화면 이지만, 그 내부를 들여다보면 엄청 자세한 부분이 복잡하게 얽혀있다.
고객들이 찾아낼 수 있는 렌딩 페이지가 있어야 한다. 해당 페이지는 가격이나 요리 그외 고객이 원하는 모든것들을 미리 알아보게함으로써 검색되기 쉬워야 한다.
각각의 레스토랑은 메뉴를 표시하고, 고객으로 하여금 어떤 음식을 먹고 싶은지 할인받을수 있는지 또는 기타 특별한 요청사항이있는지 알아낼 수 있도록 하여야 한다.
고객들은 그들이 주문한 내역과, 배달 추적, 그리고 고객에맞는 결제시스템을 확인할 수 있는 마이페이지가 있어야 한다.
각각의 페이지에는 충분한 복잡성이 있고, 이러한 복잡성은 각각에 맞추어 최적화된 팀을 이룰 수 있다. 이렇게 이루어진 각 팀은 다른팀과의 마찰이나 협업에 대한 걱정없이 해당 페이지를 독립적으로 구현하고 개발, 테스트, 배포 그리고 유지시킨다. 고객의 입장에서 보면 문제가 없는 일관된 웹페이지로 보이게 된다.

통합

필요한 단위 애플리케이션을 잘개 쪼갠만큼 통합하는 방법도 중요하고, 이를 어떻게 통합할것인가에 대한 부분이 고려되어야 한다. 통합을 진행할 때는 각 화면을 조합하는 컨테이너 애플리케이션이 있고, 그 하부에 들어가는 단위 애플리케이션이 존재하는 방식으로 진행한다. 이를 통합하는 컨테이너 애플리케이션의 경우에는 아래와 같은것을 고려해야 한다.
header와 footer와 같은 공통 페이지를 렌더링한다.
인증과 네비게이션 등과 같은 요소들에 대한 것들에 대한 처리한다.
Micro Frontends들을 페이지에 불러오고, 언제 어디에서 렌더링 되야할지를 결정한다.

Micro-frontend의 통합 과 주요 방법들

Mirco Frontend 통합할 때 몇가지 고려사항

UI 스타일 일관성
UI Component Library를 만들어 대응한다.
한번에 만들지 말고, 중복코드가 발생하는 지점에서 만들것
코드 일관성을 유지하는 팀이 수행한다.
어플리케이션 통신은 Custom events를 사용한다.
커스텀 이벤트를 위해 PubSubJS를 고려해 볼것.
호출시 URL 라우팅에 넘기기
백앤드 호출 API 구성 - BFF(Backend for Frontend Pattern) 패턴으로 프론트앤드 전용 API를 갖는다. -별도의 데이터베이스를 가질 수도 있다. - 로그인은 인증 정보는 각각 컴포넌트를 통합하는 Container가 소유한다.

server-side template 통합

각 서버로 html 템플릿을 요청하고, 최종 응답서버에서 각 템플릿을 조합해서 응답을 보내는 방식. 서버측에서 최종 화면을 조합한다.
Nginx를 사용하여 $page 변수를 URL에 맞게 매칭하여 서버에서 전달해주는 소스 예시
가장 기본적인 서버통합 방법으로, 이와같은 예제를 보면 Micro Frontends가 그렇게 특별하게 새로운 기술은 아니라는것을 깨닫게 될 것이다. 또 그렇게 복잡할 필요도 없다
빌드타임 통합
단위 애플리케이션을 패키지로 배포하고, package.json에 명시한 후 컨테이너 애플리케이션에서 import하여 사용하는 방법
{ "name":"@feed-me/container", "version":"1.0.0", "description": "A food delivery web app", "dependencies": { "@feed-me/browse-restaurants":"^1.2.3", "@feed-me/order-food":"^4.5.6", "@feed-me/user-profile":"^7.8.9" } }
각 애플리케이션에 대한 런타임 대응이 안된다.
애플리케이션을 릴리즈하고 최종 애플리케이션에서 컴파일해야 한다.

iframe 통합

가장 전통적인 방식이면서 쉬운 방식이다.
애플리케이션 통합의 유연성이 떨어진다.
routing, history, deep-link같은 것이 복잡해질 수 있다.
컨테이너 애플리케이션과 iframe에 들어가는 단위 애플리케이션간의 통신규약도 필요하다.
UX가 iframe안에 갇히기 때문에 어색한 UI 표현을 가질 수 있다.

Javascript를 통한 run-time 통합

각각의 소스를 js파일로 생성하여 컨테이너 파일에서 로딩을 한뒤 당장 렌더링 하지는 않고 각각의 애플리케이션을 진입 시점에 렌더링하는 방식이다.
iframe과 달리 유연한 통합이 가능하다. 현실적으로 가장 많이 사용하는 방식이다.
컨테이너 애플리케이션을 단위 애플리케이션 번들을 <script> 태그를 통합 다운로드 받고 약속된 초기화 메소드를 호출한다.
클라이언트측에서 (브라우져) 통합한다.

Custom Element를 활용한 Web Components들의 run-time 통합

위의 javascript를 통한 run-time 통합과 비슷하지만, 다른점이 있다면 전역함수를 container에서 호출하는것과는 달리 custom element를사용한다는 점이다. custom element에 관해서는 아래에서 좀 더 자세히 알아보도록 한다.
HTML 커스텀 엘리먼트를 통한 통합방법, static, runtime 통합 둘 다 가능함.
Javascript를 통한 런타임 통합과 유사하지만 "The web component way"를 지향한다.
클라이언트측에서 (브라우져) 통합한다.

Custom Element란?

custom Elements는 브라우저로 하여금 새로운 tag를 가르치고 정의 하여 전역적으로 사용할 수 있게 하는 웹표준 기술이다. customElements.define() 에 tag 이름을 설정하고, 이를 HTMLElement 를 extends 한 JavaScript class로 생성하여 사용한다. custom Elements는 상호운용성 측면에서 브라우저의 통합에 훌륭한 기본 요소로, 각 팀은 선택한 웹 기술(React, Vue 등등)을 사용하여컴포넌트를 구축하고 이를 custom elements에 넣는 방식으로 활용한다. 알고보면 DOM은 일종의 API다. 특정 element(tag-name, attributes & events)의 DOM specification은 다른 팀에게 계약(contract) 또는 공개 API 역할을 한다. 구현 방법을 알 필요 없이 컴포넌트와 기능을 사용할 수 있다는 것이 장점으로 단지 DOM과의 상호작용을 할 수 있으면 된다. 그러나 custom Elements 만으로는 모든 요구 사항을 해결할 수 없다. 점진적 향상(Progressive Enhancement), 범용 렌더링(UniversalRendering) 또는 라우팅 문제를 해결하기 위해서는 추가적인 기술이 필요한 편이다.
ex) 아래와 같이 HTML표준에 속하지 않은 tag를 만들어서 사용한다.
<order-minicart></order-minicart>
Custom Element를 class로 만드는 예시
아래와 같이 BlueBuy라는 버튼을 만든다고 가정할때 아래와같이 class로 custom element를 정의 할 수 있다.
이제 우리는 <blue-buy>라는 tag를 사용할 수 있게 된다. 여기서 중요한건 connectedCallback과 disconnectedCallback와 같은 life cycle이다. 브라우저가 blue-buy 태그를 만날 때마다 connectedCallback가 호출된며 여기서 this는 custom element의 root DOM 노드에 대한 참조다. innerHTML 또는 getAttribute()와 같이 표준 DOM element의 모든 properties와 methods를 사용할 수 있다.
Custom Element의 lifecycle callbacks
위에서 알아본 것처럼 custom element는 각 단계에 해당하는 life cycle을 갖고 있다. vue, react와 같은 프레임워크에 익숙하신 분이라면해당 component 내부에서 각각 여러 라이프 사이클이 존재한다는 것을 알고 있을것이다. 이와 동일하게 custom하게 생성한 element에는 각 life cycle에 해당하는 callback을 갖고 있어 이를 활용할 수 있다.
connectedCallback: element가 처음 document's DOM에 연결될 때 실행
disconnectedCallback: element가 처음 document's DOM에 연결이 해제될 때 실행
adoptedCallback: element가 처음 새로운 document로 옮겨질때 실행
attributeChangedCallback: custom element의 attributes들이 추가, 삭제, 변경 될때 실행
BFF 패턴을 통한 Front-end와 Back-end의 결합
BFF 패턴은 원래 각 front-end 채널(웹, 모바일 등)을 위한 전용 back-end를 의미하지만, 각 Micro Frontends와 어울리는 back-end와 같은개념으로도 쉽게 확장될 수 있다. 물론 Micro Frontends가 통신하는 API가 하나가 있고, 이 API가 안정적 이라면 BFF를 구축하는것도 별 의미가 없지만, 중요한점은 MicroFrontends 를 구축하는 팀이 다른팀을 위해서 소스를 변경하는 대 까지 기다릴 필요가 없다는 것이다. 만약 Micro Frontends를 full-stack팀으로 개발하게 된다면 매우 큰 시너지 효과를 발휘 할것이라고 본다.

III. 결론

Micro Frontends는 어디서 갑자기 나타난 생소한 개념이 아니다. 넓은 개념으로 본다면 사실 우리는 이미 오래전부터 이러한 방법을 사용하고 있었고 근대에 이르러서야 통합하는 방법이 다변화 되었을 뿐이다. 프로젝트의 규모에 따라 적용방법이 달라질 수는 있다고 보며, 억지로 중소 규모에서 custom element를 사용한 웹컴포넌트 방식의 결합을 굳이 사용할 필요는 없다고 생각한다. 이는 앞서 말한 단점과 같이 복잡성을 증가시키고, 소스양을 늘어나게 하며, 각각 비지니스 로직을 담당하는 팀은 물론 container를 관리,운영해야하는 팀도 필요해지기 때문이다. 아직까지는 특정 SPA 프레임워크를 결정하고 component 단위로 프론트엔드를 설계하는 방식이 가장 효율적이라고 생각한다. 특정 SPA를 활용하는 방법은 component그 자체가 각각의 Micro Frontends에 속하고, 이와 같은 설계방식에 익숙해지면 여러 전략적 이점을 취할 수도 있기 때문이다. 하지만 규모가 너무 커져서 여러개의 비지니스 기능을 하나로 묶어서 제공해야하는, 엔터프라이즈 급 애플리케이션을 만들어야하는 상황에서, 이미 만들어진 비지니스들이 각각 다른 SPA로 만들어져 있다면, 그리고 기존의 비지니스 레거시 코드들을 새롭게 리뉴얼 할 사정이 안된다면, 그땐 custom element를 활용한 웹컴포넌트 방식의 통합을고려해볼 만하다고 생각한다.

IV. 후속연구/차후계획

지금까지 알아 본 바로는 custom elements 기술을 활용하여 Front-end가 얼마나 확장이 가능한지 잘 알게 되었다. Angular, Vue, React같은 SPA 프레임워크도 결국엔 DOM fragment를 활용한 shadow DOM 기술의 응용이고, 이와 같은 기술들이 언젠가HTML 웹 표준 스펙에 SPA가 흡수되어 기본지원이 될 가능성도 있다. 그 때가 되면 SPA라고 불리우는 애플리케이션은 custom element와 shadow DOM을 활용하여 하나로 통일된 프론트엔드단 개발형태가될 가능성이 크다. 진화하는 HTML에 발맞추어 custom element를 활용하는 기술에 대해서는 더 연구할 가치가 있다고 본다.
【2】 Micro Front-ends : kt NexR 기술블로그 ‘21 테크리포트
Reference
본 기술블로그에 게재되는 모든 컨텐츠의 저작권은 케이티넥스알(kt NexR)에서 가지고 있으며, 동의 없는 컨텐츠 수정 및 무단 복제는 금하고 있습니다. 컨텐츠(글/사진/영상 등)를 공유하실 경우 반드시 출처를 밝혀주시기 바랍니다. Copyright(c) 2021 kt NexR, Inc. All Rights Reserved.