UI용 마이크로 프런트엔드(MFE) 아키텍처
문제
Bahmni가 발전하면서 AngularJS 대신 React로 모듈을 만들기 시작했습니다. 현재 이러한 React 구성 요소는 어댑터를 사용하여 AngularJS 애플리케이션 안에서 빌드됩니다. 따라서 React 기반 모듈마다 AngularJS 기반 저장소와 함께 빌드해야 하며 코드 중복과 유지 관리 부담이 늘어납니다.
또한 기존 bahmniapps AngularJS 모듈(예: form-controls)에 구성 요소를 설치해야 하는 React 모듈은 AngularJS가 동적 의존성을 허용하지 않으므로 openmrs-module-bahmniapps와 함께 빌드해야 합니다. 즉, 이러한 React 모듈을 배포할 때마다 bahmniapps 프로젝트를 다시 빌드해야 합니다.
해결 방법
WebPack은 런타임에 가져올 수 있는 동적 JavaScript 모듈을 사용하는 Module Federation 기법을 지원합니다. React의 Suspense 모델과 결합하면 React 구성 요소가 런타임에 원격 JavaScript 파일에서 불러온 구성 요소를 사용할 수 있습니다. 이 전략을 사용하면 openmrs-module-bahmniapps가 런타임에 다른 웹 서버/컨테이너에서 제공되는 React 구성 요소를 사용할 수 있습니다. 이 구성 요소들은 독립적인 배포 전략을 갖는 자체 저장소에 둘 수 있으며 최신 구성 요소를 사용하기 위해 openmrs-module-bahmniapps 호스트 UI를 다시 빌드할 필요가 없습니다.
또한 AngularJS 어댑터 코드를 openmrs-module-bahmniapps 저장소로 분리합니다. 따라서 동적 React 모듈은 AngularJS 의존성과 함께 빌드할 필요 없이 순수 React 프로젝트로 설정할 수 있습니다.
해결 방법을 설명하는 커뮤니티 통화
아키텍처 다이어그램

전체 흐름
- openmrs-module-bahmniapps에는 React 마이크로 프런트엔드 소스용 /micro-frontends 폴더가 별도로 있습니다. 이 폴더에서 빌드한 파일은 AngularJS 애플리케이션이 참조할 수 있도록 ui/app/micro-frontends-dist/에 기록됩니다. 일반적으로 *.min.js와 *.min.css 파일입니다. 모든 MFE의 공통 코드는 shared라는 고유 진입점에서 처리되어 shared.min.js와 shared.min.css가 생성됩니다. React 및 react-dom 파일과 함께 모든 마이크로 프런트엔드보다 먼저 불러와야 합니다.
- next-ui라는 로컬 MFE가 있으며 자체 저장소가 필요 없는 React 구성 요소를 담습니다. 주요 진입 구성 요소 위에 AngularJS 어댑터를 적용하면 bahmni.mfe.nextUi라는 AngularJS 모듈이 만들어집니다. AngularJS 진입점에 next-ui.min.* 파일을 포함할 때 이를 AngularJS 모듈의 의존성으로 추가할 수 있습니다. 이 구성 요소는 원격이 아니므로 openmrs-module-bahmniapps 저장소와 함께 빌드하고 업데이트해야 합니다.
- 원격 MFE마다 저장소가 하나씩 있습니다. 이 저장소는 ModuleFederationPlugin을 통해 특정 진입 구성 요소를 노출합니다. 저장소를 빌드하고 배포하면 원격 구성 요소를 불러오는 remoteEntry.js 파일을 제공합니다. 이 웹 서버는 일반적으로 Bahmni 프록시 내부에서 프록시됩니다.
- bahmniapps/micro-frontends/에는 원격 마이크로 프런트엔드마다 WebPack 진입점이 하나씩 있습니다. 이곳에는 React 구성 요소용 Angular 어댑터 코드가 있으며 bahmni.mfe.<name-of-entry>라는 Angular 모듈이 생성됩니다. 이 마이크로 프런트엔드가 필요한 Bahmni 모듈에 주입해야 합니다.
- 어댑터가 적용된 각 React 구성 요소는 런타임에 remoteEntry.js를 사용하여 해당 원격 React 구성 요소를 지연 로드합니다.
- 이 파일은 <name-of-entry>.min.js와 <name-of-entry>.min.css로 빌드되며 해당 마이크로 프런트엔드가 필요한 Bahmni 모듈에서 불러올 수 있습니다.
사용 도구 및 기법
- WebPack이 원격 모듈을 참조하게 하는 ModuleFederationPlugin
- 원격 React 구성 요소를 지연 로드하는 React의 Suspense 기법
- React 구성 요소를 AngularJS 구성 요소로 변환하는 react2angular
결정 사항 및 절충점
- Node 버전 v14.21.3(LTS): 실행에 필요한 WebPack 기능과 함께 작동하는 최소 버전입니다.
- React 버전 v16.14.0: 기존 사용 사례를 깨뜨리지 않기 위해 선택했습니다. Module Federation에 필요한 도구를 모두 지원합니다. React는 특히 훅을 사용할 때 Module Federation에 민감하므로 Node와 React 버전을 완전히 고정하고 여러 저장소에서 동기화해야 합니다.
- Carbon components v10.19 및 carbon-components-react v7.25: Node 버전 때문에 이 버전에 유지됩니다. Carbon 디자인 시스템 문서의 Sass 구조가 크게 바뀌어 개발자가 스타일을 올바르게 매핑하기 어려울 수 있습니다. 기능상 큰 변화는 없으므로 이전 문서에서 적절한 변경 방법을 찾을 수 있습니다.
- 스타일링 해결책에는 큰 변화가 없습니다. Carbon 디자인 시스템이 Sass를 사용하므로 계속 같은 방식을 사용합니다. 마이크로 프런트엔드는 격리된 스타일링을 위한 모듈 Sass를 지원합니다.
- 번역은 각 원격 MFE가 자체적으로 처리합니다. 나중에 핵심 번역을 MFE와 공유하는 방안을 검토할 수 있습니다. 로컬 MFE는 핵심 번역 집합을 사용할 수 있습니다.
- 현재 MFE에는 자체적인 구성 개념이 없습니다. 구성 API를 직접 호출하거나 런타임에 호스트 애플리케이션으로부터 필요한 구성을 전달받을 수 있습니다.
- MFE를 포함한 React 코드베이스는 React를 번들링하지 않고 window.React와 window.ReactDOM에 의존해야 합니다. 이는 비슷한 방식에 의존하는 기존 양식 구성 요소와 Angular 앱의 React 번들 로딩 방식을 깨뜨리지 않기 위한 것입니다. 그 결과 WebPack 구성이 조금 복잡해져 이 의존성을 감추고 실제 소스 코드에서 React 사용 방식의 차이가 없게 해야 합니다. 이후 전통적인 React 번들링 모델로 쉽게 마이그레이션할 수 있습니다.
MFE 작성 및 통합 방법
다음 페이지의 문서를 따르십시오.
하위 문서
Bahmni Wiki · CC BY-SA 4.0