최근 진행했던 프로젝트에서 비슷한 UI를 가지나, 각각 독립적으로 배포되어야 웹 사이트를 제작하게 되었다. 기획을 듣고나서 설계하는 과정에서 느낀 개발 요구사항은 다음과 같았다.
- 디자인 요구 사항이 반영된 UI 컴포넌트, 스타일들을 공유 해야한다.
- 몇 가지 비즈니스 로직들을 공유해야 한다.
- 타입을 공유해야한다.
위 요구 사항을 충족하기 위해서 npm private package
혹은 npm workspace
등을 먼저 떠올렸었다. npm private package
는 이전에 활용해본 적이 있었다. 각 배포마다 패키지를 직접 업데이트를 해주어야 했는데, 그렇다보니 각 배포 사이에 버전이 다르게 되는 경우가 없지 않았다. 버전 관리에 굉장히 까다로움을 느꼈다.
npm workspace
는 이전에 활용했을 때, 참조 관련 에러를 만났던 적이 있어서 새로 공부가 필요했었다. 하지만, 이번 경우에는 새로운 기능을 사용해보고 싶어서 공부 삼아 monorepo
로 진행하기로 했다.
그 중에서도 turborepo
, nx
등을 찾게 되었으나 가장 먼저 알게된 nx
를 사용하기로 했다. nx
의 기능들이 nestjs-cli
처럼 굉장히 강력하게 느껴졌기 때문인 것 같다.
Installation
monorepo
가 관장하는 큰 영역을 workspace
라고 부르는데, 이를 생성하기 위해서는 아래의 명령어를 사용한다.
1
yarn create nx-workspace
위 코드를 수행하면 어떤 형식을 선택할 것 인지 묻는데, 다음과 같이 출력된다.
1
2
3
4
5
Package-based monorepo: Nx makes it fast but lets you run things your way.
Integrated monorepo: Nx configures your favorite frameworks and lets you focus on shipping features.
Standalone React app: Nx configures Vite (or Webpack), ESLint, and Cypress.
Standalone Angular app: Nx configures Jest, ESLint, and Cypress.
Standalone Node app: Nx configures a framework (ex. Express), esbuild, ESlint and Jest.
여기서 Package-based
, Integrated
, Standalone
의 선택지가 보이는데, 각각 아래와 같은 차이점이있다.
Integrated Repos vs. Package-Based Repos vs. Standalone Apps
Package-based
는 workspace
하위의 app
마다 각각 독립적인 package.json
을 가진다. 그리고 중첩된 각각의 node_modules
폴더를 가지게 된다. 이를 통해 각각 프로젝트마다 다른 의존성을 가지게 된다.
Interaged
는 오직 하나의 의존성만 가지게 된다. 모두가 node_modules
를 공유하며 모든 프로젝트에서 하나의 버전만을 가지게 된다. 나의 경우에는 이 항목으로 작업하였다.
Standalone
은 monorepo
로서 사용하는 것이 아닌, React
, Angular
등을 위해 단독으로 사용하는 경우다. nx-cli
나 빌드 전략, 캐싱등의 기능등이 굉장히 유용하기 때문에, monorepo
가 아니더라도 사용하는 경우이다.
New App
새로운 프로젝트를 생성할때에는 원하는 항목에 알맞는 명령어를 공식 홈페이지에서 확인할 수 있다. 나의 경우에는 Next앱을 활용했다.
1
2
3
4
nx generate application myapp --directory
# same
nx g app myapp --directory
통상적으로 앱을 생성할때에는 위의 명령어를 사용한다. 축약어로도 사용가능하다. 그런데, 이 경우에는 어떤 어플리케이션을 생성할지 선택하게 되는데, 바로 next
프로젝트를 만들기 위해서는 다음과 같이 입력한다.
1
nx g @nx/next:application
이렇게 작성하면 e2e테스트 코드를 포함하여 /apps
폴더에 생성된다.
이렇게 생성된 어플리케이션은 다음과 같이 실행할 수 있다.
1
nx run myapp:serve
:serve
는 해당 프로젝트의 실행 명령어인데, package.json
에 작성되어있다.
VS Code Extension
위의 명령을 사용하다보면, 매번 명령어를 입력하는데 어려움이 따른다. VS Code
를 사용하는 경우 Nx Console을 사용하면 훨씬 수월하게 사용할 수 있다.
기본적으로 NX 명령어와 프로젝트를 볼 수 있는 탭을 추가로 제공하고, 각 명령어의 실행 시에 편리한 입력 form을 제공해준다.
New Library
실제 배포가 되는 Application
이 아닌, UI등의 코드는 Library
를 생성하여 사용한다. Library
의 경우, JavaScript
, TypeScript
는 물론 React
, NextJS
, NestJS
등도 제공한다.
나의 경우에는 UI, Type, 훅 등의 비즈니스 로직등을 나누어 두었는데, UI는 React
가 아닌 Next
Library
를 사용했다. next/image
등을 활용해야 하는 탓이었다.
명령어는 다음과 같다.
1
nx generate @nrwl/next:library
기본적으로 이렇게 생성한 Library
는 다음과 같이 참조하여 사용할 수 있다.
1
2
3
import { something } from "@my-workspace/your-lib-name";
something();