REACT MONOREPO

김다운·2022년 7월 23일
3

Monorepo

목록 보기
1/1

팀 FE 프로젝트에서 MSA (MicroService Architecture) 를 지향하는 개발을 위해 monorepo를 도입하기로 하였다.
작업을 위해 포스팅을 열심히 찾아봤지만 대부분 ts를 사용하거나 lerna, nx, turborepo를 사용해서 ts를 기반한 방법만 보였다..

지금은 js만 사용 하고 있기에 위 방법들에서 ts를 걷어내려 했지만 쉽지 않아서 yarn workspace를 활용해 처음 부터 설계하였다.

0. Monorepo

일반적으로 하나의 프로젝트당 한개의 저장소를 사용하는 것을 multi-repo 라고 하고 MonoRepo는 하나의 저장소에 여러개의 프로젝트가 구성된 것을 의미한다.

1. 기본 구조 잡기

1. root

전체 프로젝트를 도입하기 위해 root 디렉토리를 생성하고 yarn 작업 폴더를 선언해준다.

mkdir project
cd project
yarn init

생성된 package.json 파일을 수정해준고 yarn init으로 디렉토리를 yarn 패키지 폴더로 설정해 준다.

생성된 package.json을 아래처럼 수정해준다.

{
  "name": "**프로젝트 이름**",
  "private": "true",
  "version": "1.0.0",
  "workspaces": [
    "packages/*" // 프로젝트 폴더
  ],
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "license": "MIT"
}

프로젝트가 들어갈 폴더를 아래처럼 선언해주고 packages라는 폴더를 생성해준다.

...
  "workspaces": [
    "packages/*" // 프로젝트 폴더
  ],
...

2. Common Components

monorepo를 사용하는 가장 큰 이유는 여러 프로젝트에서 공통의 UI 또는 Utils를 중복으로 사용하기 위함이다.

  1. packages 폴더 밑에 common이라는 폴더를 생성하고 yarn init 명령어로 yarn 프로젝트를 선언해준다.
  2. yarn add react react-dom 명령어로 react 모듈을 해당 폴더에 생성해준다.
  3. common/Button.jsx 파일을 생성한다
import React from "react";
export const Button = props => {
  return <button {...props}>{props.children}</button>;
};

3. Create-React-app

3-1 프로젝트 생성

packages 폴더로 진입한후 CRA 프로젝트를 생성한다

npx create-react-app cra

/* yarn 으로 프로젝트가 맞춰져있어서 개발환경마다 생성시 에러가 날수도있음 아래 명령어로 npm으로 우회해서 설치해도 상관없음! */

npx create-react-app cra --use-npm

Monorepo에서 프로젝트 실행은 root에서 사용해야한다 그럼으로 root 폴더의 Package.json에 script를 추가한다.

  "scripts": {
    "client": "yarn workspace ProjectName"
  },

여기서 ProjectName은 cra로 생성한 폴더에있는 package.json에 name 속성이다.
해당 자식 Project의 package.json에 script를 root에서 사용할 수 있도록 해준다. yarn client 뒤에 이어서 자식 project의 명령어를 이어서 써주면 된다.

script를 추가 하였으면 root에서 yarn/yarn install 명령어로 root 디렉토리에서 의존성 모듈을 설치한다.

다음 명령어로 프로젝트를 실행한다

yarn client start 
or
yarn client start

3-2 Common Components 사용

생성해둔 Common Components를 Webpack 모듈을 마이그레이션 해야하는데 CRA는 Webpack config를 지원하지 않고 Caraco 모듈을 활용해서 마이그레이션을 해야한다.

  1. packages/cra 에서 yarn add @craco/craco
  2. packages/cra/craco.config.js 생성
const path = require("path");
const { getLoader, loaderByName } = require("@craco/craco");
const absolutePath = path.join(__dirname, "common(공통 컴포넌트 폴더 명)");
module.exports = {
  webpack: {
    alias: {},
    plugins: [],
    configure: (webpackConfig, { env, paths }) => {
      const { isFound, match } = getLoader(
        webpackConfig,
        loaderByName("babel-loader")
      );
      if (isFound) {
        const include = Array.isArray(match.loader.include)
          ? match.loader.include
          : [match.loader.include];
        match.loader.include = include.concat[absolutePath];
      }
      return webpackConfig;
    }
  }
};
  1. packages/cra/package.json
"scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject"
  },
  1. packages/cra/src/App.jsx
import { Button } from "common/Button";
import "./App.css";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h1>모노레포</h1>

        <Button>버튼!</Button>
      </header>
    </div>
  );
}

export default App;

profile
열려 있는 FE 개발자

0개의 댓글