마이크로 프론트엔드의 문제점 (한국어)

Ina·2023년 6월 3일
5

문서 번역

목록 보기
4/4
post-thumbnail

본 포스팅은 "Problems with Micro-frontends" by Steven Lemon on Medium을 우리말로 번역한 글입니다. 이 아티클은 직접 마이크로 프론트엔드 구축한 경험을 통해 경험한 문제점들을 이야기하며, 단순히 애플리케이션의 규모를 줄이는 것에 집중해 마이크로 프론트엔드 설계를 도입할 것이 아니라 실제 겪고 있는 문제를 잘 정의하여 문제 해결에 집중하고, 설계 단계에서 미리 면밀하게 조사하고 계획하는 것이 중요하다는 점을 역설하고 있습니다. 마이크로 프론트엔드에 대해 기본적인 개념을 이해하고 있고, 도입에 앞서 당면할 수 있는 문제점들을 미리 조사하고 있는 분들에게 도움이 될 만한 글입니다.

우리 팀은 지난 6개월 동안 마이크로 프론트엔드 접근 방식을 사용하여 애플리케이션을 재작성해 왔습니다. 현재 마이크로 프론트엔드가 얼마나 인기가 있는지를 고려할 때, 우리의 경험과 우리가 배운 교훈을 공유하고 싶었습니다.

마이크로 프론트엔드는 환상적인 도구가 될 수 있지만, 만병통치약은 아닙니다. 프로젝트, 팀, 비즈니스의 구조에 따라 마이크로 프론트엔드의 이점을 충분히 활용하지 못할 수도 있습니다. 더 나쁜 경우 마이크로 프론트엔드는 애플리케이션의 아키텍처를 훼손하고 팀의 제공 능력을 저해할 수 있습니다. 저희 팀의 경우 마이크로 프론트엔드가 특히 적합하지 않은 것으로 판명되었으며, 마이크로 프론트엔드 접근 방식이 최선의 선택이 아닌 경우를 보여주는 예시였습니다.

🔹 마이크로 프론트엔드의 (잠재적인) 이점

이 경험은 제가 마이크로 프론트엔드 접근 방식을 접한 두 번째 사례였습니다. 이전 직장에서 쉘 안드로이드 애플리케이션을 유지 관리하는 팀과 쉘 애플리케이션 내에서 각각 별도의 웹뷰를 담당하는 4개의 팀이 있었습니다. 각 팀은 완전히 별개의 비즈니스 문제를 해결했으며, 마이크로 프론트엔드가 제공하는 자율성 덕분에 각 팀이 스택 전체를 소유할 수 있었습니다. 각 팀은 독립적으로 개발 및 릴리스할 수 있었고 공유 라이브러리나 공유 워크플로를 건드리지 않는 한 서로에게 영향을 미칠까 걱정할 필요가 없었습니다. 셸과 마이크로 프론트엔드 간의 분리를 유지하려면 노력이 필요했지만, 각 팀에게 제공되는 자유와 유연성 덕분에 처음에는 그만한 가치가 있었습니다.

하지만 제가 회사를 떠날 무렵에는 균열이 보이기 시작했습니다. 공유 라이브러리는 골칫거리가 되어 결국 각 팀이 복사본을 만들게 되었습니다. 앱 간의 워크플로우와 커뮤니케이션은 끊임없이 어려움을 겪게 되었습니다. 한 마이크로 프론트엔드는 웹뷰라는 성능 제약으로 인해 어려움을 겪고 있었습니다. 셸과 자식 간의 연결 수가 증가함에 따라 셸에 업데이트를 릴리스하는 데 많은 시간이 소요되었습니다.

1. 독립적인 팀

마이크로 프론트엔드와 마이크로 서비스는 팀을 분리하고 코드를 분리하기 위한 것으로, 팀이 독립적으로 작업할 수 있도록 도와주는 훌륭한 도구가 될 수 있습니다. 각 팀은 애플리케이션의 수직적 조각에 대한 완전한 소유권을 가지며 자신의 도메인을 전문화할 수 있습니다. 다른 팀의 우발적인 간섭에 대한 걱정을 덜 수 있고 팀 간 조율의 필요성을 줄일 수 있습니다. 마이크로 프론트엔드를 사용하면 콘웨이의 법칙* ( 👩‍🏫 조직이 자체 커뮤니케이션 구조를 반영하는 시스템을 설계한다는 격언)을 적용하여 애플리케이션의 구조가 팀의 구조를 따르도록 할 수 있습니다.

마이크로 프런트엔드는 독립적인 팀의 자율성을 높여주지만 서로 연결된 팀에게는 많은 것을 제공하지 않습니다. 개발 팀의 규모가 너무 작거나, 도메인이 너무 상호 연결되어 있거나, 들어오는 작업이 비즈니스 라인 간에 균등하게 분할되지 않을 수 있습니다. 마이크로 프론트엔드를 사용하지만 팀에 연결된 서비스 및 도메인이 없는 경우 아키텍처는 분산되어 있지만 팀은 분산되어 있지 않은 분산형 모놀리스를 구축하게 될 수 있습니다.

분산 모놀리스 아키텍처에서는 마이크로 프론트엔드가 있지만 팀에 할당되지 않습니다. 마이크로 프론트엔드를 동시에 업데이트하려고 하면 팀이 서로 충돌하게 됩니다.
저희는 총 12명의 개발자로 구성된 두 개의 소규모 팀입니다. 최근 백엔드 서비스를 마이크로서비스로 전환하려는 움직임에 대해 이전 글에서 자세히 설명한 바 있습니다. 마이크로서비스가 모든 팀과 프로젝트에 가치를 더하는 만병통치약은 아닙니다. 마이크로 서비스가 가치가 없는 환경에서는 마이크로 프론트엔드에도 동일한 이유가 적용될 것입니다. 이미 한 가지가 유용하지 않다는 것을 알게 되었다면 다른 것의 이점을 누릴 가능성이 낮습니다.

2. 코드 구성

이론적으로 마이크로 프론트엔드는 코드베이스의 구조를 개선하는 데 도움이 될 수 있습니다. 각 마이크로 프론트엔드는 애플리케이션의 더 작고 집중된 부분을 포함합니다. 그렇다고 해서 모놀리식 애플리케이션이 구조가 잘 짜여져 있지 않다고 생각하는 것은 잘못된 생각이며, 몇 가지 작은 조정만으로도 애플리케이션을 완전히 분리하는 것만큼이나 많은 이점을 얻을 수 있습니다. 저희 팀은 최근 마이크로서비스로의 마이그레이션을 취소한 후 백엔드 서비스의 구조를 개선하는 데 약간의 시간을 투자했습니다. 개선된 구조 덕분에 마이크로서비스로 인한 장단점이나 복잡성 없이 훨씬 깔끔한 애플리케이션을 만들 수 있었습니다.

3. 릴리스 독립성

마이크로 프론트엔드를 사용하면 프론트엔드의 일부를 독립적으로 릴리스할 수 있습니다. 모든 것을 다시 배포하지 않고 변경된 부분만 배포할 수 있습니다. 다른 팀과 조율하거나 회사 전체의 릴리스 주기에 맞출 필요 없이 필요할 때 릴리스할 수 있도록 팀의 역량을 강화할 수 있습니다. 다른 팀의 작업에 영향을 주지 않고 잘못된 릴리스를 롤백할 수 있습니다.

이러한 모든 프런트엔드에는 더 큰 기능의 부분적인 구현이 포함되어 있으므로 어느 것도 독립적으로 릴리스할 수 없습니다.

하지만 곧 다루겠지만 마이크로 프론트엔드 간에 연결성이 생길 수 있습니다. 이러한 연결성은 각 프론트엔드의 독립성을 감소시켜 각 릴리스에 많은 종속성을 갖게 합니다.

변경되지 않은 것을 릴리스하지 않으면 최종적으로 변경해야 할 때 위험이 증가할 수 있습니다. 의존하는 공유 라이브러리 또는 다른 프론트엔드와의 연결성이 크게 변경되었을 수 있습니다.

프론트엔드 간 공유되는 코드베이스가 너무 커지면 릴리스가 더 이상 독립적일 수 없습니다. 다른 팀에 의해 출시 전에 앱이 망가질 가능성이 하나의 애플리케이션처럼 높아집니다.

4. 테스트할 수 있는 범위 감소

프론트엔드 및 릴리스가 작아지면 회귀 테스트를 위한 범위가 훨씬 더 작아집니다. 릴리스당 변경 사항이 적기 때문에 이론적으로 테스트에 소요되는 시간을 줄일 수 있습니다.

그러나 각 프론트엔드는 작을 수 있지만, 그 연결성은 그렇지 않습니다:

  • 하나의 마이크로 프론트엔드는 다른 프론트엔드로 연결되는 메시지와 이벤트를 전달하고 수신합니다.
  • 다중 페이지 워크플로는 이 프론트엔드를 다른 프론트엔드와 연결합니다.
  • 여기서 공유 코드베이스가 지난 릴리스 이후 크게 변경되었을 수 있습니다.
  • 하위 호환성을 지원하려면 과거와 미래의 연결을 알고 있어야 합니다.

이번 릴리스에서 컴포넌트를 업데이트하지 않았다고 해서 영향을 받지 않는다는 의미는 아닙니다.

테스트 시간을 몇 시간 절약할 수 있었다고 해도 아키텍처 결정에 따른 오버헤드로 인해 개발 시간이 늘어났을 수 있습니다. 테스트 시간을 절약할 수 있기는 하지만, 팀과 역할에 따라 기능 당 총 소요 시간이 더 늘어날 수도 있습니다.

5. 더 빠른 빌드 시간

각 클라이언트의 규모가 작을수록 빌드 속도가 빨라지고 테스트 실행 속도도 빨라집니다. 하지만 중소규모 애플리케이션의 경우 최적화가 시기상조일 수도 있습니다. 빌드 규모가 최신 도구를 압도할 정도로 커지기까지 오랜 시간이 걸릴 수 있습니다. 파일 감시 기능을 사용하면 적당한 크기의 빌드를 빠르게 컴파일할 수 있습니다.

마이크로 프론트엔드는 순 빌드 시간을 악화시킬 수 있습니다. 이제 하나의 애플리케이션을 빌드하는 대신 여러 애플리케이션을 빌드하여 프론트엔드 간의 모든 연결과 링크를 확인해야 합니다. 이제 실행해야 하는 테스트 스위트가 여러 개 있습니다.

6. 다양한 기술 사용 가능

마이크로 프론트엔드의 마지막 장점은 모든 사람이 다양한 프론트엔드 프레임워크와 도구를 자유롭게 사용할 수 있다는 것입니다. 소규모 팀에서 여러 프론트엔드를 동시에 배우고 사용할 가능성은 낮지만, 향후에 도구와 프레임워크로 업그레이드하고 싶을 때 업그레이드 경로를 확보할 수 있습니다. 마이크로 프론트엔드를 사용하면 모든 팀에서 업그레이드를 조율해야 하는 대신 각 팀이 독립적으로 기술 스택을 업그레이드할 수 있습니다. 또한 여러 기술 스택을 지원하므로 프레임워크에 관계없이 상용 솔루션을 쉽게 가져올 수 있습니다.

🔹 마이크로 프론트엔드가 아키텍처에 미치는 영향

프론트엔드를 분할하기로 결정할 때 가장 중요한 첫 번째 부분은 분할을 어떻게 할 것인가입니다. 여기서 내린 결정은 추후 다른 모든 작업에도 영향을 미쳤습니다.

애플리케이션을 분할할 수 있는 방법은 최소한 네 가지가 있었습니다:

  1. 비즈니스 관심사 또는 기능별로 분할
  2. 더 세분화하여 도메인 객체별로 분할
  3. 애플리케이션 내 위치 및 UI/UX 관심사별로.
  4. 팀별로, 집중적인 관심사에 대해 작업하는 팀이 있는 경우.

이상적으로는 이러한 결정 중 일부는 타협 횟수를 줄이기 위해 리스트업되었을 것입니다. 예를 들어, 별도의 비즈니스 문제를 전담하는 팀을 둘 수도 있었을 것입니다. 하지만 저희는 그런 상황이 아니었기 때문에 도메인 개체별로 세분화하기로 결정했습니다. 모든 부서의 이름을 미리 정하지는 않았지만 15~20개의 개별 마이크로 프론트엔드로 이어지는 방향으로 진행했습니다.

1. 마이크로 프론트엔드에 기능 분할

프론트엔드를 매우 세밀하게 분할함으로써 이제 많은 기능이 여러 마이크로 프론트엔드에 걸쳐 변경되어야 했습니다. 이러한 분할로 인해 각 프론트엔드의 독립성과 자율성이 제거되어 더 이상 개별적으로 개발, 테스트 또는 릴리스할 수 없게 되었습니다.

기능이 여러 프론트엔드에 걸쳐 있는 경우, 기능을 제공하기 위해 팀 간의 조율을 강화하거나 프론트엔드를 공유 풀로 만들어 분산형 모놀리스 아키텍처로 전환해야 합니다.

2. 마이크로 프론트엔드 간에 UI/UX 분할하기

마이크로서비스를 구축할 때는 다른 개발자들이 사용할 수 있도록 서비스를 만든다는 것을 고려해야 합니다. 반면 사용자 대면 애플리케이션의 경우 사용자와 UI/UX가 주안점이 되어야 합니다. 더 나은 사용자 경험을 제공하기 위해서는 여러 도메인을 단일 페이지에 결합하거나 여러 도메인에서 데이터를 수집하는 워크플로우를 만들 수 있습니다. UI에는 도메인 개체가 다른 도메인 개체로 래핑되거나 완전히 다른 개체인 것처럼 표시될 수 있습니다. 여러 도메인의 데이터를 집계하는 페이지를 표시하여 모든 사람이 자유롭게 업데이트할 수 있는 마이크로 프론트엔드를 만들어야 할 수도 있습니다.

저희는 사용자 친화적인 모든 기능을 포함하여 기존 UI를 모방하려고 노력했습니다. 하지만 세분화된 분할로 인해 이러한 접근 방식은 문제가 있었습니다. 마이크로 프론트엔드 간의 경계를 넘나드는 워크플로가 필요했습니다. 어디서는 마이크로 프론트엔드가 고립된 개별 컴포넌트가 되어야 했고, 또 다른 곳에서슨 마이크로 프론트엔드를 모두 다시 하나로 연결해야 했습니다!

3. 경계를 넘나드는 워크플로

마이크로 프론트엔드와 셸의 경계를 넘나드는 워크플로를 만드는 것은 만들기도 어렵고 유지 관리하기도 어렵습니다. 선택한 프레임워크에 기본 제공되는 라우팅 및 네비게이션 도구를 사용하는 대신 커스텀한 사용자 네비게이션을 구축해야 합니다. 별도의 애플리케이션, 언어, 프레임워크를 거쳐서 상태를 전달해야 합니다. 워크플로의 앞뒤 단계, 브랜칭 경로, 또한 사용자가 취소하거나 완료할 수 있는 다양한 위치를 고려해야 합니다. 워크플로우가 완료될 때만 저장하는 경우, 완료된 상태를 저장할 책임이 있는 주체를 고려해야 합니다. 각 애플리케이션은 여러 팀에서 업데이트할 수 있으며 독립적으로 릴리스 및 변경할 수 있습니다. 저는 이러한 애플리케이션을 빌드하고 유지 관리한 경험이 있는 입장으로서, 버그와 복잡성이 추가될 수 있으므로 가능하면 이 접근 방식을 피하는 것이 좋습니다.

이제 여러 프론트엔드를 함께 결합했으므로 각 프론트엔드의 독립성이 줄어들었습니다. 하나의 프런트엔드를 변경하면 연결된 모든 멀티 프론트엔드 워크플로우가 여전히 그대로 유지되는지 테스트해야 합니다. 독립적인 릴리스 또는 롤백을 지원하려면 각 멤버의 여러 버전을 조합하여 테스트해야 할 수도 있습니다. 버전 확인으로 인해 코드가 복잡해집니다.

4. 'Shared'가 덤핑 지대가 되다

마이크로 프론트엔드 간에 공통점이 너무 많아서, 우리는 Shared 프로젝트에 많은 것을 넣기 시작했습니다. 라이브러리를 공유하는 것 자체는 문제가 되지 않지만, 잘못된 구분으로 인해 만들어진 임의의 경계를 넘나들며 작업하기 위한 포괄적인 위치로 사용되면 문제가 됩니다.

공유 코드베이스가 커지면 각 릴리스 사이에 변경할 수 있는 내용이 늘어납니다. 마이크로 프론트엔드를 추가로 만들면 각 마이크로 프론트엔드를 수정하는 빈도는 줄어들지만 업데이트 사이에 Shared에 대한 변경 사항은 더 많이 발생합니다. 한동안 손대지 않았던 마이크로 프론트엔드를 릴리스할 때 Shared에 대한 변경 사항을 발견하기가 훨씬 쉬워집니다. 단일 애플리케이션을 사용하면 컴파일 시간 확인이 가능하고, 변경 효과를 즉시 확인할 수 있으며, 모든 것이 함께 릴리스됩니다.

재사용 가능한 라이브러리 코드를 작성하려면 더 많은 시간과 노력이 필요하며, 경계를 신중하게 고려하고 모든 사용법을 알 수 없을 것으로 예상되는 부분을 작성해야 합니다. 애플리케이션 코드를 작성하는 것과는 다른 기술입니다. 변경 사항의 영향을 이해하는 데 도움이 되는 IDE나 정적 분석에 의존할 수 없습니다. 변경 사항이 다른 팀의 특정 사용 사례를 깨뜨리지 않을 것이라고 보장하기 어렵습니다. 공유 코드의 모든 용도를 확인하는 것은 실용적이지 않으며, 최신 버전의 Shared를 마이크로 프론트엔드로 임포트해서 사용하는 사람의 문제로 전가되게 됩니다. 공유 라이브러리는 버그가 몰래 침투할 수 있는 또 다른 통로가 됩니다. 소규모 팀의 경우 공유 코드 작업에 소요되는 추가 시간으로 인해 추진력이 저하될 수 있습니다.

5. 검색 가능성 감소는 중복 구현으로 이어집니다.

애플리케이션을 분할하면 기존 코드를 검색할 수 있는 기능이 감소합니다. 검색을 지원하는 도구를 잃게 됩니다. 재사용할 부분을 찾기 위해 다른 프로젝트를 샅샅이 뒤져야 합니다. 무언가를 찾았다고 해도 공유 구성 요소에 액세스하기 위해 익숙하지 않은 프로젝트를 리팩토링해야 하는 번거로움을 감수하고 싶지 않을 것입니다.

검색 가능성 감소의 결과로 일부 표준 컴포넌트를 공유하지 못하여 결국 별도의 프론트엔드에서 중복 구현이 발생했습니다.

중복된 구성 요소는 시간이 지남에 따라 높은 비용을 초래합니다. 기존 솔루션을 재구현하는 데 많은 노력을 들일 뿐만 아니라, 앞으로의 변화는 더 다양한 곳에서 더 많은 변화를 필요로 합니다. 중복은 인스턴스를 놓치거나 유사한 두 컴포넌트 간의 차이점을 오해할 위험을 증가시켜 버그가 발생할 수 있는 또 다른 길을 열어줍니다.

6. 마이크로 프론트엔드 간의 커뮤니케이션

마이크로 프론트엔드는 호스트 또는 다른 마이크로 프론트엔드와 서로 통신하여 애플리케이션의 다른 부분에 변경이 필요함을 알려야 할 수 있습니다. 클라이언트가 줄어들고 애플리케이션의 복잡성이 증가함에 따라 마이크로 프론트엔드 간의 링크도 늘어납니다. 결국 커스텀 메시징 서비스를 만들어야 할 수도 있습니다.

앞서 언급한 워크플로우와 마찬가지로, 컴포넌트 간의 커뮤니케이션을 구축하면 구현 및 유지 관리가 더 어려워질 뿐만 아니라 컴포넌트의 독립성이 박탈됩니다. 더 이상 각각의 컴포넌트를 개별적으로 릴리스, 개발 또는 테스트할 수 없습니다. 어떤 통신이 존재하는지 발견하기가 더 어려워집니다. 적어도 마이크로서비스(Backend)의 경우 각 서비스의 경계를 제어할 수 있지만, 프론트엔드는 일반적으로 덜 엄격합니다.

7. 코드베이스가 분산되기 시작하다

애플리케이션을 여러 구성 요소로 나누고 팀 간에 공유할 때 발생할 수 있는 또 다른 문제는 팀별로 각자 다른 방향으로 갈라질 가능성이 있다는 것입니다. 시간이 지남에 따라 많은 의사 결정이 누적되고 결국 매우 다른 모양의 프로젝트가 만들어집니다. 팀 간에 서로 다른 구성 요소를 분리하는 경우 각 팀의 독립성을 높이고 각 팀이 적합하다고 판단되는 문제를 해결할 수 있으므로 이러한 분리는 이점이 있습니다. 반면에 각 팀이 다양한 기능을 개발할 때 선택했다가 내려놓는 마이크로 프론트엔드 풀이 있다면 분리가 문제가 될 수 있습니다. 오랫동안 유지보수 하지 않았던 마이크로 프론트엔드를 오랜만에 접할 때 생소하고 쉽게 함정에 빠질 수도 있습니다. 한 기능으로 인해 여러 웹뷰를 동시에 업데이트해야 하는 경우 코드베이스의 작동 방식을 지속적으로 다시 배우고 이해해야 하므로 추가적인 마찰과 시간이 소요됩니다.

우리는 첫 번째 마이크로 프론트엔드가 다각화되는 것을 막기 위해 조심스럽게 접근했음에도 불구하고, 불과 몇 달 만에 다음과 같은 차이점을 발견했습니다:

  • Jest에서 단위 테스트 작성하기 VS Enzyme에서 테스트 작성하기
  • 크기 조정에 rem을 사용하는 것 VS px을 사용하는 것.
  • UI 컴포넌트를 부모로부터 데이터를 받는 Dumb 컴포넌트(presentational component)로 취급하는 것 VS 데이터 검색을 담당하는 UI 컴포넌트로 취급하는 것.

원격 측정, 오류 로깅, 빌드 파이프라인 등 모든 마이크로 프론트엔드를 최신 상태로 유지하는 것만으로도 시간이 많이 소요됩니다. 하나의 변경 사항이 모든 마이크로 프론트엔드에 파급되어야 하기 때문입니다. 더 나쁜 경우, 업데이트가 한 지점을 놓쳐서 해당 로그가 필요할 때가 되어서야 특정 마이크로 프론트엔드에 대한 로그가 누락되었다는 사실을 알게 되는 경우도 있습니다.

8. 성능 문제

각 웹뷰를 격리하고 호스트에 대한 의존도를 최소화하려다 보니 애플리케이션의 성능이 저하되었습니다. 공유 캐시가 없기 때문에 각 웹뷰가 자체 데이터 세트를 가져와야 했기 때문에 대량의 중복 호출이 발생했습니다. 다만 우리의 경우 로그인 시 대부분의 데이터를 가져오고 자주 변경되지 않는 이미지를 캐시하는 애플리케이션을 교체하고 있었기 때문에 백엔드 서비스가 이 접근 방식을 지원하여 캐시 문제를 일으키지 않는 극적인 전환이 가능했습니다.

host가 웹뷰를 직접 띄우고 각 웹뷰는 고립된 상태였기 때문에 사용자는 웹뷰를 로드하고 코드를 가져오는 데 한 번, UI에 표시할 데이터를 검색하는 데 한 번, 두 번 기다리게 되었습니다. 웹뷰는 서비스 워커를 선행하는 Edge 버전을 사용하고 있었기 때문에 매번 웹뷰의 각 인스턴스를 새로 만들어야 했기 때문에 데이터를 프리페칭할 수 없었습니다. 그 결과 사용자가 여러 번의 로딩 상태를 거쳐야 하는 불안정한 경험을 하게 되었습니다. 마이크로 프론트엔드는 사용자 경험을 개선하는 데 방해가 되었습니다.

9. 프레임워크 지원

마이크로 프론트엔드의 장점 중 하나는 현재 자바스크립트 프레임워크가 이전 프레임워크의 방식으로 전환될 때 합리적인 업그레이드 경로를 제공한다는 점입니다. 하지만 이를 달성하기 위해 우리는 결국 또 다른 독단적인 자바스크립트 프레임워크에 갇히게 되었습니다. 지금까지 이 프레임워크에 대한 경험은 좋지 않았으며, 마이크로 프론트엔드를 충분히 지원하지 못했기 때문에 복잡성과 종속성을 더하는 것 외에는 별다른 이득을 얻지 못했습니다.

차라리 모놀리스로 시작해서 크기가 문제가 되면 그때 분할하는 것이 더 나았을 것입니다. 그때쯤이면 우리가 활용할 수 있는 프레임워크, 관행 및 도구가 확립되어 있을 것입니다. 하지만 우리는 남들보다 빨리 이 프레임워크를 도입했으며, 약간은 섣부른 접근 방식을 취했으며, 잘못된 도구를 사용했습니다.

10. 개발과 디버깅을 더 어렵게 만들고 있었습니다.

처음에는 각 프론트엔드를 개발하기 쉬웠습니다. 작고, 집중적이며, host 외부에서 실행할 수 있었기 때문입니다. 하지만 시간이 지남에 따라 다중 페이지 워크플로나 메시징 등 각 마이크로 프론트엔드 간에 연결이 생기기 시작했습니다. 디버깅할 마이크로 프론트엔드를 설정하기 위해 필요한 환경설정들을 해야 했고, 프론트엔드 간에 유기적인 흐름을 설정하고 테스트하는 것이 어려웠습니다. 연결할 때마다 테스트를 위해 호스트로 돌아가야 했고, 디버깅 도구와 전반적인 개발 환경이 열악했습니다. 이는 여러 프론트엔드를 동시에 로컬에서 실행해야 하는 오버헤드를 의미했습니다.

현재 개발 중인 앱 외에 다른 앱에 대한 컴파일 타임 검사 및 정적 분석에 액세스할 수 없게 되었습니다. 공유 코드를 변경할 때 어떤 영향이 있는지 파악하기가 더 어려웠습니다. 모든 프론트엔드를 중단하고 빌드하고 테스트하지 않으면 자신도 모르는 사이에 다른 사람의 작업을 망칠 가능성이 있었습니다. 작은 부분 하나를 더 쉽게 이해하기 위해 애플리케이션의 큰 그림을 이해하기 훨씬 더 어렵게 만드는 복잡성을 감수했습니다.

11. 규모에 너무 집중한 나머지 문제에 집중하지 못했습니다.

소프트웨어 개발자로서 우리는 크기에 너무 집착합니다. "이건 더 작아야 해." "아니, 더 작아야 해." 우리는 자르고 자르기 시작하기에 적절한 수준이 어느 정도인지에 대해 논쟁을 벌입니다. 저희의 경우, 일부 사람들은 사업 영역에 따라 겹치는 부분이 거의 없는 두 개의 크고 뚜렷한 영역으로 제품을 나누자고 주장했습니다. 다른 사람들은 모든 것을 정말 '마이크로'로 만들기 위해 한 단계 더 깊게 자르고 각각 15~20번씩 분할하자고 주장했습니다.

규모에 대해 논쟁할 때 우리는 요점을 놓치고 있습니다. 각 마이크로의 이상적인 크기를 가상의 이상적인 크기로 생각하는 대신, 문제에 대한 잠재적인 해결책으로서만 크기를 변경하는 것을 고려해야 합니다.

여기까지 오게 된 오해는 모든 것을 최대한 작게 만들면 애플리케이션을 배치하는 방법, 데이터를 검색하고 저장하는 방법, 라우팅과 통신이 작동하는 위치와 방법, 교차되는 문제를 관리하는 방법, 애플리케이션이 성장하는 방식에 대해 걱정할 필요가 없다는 생각, 즉 작다는 것이 아키텍처를 갖는 것을 대체할 수 있다는 생각입니다. 각 구성 요소는 매우 작아서 이론적으로는 순수하고 단순한 상태를 유지합니다. 하지만 실제로는 엉망진창이 됩니다.

🔹 실수하기

마이크로 프론트엔드의 아키텍처를 구축하는 과정에서 많은 실수를 저질렀습니다:

  • 팀, 기능 또는 애플리케이션의 사용자 경험을 고려하지 않고 마이크로 프론트엔드를 너무 세밀하게 나눴습니다.
  • 어떤 마이크로 프론트엔드를 만들 것인지 미리 파악하지 못했습니다.
  • 마이크로 프론트엔드 아키텍처를 지원하지 않는 프레임워크를 선택했습니다.
  • 문제에 대응하기보다는 시작하기 전에 각 프론트엔드의 목표 크기를 결정했습니다.
  • 계획적이고 체계적인 방식으로 애플리케이션을 업그레이드하지 않고 변경이 필요할 때마다 기존 애플리케이션의 기능을 새 애플리케이션으로 전환했습니다.
  • 이러한 접근 방식은 정상적인 아키텍처를 개발하지 못하게 하고 중요한 결정을 지연시켰습니다.
  • 공유 라이브러리를 어떻게 구성할지, 마이크로 프론트엔드 간에 무엇을 공유해야 할지, 공유하지 말아야 할지를 결정할 계획 없이 진행했습니다.

일이 궤도를 벗어났다는 사실을 깨달은 후 마이크로 프론트엔드를 더 잘 지원하기 위해 몇 가지 변경할 수 있었습니다:

  • 우리의 아키텍처를 지원하기 위해 UI/UX 및 사용자 워크플로를 업데이트합니다.
  • 더 많은 개발자를 고용하고 팀과 들어오는 작업을 재구성하여 팀을 더 잘 분리했습니다.
  • 데스크톱 클라이언트와 마이크로 프론트엔드 사이에 웹 기반 쉘 레이어를 추가합니다. 이 쉘은 적절한 마이크로 프론트엔드 아키텍처를 촉진하기 위한 접근 방식과 프레임워크를 사용할 수 있었습니다.

모놀리스는 우리의 문제점 중 하나가 아니었고 마이크로 프론트엔드로 전환해도 얻을 수 있는 이점은 별로 없었습니다. 더 시급히 해결해야 할 다른 문제들이 많았기 때문입니다. 물론 우리는 훨씬 더 많은 노력과 비용을 들여 마이크로 프론트엔드 아키텍처를 제대로 구축해 낼 수도 있었습니다. 하지만 꿈에 그리던 그 아키텍처를 구축했더라도 마이크로 프론트엔드를 도입할 가치가 없었을 것입니다.

profile
프론트엔드 개발자. 기록하기, 요가, 등산

0개의 댓글