본문 바로가기

import
{ [NextJS] Module-Federation 2 }
from" ../hr-devlog"

const { Frontend } = useHrDevlog( );

저번글에서는 Monorepo 프로젝트 셋팅을 해보았는데 이번에는 Module-federation을 통해서

RemoteApp에서 HostApp으로 Component를 가져와보겠습니다!

 

먼저 Next.js에서 Module-Federation을 하기위해 hostApp과 remoteApp에 @module-federation/nextjs-mf 를 설치하겠습니다

그리고 Module-Federation을 위해 Webpack도 설치해주겠습니다~

 

 

// apps/mono-app 
// shared/ui
yarn add @module-federation/nextjs-mf
yarn add webpack

// root
yarn

 

Host에서 RemoteApp 불러오는 설정하기

// apps/mono-app
// next.config.js

/** @type {import('next').NextConfig} */
const NextFederationPlugin = require("@module-federation/nextjs-mf");
const nextConfig = {
  reactStrictMode: true,
  webpack(config, options) {
    config.resolve.fallback = {
      monoUi: false, // remote쪽 name과 일치해야함
    };
    if (!options.isServer) {
      config.plugins.push(
        new NextFederationPlugin({
          name: "momoApp",
          filename: "static/chunks/remoteEntry.js",
          remotes: {
            monoUi: `monoUi@http://localhost:3001/_next/static/chunks/remoteEntry.js`,
            // remote쪽 name과 일치해야함
          },
          exposes: {},
          shared: {},
        })
      );
    }

    return config;
  },
};

module.exports = nextConfig;

 

Host App 쪽에서는 NextFederationPlugin으로 불러올 RemoteApp을 설정해준다!

 

RemoteApp에서 내보낼 Remote 설정하기

먼저 간단한 Button 하나를 만들어주고,

 

// Shared/ui/Button/index.tsx
import React from "react";

export default function Button() {
  return (
    <button
      style={{
        backgroundColor: "#fedcba",
        padding: "50px",
        borderRadius: "15px",
        cursor: "pointer",
      }}
      type="button"
    >
      Hi I'm Remote Button in Shared/Ui
    </button>
  );
}
 

잘만들어졌는지 한번 봐볼까요?

 

간단하게 만든 버튼

 

다음은 RemoteApp의 next.config.js를 설정해보기로!

npx로 안했더니 파일이 없네요,, host꺼 복사해와서 수정해주는걸로 하겠습니다

 

/** @type {import('next').NextConfig} */
const NextFederationPlugin = require("@module-federation/nextjs-mf");

const nextConfig = {
  swcMinify: true,
  webpack(config, options) {
    if (!options.isServer) {
      config.plugins.push(
        new NextFederationPlugin({
          name: "monoUi",// host name과 일치해야함
          remotes: {},
          filename: "static/chunks/remoteEntry.js",
          exposes: {
            "./button": "./Button/index.tsx",
          },
          shared: {},
        })
      );
    }
    return config;
  },
};

module.exports = nextConfig;

 

여기서 중요한 점은 host와 remote의 next.config.js에서 name이 일치해야합니다!

이제 host와 remote 에서 module-federation을 할 준비는 끝났으니 host에서 불러와보도록 하겠습니다

 

Host에서 Remote의 Components 불러오기

 

// apps/mono-app/pages/index.tsx
import dynamic from "next/dynamic";

// dynamic import 해줘야 합니다!
const Button: React.ComponentType = dynamic(() => import("monoUi/button"), {
  ssr: false,
});
export default function Home() {
  return (
    <main>
      <div
        style={{
          padding: "50px",
          backgroundColor: "#abcdef",
          textAlign: "center",
          fontSize: 30,
          color: "#000",
        }}
      >
        Hi. I am HostApp
      </div>
      <div style={{ display: "flex", justifyContent: "center" }}>
        <Button />
      </div>
    </main>
  );
}

 

remote에서 잘 가져오나 볼까요?

 

Host App

 

Remote App

 

잘가져와집니다! 하지만 타입에러가 나는것을 확인할 수 있습니다,,

 

d.ts 파일을 만들어줘서 명시해주도록 합시다!

 

// remoteTypes.d.ts
declare module "monoUi/*";

 

앞으로 monoUi에서도 여러가지 Components 를 가져올거기때문에 *로 선언해두면 타입문제도 해결됩니다!

 

이번글은 여기서 마치며 다음글에서는 Shared에서 type을 정의해주고 Button의 Props를 전달하는 방식을 작성해보겠습니다!

'Frontend' 카테고리의 다른 글