๐Ÿ‘‰ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

Untitled Diagram drawio

yarn v2 ์˜ Plug'n'Play( pnp )

yarn version 2 ๋ถ€ํ„ฐ ๋‚˜์˜จ Plug'n'Play ์ „๋žต์€ npm์˜ node_modulesํƒ์ƒ‰์ด ์•„๋‹Œ pnp ํŒŒ์ผ์— ๋ช…์‹œ์ ์œผ๋กœ ์œ„์น˜๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ํšจ์œจ์ ์œผ๋กœ ์˜์กด์„ฑ ๋ชจ๋“ˆ์„ ๊ฒ€์ƒ‰ํ• ์ˆ˜์žˆ๊ณ , npm ๊ฐ™์ด ์„ค์น˜ ํ•˜์ง€ ์•Š์€ ํŒจํ‚ค์ง€ ๋ชจ๋“ˆ์ด ์„ค์น˜๋œ ํŒจํ‚ค์ง€ ๋ชจ๋“ˆ ์•„๋ž˜์— ์žˆ๋‹ค๋ฉด importํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ๋ น ์˜์กด์„ฑ์„ ์ œ๊ฑฐํ•˜์—ฌ ํ˜ผ๋ž€์„ ์—†์•ด๋‹ค.

  ["react", [\
        ["npm:18.2.0", {\
          "packageLocation": "./.yarn/cache/react-npm-18.2.0-1eae08fee2-88e38092da.zip/node_modules/react/",\ <- ์˜์กด์„ฑ ์œ„์น˜ ๋ช…์‹œ
          "packageDependencies": [\
            ["react", "npm:18.2.0"],\
            ["loose-envify", "npm:1.4.0"]\
          ],\
          "linkType": "HARD"\
        }]\
  ]],\

ZipFS

yarn v2 pnp ์ „๋žต์„ ์‚ฌ์šฉํ•˜๋ฉด .yarn/cache/~.zip ์œ„์น˜์— zip ํŒŒ์ผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜์กด์„ฑ๋“ค์˜ ๊ธฐ์กด๋ณด๋‹ค ์ž‘์€ ์šฉ๋Ÿ‰์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ์–ด github ๊ฐ™์€ ์ €์žฅ์†Œ์— ์˜์กด์„ฑ์„ ๊ฐ™์ด ์˜ฌ๋ ค๋‘์–ด ๋ฐฐํฌ์‹œ ์˜์กด์„ฑ ์„ค์น˜๋ฅผ ์ƒ๋žตํ•˜์—ฌ ๋ฐฐํฌ์‹œ๊ฐ„์„ ์ค„์ผ์ˆ˜ ์žˆ๋‹ค.

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2022-07-12 แ„‹แ…ฉแ„’แ…ฎ 2 41 24

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2022-07-12 แ„‹แ…ฉแ„’แ…ฎ 2 42 01

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2022-07-12 แ„‹แ…ฉแ„’แ…ฎ 2 42 22

vscode๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑ์‹œ zip ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์–ด ์˜์กด์„ฑ์„ ์ฝ์„์ˆ˜ ์žˆ๋„๋ก ZipFS extension์„ ์„ค์น˜ ํ›„ yarn dlx @yarnpkg/sdks vscode ์ž…๋ ฅํ•˜๋ฉด .vscode ํŒŒ์ผ์ด ์„ค์น˜๋˜๋ฉฐ ์˜์กด์„ฑ ์ธ์‹์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

mono-repo (yarn - workspace)

๋ชจ๋…ธ๋ ˆํฌ๋Š” ํ•˜๋‚˜์˜ ์ €์žฅ์†Œ์— ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๋“ค์„ ๊ด€๋ฆฌํ•˜๊ณ  ์˜์กด์„ฑ์„ ๊ณต์œ ํ•˜์—ฌ ๊ฐœ๋ฐœํ•˜๋Š” ์ „๋žต์ž…๋‹ˆ๋‹ค. yarn v2 workspace๋ฅผ ํ™œ์šฉํ•œ๋‹ค๋ฉด ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ๋ฅผ ํด๋ก ํ•˜์˜€์„ ๊ฒฝ์šฐ ์˜์กด์„ฑ ์„ค์น˜๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋Š” zeroInstall ์ „๋žต์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฟ๋งŒ์•„๋‹ˆ๋ผ ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ํ™œ์šฉํ•œ๋‹ค๋ฉด ๊ณตํ†ต ํ•ญ๋ชฉ(์ปดํฌ๋„ŒํŠธ, ์Šคํƒ€์ผ, ์„ธํŒ…)์„ ๊ณต์œ ํ•˜์—ฌ ์ข€๋” ์ฒด๊ณ„์ ์ธ ๊ฐœ๋ฐœ์„ ํ• ์ˆ˜ ์žˆ๋‹ค.

_แ„€แ…ฎแ„Œแ…ฉ แ„ƒแ…กแ„‹แ…ตแ„‹แ…ฅแ„€แ…ณแ„…แ…ขแ†ท drawio

workspace-tool plugin

// yarn workspace-tool ์„ค์น˜

yarn plugin import workspace-tools

workspace-tools ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๋Š” ์ด์œ ๋Š” foreach๋ผ๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์„ค์น˜๋ฅผ ํ•˜์˜€๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ foreach ๊ฐ™์€ ๊ฐœ๋…์œผ๋กœ ์„ค์ •ํ•œ workspace์— ๋Œ€ํ•ด ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰์„ํ•˜๊ฒŒ ํ•ด์ฃผ๊ณ , --since ๋ผ๋Š” ์˜ต์…˜์œผ๋กœ ์ฐธ์กฐ ๋ธŒ๋žœ์น˜ ๊ธฐ์ค€ ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” workspace๋งŒ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฃผ์˜โ—๏ธ - foreach์˜ --since ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ git-flow ์ „๋žต์„ ๋ฌด์—‡๋ณด๋‹ค ์ž˜ ์ด์šฉํ•ด์•ผํ•œ๋‹ค.

Untitled Diagram drawio (1)

โ—๏ธwebpack5 module Federation

์›นํŒฉ5 ๋ถ€ํ„ฐ ๋‚ด์žฅ๊ธฐ๋Šฅ์œผ๋กœ ์ถ”๊ฐ€๋œ federation ๊ธฐ์ˆ ์€ ์ง€๊ธˆ ๊ตฌํ˜„ํ•œ ๋งˆ์ดํฌ๋กœ ํ”„๋ก ํŠธ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ด๋‹ค. Federation์€ runtime์‹œ ๊ณต์œ ํ•œ ์„œ๋น„์Šค๋กœ ๋ถ€ํ„ฐ ์ฝ”๋“œ(chunk file)์™€ ์ข…์†์„ฑ(dependency)์„ ๋™์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋‹ค์‹œ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Federation config options

  • name : service ์ด๋ฆ„
  • filename : ๋‚ด๋ณด๋‚ผ ํŒŒ์ผ ์ด๋ฆ„
  • exposes : ๊ณต์œ ํ•  ์ž์›
  • remotes : ๊ณต์œ  ๋ฐ›์„ ์„œ๋น„์Šค ์ฃผ์†Œ
  • shared : ๊ณต์œ ํ•  ์ž์›์ด ์žˆ์„ ๊ฒฝ์šฐ! ์ข…์†์„ฑ ๊ณต์œ 

    shared options

    • singleton : ์—ฌ๋Ÿฌ ํŒจํ‚ค์ง€ ๋ฒ„์ „์ด ๊ณต์œ ๊ฐ€ ๋˜์–ด์žˆ๋‹ค๋ฉด ํ•˜๋‚˜์˜ ๋ฒ„์ „์—์„œ๋งŒ ๋กœ๋“œ๊ฐ€ ๋œ๋‹ค, ์ฆ‰ ์„ค์ •ํ•œ ๋ฒ„์ „์—์„œ๋งŒ ๋กœ๋“œ๊ฐ€ ๋œ๋‹ค
    • requiredVersion : ์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ข…์†์„ฑ ํŒจํ‚ค์ง€ ๋ฒ„์ „์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.
    • eager : true๋กœ ์‚ฌ์šฉํ•˜๋ฉด load๊ฐ€ ๋˜์ง€ ์•Š์„๋•Œ๋„ ํ•ญ์ƒ ๋‚ด๋ ค๋ฐ›๊ฒŒ ๋œ๋‹ค.

- exposes

exposes ์˜ต์…˜์€ ์„œ๋น„์Šค์˜ component, style, assets ๋“ฑ... ์„œ๋น„์Šค ์ž์›? ์„ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ด๋‹ค.

// service1/webpack.config.js

const { ModuleFederationPlugin } = require("webpack").container;
const deps = require("./package.json").dependencies;

plugins: [
  new ModuleFederationPlugin({
    name: "service1",
    filename: "remoteEntry.js",
    exposes: {
      "./App": "./src/App.tsx",
    },
    shared: {
      ...deps,
      react: {
        eager: true,
        singleton: true,
        requiredVersion: deps.react,
      },
      "react-dom": {
        eager: true,
        singleton: true,
        requiredVersion: deps["react-dom"],
      },
    }
  })
]

- remotes

remotes ์˜ต์…˜์€ ๊ณต์œ ํ•œ ์„œ๋น„์Šค์™€ ์—ฐ๊ฒฐ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

// container/webpack.config.js

plugins: [
  new ModuleFederationPlugin({
    name: "container",
    remotes: {
      remote_service1: "service1@http://localhost:port/remoteEntry.js",
    },
  })
]
// container/src/App.tsx
import React from 'react'

const ServiceApp = React.lazy(()=> import('remote_service1/App'))


function App() {
  return (
    <div>
      {
        <React.Suspense fallback={<div>๋กœ๋”ฉ์ค‘</div>}>
          <ServiceApp />
        </React.Suspense>
      }
    </div>
  )
}

export default App

๐Ÿ–ฅ ๋ฐฐํฌ์ „๋žต

์ง€๊ธˆ ๋ฐฐํฌ ๋ฐฉ๋ฒ•์€ ๊ฐœ์ธ์ ์ธ ์ƒ๊ฐ์„ ๋‹ด์€ ๋ฐฐํฌ ๋ฐฉ๋ฒ•์ด๋‹ค.

๐Ÿ‘‰ yarn pnp ์ „๋žต์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ์— ๋ชจ๋“  ์ข…์†์„ฑ๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด, docker container์—์„œ build๋ฅผ ์ง„ํ–‰ํ•˜๋Š” docker multi stage build ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ํ”„๋กœ์ ํŠธ์—์„œ build ํ›„ dist ํด๋”๋ฅผ VOLUMES๋กœ ๊ณต์œ  ํ•œ๋‹ค๋ฉด, ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ์ด ์žˆ๋”๋ผ๋„ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด ์‹œ๊ฐ„ ๋‚ญ๋น„๋ฅผ ์ตœ์†Œํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.