예전 대규모 프로젝트를 수행하기 위해 웹팩 빌드를 기능 별로 분리하려고 땅을 파다가 이런 생각이 났다. 빌드해야 할 Front-end가 크다면 아예 프로젝트를 여러 개로 나누어서 빌드하고 합치면 되지 않는가?
이 경우에 빌드된 파일의 chunk
가 다 다르게 나오면 문제가 발생하고 새로운 컴포넌트나 페이지를 만들 때마다 webpack
의 설정을 수정해야 하는 문제 등이 발생한다. 혼자 개발한다면 아주 큰 문제가 되지 않을 수 있지만 여러 명, 여러 팀이 프로젝트를 수행할 때면 발생 가능한 문제점을 최소화할 필요가 있었다.
문제점을 해결할 방안을 탐색 중 서버 사이드에서 사용하는 MSA
를 적용하면 좋을 것 같다는 생각을 했다. 구글링한 결과 MSA
에서 개념을 얻어 Front-end
에 적용한 Micro Front-end 개념이 있었다.
Server
의 Micro Services Architecture
에서 고안한 것으로 작은 단위의 웹 앱들을 컴포넌트로써 조립하여 하나의 웹 앱을 만드는 기술이다. 여기서 각 웹 앱은 독립적으로 제공할 수 있는 웹 앱이다.
업그레이드 시 전체를 재구축할 필요가 없다. 각 앱들은 상호 분리되어 있는 구조이기 때문에 언제든지 필요한 소스만 수정하거나 새로운 웹 앱을 구성하여 추가할 수 있다.
각각의 Micro Front-end 앱의 소스는 기존의 모놀리식 프로젝트의 소스보다 훨씬 작다. 이는 코드의 복잡성을 줄이고 개발자 친화적이다.
Micro Front-end를 사용한 웹 앱의 경우 Micro Front-end 앱을 모아서 큰 웹 앱을 만드는 것이므로 각 Micro Front-end 앱은 독립적이며 각각의 프로젝트 환경, 테스트 및 배포할 수 있다.
프로젝트의 일부분을 각 Micro Front-end 개발 팀이 완전히 소유할 수 있어야 한다. 해당 프로젝트의 개발 환경 등은 각 팀 별로 구성할 수 있어 신속하고 효과적으로 수행할 수 있다.
Nginx
를 사용하여 reverse proxy
를 정의하였고 해당 위치를 get
방식으로 불러와 웹 앱을 구성하는 방식으로 구현해보았다.
// nginx.conf
server {
...
location / {
proxy_pass http://localhost:3000;
}
location /react {
proxy_pass http://localhost:3001;
}
location /angular {
proxy_pass http://localhost:3002;
}
location /vue {
proxy_pass http://localhost:3003;
}
...
}
컨테이너를 담당할 웹을 /
로 주었고 각 프레임워크를 사용한 Micro Front-end 앱의 접근 주소를 지정해주었다.
const setInnerHTML = (elm, html) => {
elm.innerHTML = html;
Array.from(elm.querySelectorAll('script')).forEach((oldScript) => {
const newScript = document.createElement('script');
Array.from(oldScript.attributes).forEach((attr) =>
newScript.setAttribute(attr.name, attr.value)
);
newScript.appendChild(document.createTextNode(oldScript.innerHTML));
oldScript.parentNode.replaceChild(newScript, oldScript);
});
},
각 주소를 접근하여 얻은 text/html
자체를 innerHTML
또는 컨테이너 앱의 ref
를 통해 그려주게 되면 script
가 동작하지 않는다. 위의 함수를 정의하여 script
요소를 만들어 교체하는 방식으로 script
가 수행되어 SPA
이 그려질 수 있도록 하였다.
🚨 실제로 Micro Front-end는 웹 컴포넌트를 조립해서 작성한다. 이를 구현했을 때는 웹 컴포넌트에 대한 지식이 부족하여 HTML 코드를 통째로 집어 넣어 모의 구현한 것이다. 쓸데 없는 코드가 입력되기 때문에 웹 컴포넌트에 대한 지식을 좀 더 습득해야 겠다.
빨간색 테두리는 Angular, 초록색 테두리는 Vue, 파란색 테두리는 React로 구성하여 하나의 웹 앱을 구성해보았다. 이벤트의 전달 방식은 Custom Event
를 활용하여 전달할 수 있다. 다음에 자세히 알아보도록 하겠다.