회사 여러 프로젝트에 중복 사용되는 유틸리티 코드와
통일되지 않은 버전들이 너무 많아 관리가 힘들어 lerna
를 사용해 이 문제를 해결해보려 한다.
“A tool for managing JavaScript projects with multiple packages.”
Lerna는 여러 개의 패키지를 관리하는 JavaScript 프로젝트를 위한 도구입니다.
Lerna를 사용하면 모노레포(Monorepo) 형태로 구성된 프로젝트에서 여러 패키지를 일괄적으로 관리하고, 배포 및 테스트를 쉽게 수행할 수 있습니다.
설치
npm i -g lerna
프로젝트 초기화
lerna init
패키지 추가하기
lerna create 패키지이름
의존성 관리
lerna add 패키지이름 --scope=base //
lerna add 패키지이름 --scope=base --dev // base 패키지에 라이브러리를 dev로 설치
{
"packages": ["packages/*"],
"version": "independent",
"npmClient": "yarn",
"useWorkspaces": true
}
--stream 옵션, 실행 console 같이 출력
lerna link convert
패키지들의 devDependency를 root package.json으로 끌어올리기
lerna bootstrap
패키지들의 dependency 설치
2022-08-02 추가
처음부터 모노 레포지토리를 lerna
를 이용하여 코드를 작성한다면 위와 같은 방법을 사용하면 되지만
어느 정도 구현이 되어있는 여러 레포지토리를 합치는 경우는 어떻게 해야할까?
기존에 어느 정도 작성된 레포지토리가 3개 있다 가정한다.
$ lerna init
$ lerna create 기존레포1
$ lerna create 기존레포2
$ lerna create 공유모듈 // 기존레포1과 기존레포2 공통적으로 사용되던 모듈을 따로 추출
먼저 packages
에 기존레포1
, 기존레포2
, 공유모듈
3가지 폴더가 생긴다.
각 폴더에 기존에 작성 되었던 package.json
의 scripts, dependencies, devDependencies를 직접 복사하여 저장 후
루트 디렉토리에서lerna link convert
를 cli에 작성하면 각 json의
devDependencies를
를 루트의 json의 devDependencies
로 이동시켜준다.
이 과정에서 모듈의 버전이 바뀌는 경험을 하였습니다. 모든 과정이후 실행을 할 때 에러가 발생하면 기존에 작성 되었던 레포지토리 디펜던시 버전을 확인하세요.
각 레포의 공통 모듈을 추출한 공유모듈
에 기존레포1
과 기존레포2
는 의존성을 갖고 있기 때문에 주입을 해주어야합니다.
lerna add 공유모듈 --scope=기존레포1 // 기존레포2도 똑같이 실행.
이전의 공유모듈의 호출은 상대주소로 되어있지만 위와 같이 의존성을 주입하면 라이브러리
와 같은 방법으로 호출해야 합니다.
e.g
import { ... } from "../공유모듈" // 수정 전
import { ... } from "공유모듈" // 수정 후
root 디렉토리에서 lerna bootstrap
실행을 하여 디펜던시를 설치합니다.
각 레포지토리의 package.json의 scripts에 start, build와 같은 공통적인 명령어를 작성 후
루트 디렉토리에서 lerna run build
또는 start
를 하면 등록된 모든 패키지의 json의 명령어를 실행합니다.
공유모듈의 경우 타입정의 용도로 사용했으므로 json scripts에 start와 같은 실행명령어는 X
lerna run build
와 같이 각 레포의 build 명령어를 실행 시켜 주는 경우
root 디렉토리에서 실행을 시키는 것이 아닌
각 레포의 루트 위치에서 실행을 시켜주기 때문에 path
디렉토리 위치가 꼬일 수가 있으니 참고.
추가 2022-08-11
lerna run start
와 같이 모든 packages을 실행이 가능하지만
lerna 만으로는 각 서비스들이 계속 실행되고 있음을 보장 할 수가 없다.
각 패키지 마다 pm2를 실행 시키기 보다는
lerna root 폴더에 통합하여 pm2.json을 생성함.
{
"apps": [
{
"name": "package1",
"cwd": "./packages/package1",
"script": "./dist/index.js"
},
{
"name": "package2",
"cwd": "./packages/package2",
"script": "./dist/server.js"
}
]
}
주의 : cwd 옵션을 주어야 각 패키지 모듈이 root인 것 처럼 실행이 된다.
pm2 start pm2.json
root 디렉토리에서 실행.