https://www.youtube.com/watch?v=lKKsjpH09dU
이 영상의 0:00 ~ 11:50의 내용을 토대로 정리한 글입니다.
리액트 앱를 설치하기 위해 아래의 명령어를 입력
pnpx create-mf-app
설정은 다음과 같이 선택했습니다.
? Pick the name of your app: home
? Project Type: Application
? Port number: 3000
? Framework: (Use arrow keys)
lit-html
? Framework: react
? Language: javascript
? CSS: Tailwind
? Pick the name of your app: pdp
? Project Type: Application
? Port number: 3001
? Framework: (Use arrow keys)
lit-html
? Framework: react
? Language: javascript
? CSS: Tailwind
각 폴더로 들어가 다음 명령어를 입력합니다.
yarn
yarn start
설치를 두 폴더 완료했다면 웹페이지에서 다음과 같은 화면이 나옵니다.
모듈을 통해 예시를 들 것이기 떄문에 home에 Header.jsx와 Footer.jsx을 만들겁니다.
/home/src/header.jsx
export default function Header() {
return (
<div className="p-5 bg-blue-500 text-white text-3xl font-bold">
Fidget Spinner World
</div>
);
}
/home/src/footer.jsx
export default function Footer() {
return (
<div className="p-5 bg-blue-500 text-white text-3xl font-bold">
Only The Best Spinners
</div>
);
}
/home/src/App.jsx
import React from "react";
import ReactDOM from "react-dom";
import "./index.scss";
import Header from "./Header";
import Footer from "./Footer";
const App = () => (
<div className="text-3xl mx-auto max-w-6xl">
<Header />
<div className="my-10">
Home Page Content
</div>
<Footer />
</div>
);
ReactDOM.render(<App />, document.getElementById("app"));
제대로 적용되면 다음과 같은 화면이 나옵니다.
webpack.config.js에서 다른 앱에서도 사용할 모듈을 exposes합니다.
/home/webpack.config.js
modules.exports = (_, argv) => ({
...
plugins: [
new ModuleFederationPlugin({
name: "home",
filename: "remoteEntry.js",
remotes: {},
exposes: { // 이곳에 외부로 보낼 모듈을 등록
"./Header": "./src/Header.jsx",
"./Footer": "./src/Footer.jsx",
},
...
}
]
})
webpack 설정을 리로드하기 위해 home을 재시작합니다.
성공적으로 마쳤다면 http://localhost:3000/remoteEntry.js 에서 모듈에 대한 manifest를 볼 수 있을 겁니다.
그리고 이 링크를 가지고 home에서 exposes한 모듈을, pdp 앱에서 remotes 할 겁니다.
remotes하기 위한 pdp/webpack.config.js의 설정입니다.
/pdp/webpack.config.js
modules.exports = (_, argv) => ({
...
plugins: [
new ModuleFederationPlugin({
name: "home",
filename: "remoteEntry.js",
remotes: {
home: "home@http://localhost:3000/remoteEntry.js"
// 이름: "(exposes한 ModuleFederationPlugin의 name)@http://localhost:3000/remoteEntry.js
},
exposes: {},
...
}
]
})
webpack 설정을 reload하기 위해 pdp를 재시작합니다.
기져온 모듈을 사용하기 위해 pdp/src/App.jsx에서 다음과 같이 설정합니다.
/pdp/src/App.jsx
import React from "react";
import ReactDOM from "react-dom";
import "./index.scss";
import Header from "home/Header";
import Footer from "home/Footer";
const App = () => (
<div className="text-3xl mx-auto max-w-6xl">
<Header />
<div className="my-10">
PDP Page Content
</div>
<Footer />
</div>
);
ReactDOM.render(<App />, document.getElementById("app"));
아까 remotes한 모듈을 home으로 등록했으니, Header와 Footer는 home/을 통해 불러올 수 있습니다.
적용이 제대로 되었다면 pdp 앱에서는 다음과 같은 화면이 나옵니다.
이제 Home 앱에서 Header를 바꾸면 pdp 앱에서는 단순히 새로고침만 해도 업데이트된 모듈의 내용을 가져올 수 있습니다.
참고로 이 방식은 Micro-Frontend를 구성하는 방식 중 하나인 Module Federation이라는 방법입니다.
Micro-Frontend를 사용하는 이유는 백엔드가 모놀리틱에서 Micro-Service로 전환되면서 얻는 이점과 동일합니다.
장점
어플리케이션의 환경 의존성이 낮아지기 때문에 팀마다 모듈을 독립적으로 개발하고 배포하기가 용이해짐
특히 서비스가 커질 때 같이 의존성도 높아지기 마련이라 더욱 효과적으로 적용될 수 있음
필요한 파일만 사용하기 때문에 빌드 속도가 줄어듦
한 어플리케이션에서 개발하는 것이 아니여서 서로 다른 기술 스택을 사용할 수 있음
단점
기타
간단히 요약하자면 애플리케이션의 일부분만 업데이트하거나 교체할 수 있어 유지보수와 확장성이 용이하다는 것입니다.