새로운 프로젝트를 시작하기 앞서서 프로젝트의 구조를 어떻게 짤지 고민을 많이 하게 됐다.
3가지의 프로젝트를 진행하는데 비슷한 ui와 같은 api를 쓰는 것들이 많았고 자주쓰는 hook 들과 style들을 각각의 프로젝트마다 붙여넣는 것은 생각보다 비효율적인 것 같았다.
그래서 모노레포라는 것을 들어는 봤지만 깊이 알지는 못해서 자료를 찾아봤다.
등등 모노레포를 위한것들이 꽤나 많이 있었다.
그중에서 lerna와 yarn workspace를 같이 사용해서 모노레포를 구성하였다.
npm install --global yarn
npm install -g lerna
or
npx lerna init
먼저 이렇게 yarn과 lerna를 설치해 주었다.
그리고 루트에 있는 package.json을 수정해 주었다.
{
"name": "root",
"private": true,
"workspaces": [
"packages/*"
],
...
}
lerna create [workspace name]
workspace는 이렇게 추가하였다.
이렇게 만들고자 하는 프로젝트들을 추가하면
packages폴더에 들어가게 된다.
root
├── node_modules
├── packages
│ ├── 🗂project1
│ ├── 🗂project2
│ ├── 🗂project3
│ ├── 🗂common-components
│ ├── 🗂common-styles
│ ├── 🗂common-utils
├── package.json
├── tsconfig.json
├── lerna.json
...
공통적으로 들어갈 라이브러리가 있다면 이렇게 add 뒤에 -W
를 추가한다.
yarn add -W -D axios
yarn add -W redux
그리고 각 프로젝트 별로 필요한 라이브러리는 이렇게 추가한다.
yarn workspace [project name] add [library]
각 프로젝트에서 만약 공통 컴포넌트나 스타일, 유틸함수를 사용해야한다면
해당 프로젝트의 package.json에 사용하고자 하는 공통 모듈을 dependencies에 넣어주어야 한다.
// project1 의 package.json
{
...
"dependencies": {
"@common/components": "^1.0.0",
"@common/styles": "^1.0.0",
"@common/utils": "^1.0.0"
},
}
또한 공통 모듈을 사용하고자 하는 프로젝트에서 외부 패키지는 따로 transpiling을 해야 하기에
next-transpile-modules
를 추가해준다.
yarn workspace [project name] add -D next-transpile-modules
//해당 project의 next.config.js
const withTM = require("next-transpile-modules")(["@common/components"]);
const nextConfig = {
...
};
module.exports = withTM(nextConfig);
그리고 해당 모듈을 import 하여 사용하면 된다.
import { Button } from '@common/components'
...
*Next 13.1 부터는
next.config.js에 transpilePackages이라는 옵션이 생겨서 이걸 사용하면 된다.
monorepo로 프로젝트들을 구성하다 보니 배포 시스템도 많이 바꿀수 밖에 없었다.
기존에는 프로젝트별로 ec2를 하나씩 구성하였는데 이번에는 하나의 ec2로 여러개의 프로젝트를 docker container 별로 띄우는 식으로 구성해보았다.
다음 게시물에 자세히 작성해 볼 예정이다.