마이크로 프런트엔드 실용 가이드 - 2부

에서 우리는 마이크로 프론트엔드 아키텍처가 무엇이며 장단점에 대해 논의했습니다. 이 게시물에서는 프로젝트 설정에 필요한 단계인 React를 사용하여 기본 컨테이너 앱 및 샘플 모듈을 초기화하는 방법을 살펴보겠습니다.

우리는 복잡한 앱에 일부 예약 기능이 필요하다고 가정합니다. 하나의 모듈(예약 모듈)과 컨테이너(또는 마스터) 앱부터 시작하겠습니다.

다음을 사용하여 예약 모듈 초기화


npx create-react-app booking-modulecd booking-module && npm start 모든 것이 예상대로 작동하는지 확인하십시오.

기본 컨테이너 앱에 노출될 카운터 구성 요소를 만듭니다.

// src/Counter.js
import React, { useState } from 'react'

const Counter = () => {
    const [count, setCount] = useState(0);
    const handleIncrement = () => setCount(count + 1);
    const handleDecrement = () => setCount(count - 1);
    return (
        <div className='counter'>
            <h3>This is Counter App Module</h3>
            <p><strong>{count}</strong></p>
            <div>
                <button onClick={handleIncrement} className='counter-btn'>+</button>
                <button onClick={handleDecrement} className='counter-btn'>-</button> 
            </div>

        </div>
    )
}
export default Counter;


App.js 업데이트

import './App.css';
import Counter from './Counter';

function App() {
  return (
    <div className="App">
      <h3>This is Booking module</h3>
      <Counter/>
    </div>
  );
}

export default App;


다음 단계: 웹팩 소개npm install webpack webpack-cli webpack-dev-server html-webpack-plugin
webpack.config.js 생성

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;
const deps = require('./package.json').dependencies

module.exports = {
    mode: 'development',
    devServer: {
        port: 8082,
    },
    output: {
        filename: 'main.js',
      },
      module: {
        rules: [{ 
            test: /\.jsx?$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: { presets: [
                '@babel/env',
                ["@babel/preset-react", {"runtime": "automatic"}]
            ] },
         }, { 
            test: /\.css$/, 
            use: [ 'style-loader', 'css-loader' ] 
        }],
      },
    plugins: [
        new ModuleFederationPlugin({
            name: "bookingModule",
            filename: "remoteEntry.js",
            remotes: {},
            exposes: {
              "./Counter":"./src/Counter.js"
            },
            shared: {
              ...deps,
              react: {
                singleton: true,
                requiredVersion: deps.react,
              },
              "react-dom": {
                singleton: true,
                requiredVersion: deps["react-dom"],
              },
            },
          }),
        new HtmlWebpackPlugin({
            template: './public/index.html'
        })
    ]
};


여기서ModuleFederationPlugin 구성 요소를 별도의 번들로 표시합니다. 참고 - 내부의 이름 필드ModuleFederationPlugin는 구성 요소를 가져오는 동안 사용되므로 고유한 모듈 이름이 있는지 확인하십시오.

우리는 Counter 컴포넌트를 이렇게 노출시켰습니다.

exposes: {
    "./Counter":"./src/Counter.js"
}


다음과 같이 여러 구성 요소를 노출할 수도 있습니다.

exposes: {
    "./Counter":"./src/Counter.js",
    "./Timer":"./src/Timer.js"
},


다음 단계 -npx webpack serve - 주어진 포트에서 모듈 인스턴스를 실행합니다. 내 경우에는 8082



모듈의 진입점 파일을 재구성합니다.
기본적으로 src/index.js는 항목 파일이며 번들을 빌드하는 동안 문제를 일으키는 여러 가져오기를 포함합니다.
다음과 같이 src/index.js 파일을 수정합니다.

import('./bootstrap')


다음 내용으로 bootstrap.js 파일을 만듭니다.

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);


기본 컨테이너 앱 초기화


npx create-react-app containercd container
Webpack 종속성 설치npm install webpack webpack-cli webpack-dev-server html-webpack-plugin
webpack.config.js 파일 생성

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;
const deps = require('./package.json').dependencies

module.exports = {
    mode: 'development',
    devServer: {
        port: 8080,
    },
    output: {
        filename: 'main.js',
      },
      module: {
        rules: [{ 
            test: /\.jsx?$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: { presets: [
                '@babel/env',
                ["@babel/preset-react", {"runtime": "automatic"}]
            ] },
         }, { 
            test: /\.css$/, 
            use: [ 'style-loader', 'css-loader' ] 
        }],
      },
      plugins: [
        new ModuleFederationPlugin({
            name: "container",
            remotes: {
               bookingModule:"bookingModule@http://localhost:8082/remoteEntry.js",
              },
            exposes: {
            },
            shared: {
              ...deps,
              react: {
                singleton: true,
                requiredVersion: deps.react,
              },
              "react-dom": {
                singleton: true,
                requiredVersion: deps["react-dom"],
              },
            },
          }),
        new HtmlWebpackPlugin({
            template: './public/index.html'
        })
    ]
}


우리는 이제 이 URL에서 모듈을 가져오도록 웹팩에 지시하고 있으며 예약 모듈에서 했던 것과 유사하게 여러 모듈을 가져올 수 있습니다.

remotes: {
               bookingModule:"bookingModule@http://localhost:8082/remoteEntry.js",
              },


이제 예약 모듈의 구성 요소를 사용할 준비가 되었지만 예약 모듈에서 수행한 것과 유사한 프로젝트의 진입점을 변경해야 합니다.

콘텐츠가 포함된 bootstrap.js 파일 생성

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);



index.js 파일을 아래와 같이 수정

import('./bootstrap')


이제 예약 모듈에서 카운터를 가져오고 구성 요소를 소비합니다.

import Counter from 'bookingModule/Counter';

function App() {
  return (
    <div className="App">
      <h3>This is Container App</h3>
      <Counter/>
    </div>
  );
}



산출:


소스 코드는 여기에서 찾을 수 있습니다.



다음 단계 - 배포 예정

좋은 웹페이지 즐겨찾기