코드 스터디

「WebPack 개발」 4 Federation(합치기)

Recstasy 2023. 4. 6. 06:45

 

Federation은 사전적 용어로 '연합'을 의미하는데, 쉽게 '합치기'라 생각하면 된다. 

 

webpack은 Federation을 통해 마이크로서비스를 제작할 수 있는 기반을 제공해준다. 이번 포스팅에서는 Federation에 관해 알아보자.

 

 

 


1] product / Federation모듈 import

Federation을 실행할 수 있는 웹팩 플러그인, 'ModuleFederationPlugin'모듈을 import한다.

 

platform/product/webpack.config.js

 

현재 platform폴더 아래에는 container, product폴더가 있으며, container폴더가 배포팀(팀장)이므로 주인이다. 나머지 폴더는 하위 개발팀이므로 각 팀들의 개발코드를 상부에 보고(exposes)해야 한다. 따라서 ModuleFederationPlugin의 exposes값을 위와 같이 설정해줘야 한다.

 

반면, container폴더는 배포팀(팀장)이므로 하위 폴더를 조정 & 통제해야 한다. 그러므로 다음과 같이 ModuleFederationPlugin의 remotes값을 설정할 수 있다.

 

platform/container/webpack.config.js

 

배포폴더(container)의 ModuleFederationPlugin(webpack.config.js)에는 remotes 객체값으로 하위 폴더 Federation플러그인 설정값(fetch주소, 이름, 임시 js파일)을 지정할 수 있다. 위에서는 product Federation플러그인에서 설정한 이름 'products'와 'filename'을 연결했다.

 

 

 

 

 

 


2] container /  src설정

container의 src폴더는 하위 폴더(개발팀)의 main.js파일이 모두 모여드는 저장소다.

platform/container/src/bootstrap.js & index.js

 

bootstrap.js는 감별사와 같은 역할을 한다. 배포하려는 폴더의 js파일을 import할 지 결정하기 때문이다. 그리고 index.js는 bootstrap.js파일을 import한다. 여기서 굳이 index.js, bootstrap.js 2가지 파일을 생성한 이유는 배포 파일과 하위 모듈의 직접적인 연결을 피하기 위해서다. index.js는 어떠한 모듈인지 전혀 알 필요가 없다. 배포 결정은 bootstrap.js가 처리하며, index.js는 하부 사항에 개입하지 않기 때문에 변경이 발생하더라도 bootstrap.js만 선에서 해결된다. 이것은 대통령이 실무 공무원들에게 직접 지시하지 않고, 장관들에게 안건을 일임하는 것과 같다. 

 

위에서는 product 파일을 선택했다.

 

 

 

 

 


3] container / public  / index.html 수정

현재 상태에서 웹서버를 실행하면 에러가 발생한다.

 

 

product의 index.js파일은 product 내의 'index.html'이 갖고 있는 id 요소가 지정되어 있기 때문이다. 이를 해결하려면, 아래와 같이 container의 index.html파일에 product의 id요소를 추가해야 한다.

 

 

 

 

 

 


4] container 실행

현재 product "포트:8081", container "포트:8080"로 웹서버가 설정되어 있다.

product:8081, container:8080

 

product, container 각 폴더에서 webpack 서버를 실행한 후, 포트8080으로 접속해보자.

 

container 웹서버:8080

 

위와 같이, 런타임으로 product(src폴더 내) 코드를 실행한 container 웹서버를 볼 수 있다.

이같은 결과는 container의 bootstrap.js의 기능 덕분이다. (모듈 방식으로 하위 폴더의 실행 파일을 읽음)

 

 

그러므로 bootstrap.js를 주석으로 처리하게 되면,

 

 

product 결과를 읽을 수 없기에 해당 부분이 없어진다.

 

즉, container의 bootstrap.js에서 어떤 하위 폴더를 모듈로 선택 하는지에 따라 결과를 컨트롤 할 수 있다.(변경에 용이함)

 

 

bootstrap.js는 상당히 중요하기에 좀더 살펴보자.

container/bootstrap.js 모듈 규칙

 

bootstrap.js에서 import하는 모듈은 'webpack.config.js'파일의 ModelFederationPlugin에서 설정한 'remotes' 값에 달려있다. import "[container]remotes객체의 key값/[product]exposes객체의  key값" 규칙이 적용된다.

 

 

그리고 container(배포팀)의 webpack.config.js에서 remotes객체는 아래와 같은 규칙에 따라 특정 폴더를 모듈로 설정할 수 있다. **다소 헷갈릴 수 있는 부분이므로 아래 화살표 참고

 

 

 

 

 


5] cart 생성

product폴더(하위팀)에 이어 cart폴더를 추가적으로 생성한 뒤,

product의 package.json파일을 '복사-붙이기'로 넣어준다.(이름만 변경)

 

platform/cart/package.json

 

cart폴더에서 npm을 초기화를 진행한 후, 모듈을 설치한다.

 

cart 내 npm모듈 설치

 

 

 

 


6] cart / public / src 생성

product폴더와 같은 방식으로 "public/index.html", "src/index.js", "src/bootstrap.js"를 생성한다.

 

 

 

 

 


7] cart / webpack.config.js 생성

cart의 webpack.config.js 역시 product와 유사하다. 

- 포트 지정

- Federation 설정

- HtmlWebpack플러그인 설정

cart/webpack.config.js

 

webpack.config.js 설정을 끝냈다면,

npm run start를 통해 cart의 8082포트가 정상적으로 실행되는지 확인한다.

 

cart:8082 포트 웹서버 실행

 

 

 

 

 

 


8] container 병합

현재, 8081포트는 'product', 8082 포트는 'cart'를 사용하고 있다. 

container(8080포트)는 총책임자이며, product와 cart의 모듈을 import해야 한다.

이 부분은 container의 webpack.config.js를 아래와 같이 수정함으로써 해결할 수 있다.

 

container/webpack.config.js

 

핵심은 ModuleFederationPlugins의 'remotes' 객체다. container의 remotes객체는 bootstrap.js가 요구하는 모듈을 불러오는 핵심적인 기능을 수행한다. 

 

container/src/bootstrap.js

 

container의 bootstrap.js에서 모듈 설정까지 끝냈다면,

'cart'의 id요소를 'container/public'의 index.html에 추가한다.

 

container/public/index.html

container의 웹 서버를 실행해보자.

 

 

아래와 같이 product, cart의 "src/index.js" 모두 8080포트에서 확인할 수 있다.(container에서 병합)

 

container:8080포트