개발 기술/사소하지만 놓치기 쉬운 개발 지식

[모노레포] 특정 폴더를 패키지화하는 방법

by GicoMomg (Lux) 2023. 5. 15.

1. 들어가기에 앞서…

  • 어플리케이션을 개발하다보면 모노레포에 여러 개의 패키지가 만들어지고, 의미 단위로 폴더를 구분하다보면 패키지 내부에도 여러 개의 폴더가 발생할 수 있다.
  • 우리 서비스의 경우, components 패키지 내에 총 2개의 폴더가 존재하는데
  • 서비스와 독립적이면서 재사용 가능한 컴포넌트를 모은 ui 폴더, 그리고 서비스에 종속되면서 재사용가능한 컴포넌트의 모음인 shares가 있다.
|- components
|-- ui        // 서비스와 독립적, 디자인 시스템이 확립됨, 재사용 가능
|-- shares    // 서비스에 종속적, 재사용 가능

  • 그리고 우리는 불과 얼마 전까지만 해도 이 두 폴더의 컴포넌트를 접근할 때 아래와 같이 import 했다.
import { Checkbox } from @gc/components/ui;

import { MenuHeader } from @gc/components/shares;

  • 하지만 이 두 폴더는 components 폴더에 존재하기만 하는 거지 사실상 독립적인 패키지로 취급되어야 했다.
  • 그래서 import할 때는 components 명칭은 무의미했고, import할 때 components 명칭이 빠져야 했다.
import { Checkbox } from @gc/ui;

import { MenuHeader } from @gc/shares;

  • 그렇다면 이를 어떻게 구현할 수 있었을까?
  • 이번 시간에는 모노레포에서 특정 폴더를 패키지화하는 방법에 대해 알아보았다.




2. 특정 폴더를 패키지화하는 방법

큰 흐름은 아래와 같다.
1. 루트의 packages.jsonworkspaces에 패키지화를 하고 싶은 폴더의 경로를 추가한다.
2. 패키지화 대상 폴더에 packages.json을 만든다.
3. 생성한 packages.jsonname 속성에 원하는 패키지명(ex. @gc/ui, @gc/shares)을 작성한다.


1) 루트의 package.json의 workspaces에 경로 추가하기

(1) workspaces가 무엇인가요?(사전 지식)

  • 모노레포에서 루트 위치의 package.json에는 workspaces속성이 있는데,
  • 속성값으로 독립적인 작업으로 취급되어야 할 디렉토리 목록을 정의할 수 있다.
  • 이렇게 정의한 디렉토리 목록은 모노레포에서 별도 패키지로 취급된다.
// packages.json

{
 "workspaces": ["packages/*"],
}

  • 예를 들어 workspaces 속성값을 packages/* 으로 정의하면,
  • packages 디렉토리 내의 모든 디렉토리를 별도의 작업 공간으로 취급한다는 의미가 된다.
// packages.json

{
 "workspaces": ["packages/*"],
}

  • 만약 packages 디렉토리 안에 pepe라는 디렉토리가 있으면 pepe는 개별 작업 공간으로 취급된다.
|- packages/components
|-- pepe

  • pepe 폴더의 package.json에서 name@gc/hello-pepe라고 명명하면
// packages/pepe/package.json

{
  "name": "@gc/hello-pepe",
  "version": "1.0.0",
  "main": "index.js"
}

  • 다른 패키지에서 아래와 같이 import 할 수 있게 된다.
import { 어쩌구 } from '@gc/hello-pepe';

(2) package.json의 workspaces 수정해보기

😎 그럼 이제 실전으로 돌아와서 components 디렉토리 내의 ui, shares를
각각 @gc/ui, @gc/shares로 패키지화해보자!

  • 우리는 우선 workspaces에 이 두 폴더를 개별 작업 공간으로 정의해주어야 한다.
  • 아래와 같이 폴더 경로를 추가해주면, ui, shares는 개별적인 패키지로 인식된다.
// ./package.json

"workspaces": [
  "packages/*",
  "packages/components/shares",  // 추가!
  "packages/components/ui"       // 추가!
],

  • 여기서 중요한 점은, workspaces를 수정한 후 yarn install을 해줘야 한다는 점이다.
  • 해당 명령어를 실행해줘야 모노레포에서 추가된 패키지를 인식할 수 있다.
yarn install



2&3) 각 폴더에 package.json을 만들고, name 정의하기

  • 그 다음으로 shares, ui폴더에 각각 package.json 파일을 만들어준다.
  • 그리고 원하는 패키지명을 name에 정의해주자!
// packages/components/shares/package.json
{
  "name": "@gc/shares", // 수정
  "version": "1.0.0",
  "main": "index.js"
}
// packages/components/ui/package.json
{
  "name": "@gc/ui", // 수정
  "version": "1.0.0",
  "main: "index.js"
}

  • 그러면 다른 패키지에서 shares, ui폴더를 아래와 같이 import할 수 있게 된다!
import { HeaderMenu } from '@gc/shares';
import { Checkbox } from '@gc/ui';




3. 마치며…

  • 이번 시간에는 모노레포에서 특정 폴더를 패키지화하는 방법에 대해 알아보았다.
  • 패키지화 방법은 간단했는데 우선 루트 위치의 packages.jsonworkspaces에 패키지화를 원하는 폴더의 경로를 추가하고, 각 폴더에 package.json을 만들어서 name을 정의해주면 됐다.
  • 이렇게 하면 다른 패키지에서 해당 폴더를 원하는 패키지명으로 import할 수 있게 된다.
  • 이 문서의 예시 레포는 이 링크에서 확인할 수 있다.(코멘트로 설명도 남겨두었으니 참고용으로 봐주세요~)




반응형

댓글