Yarn Berry Workspace

Yarn Berry WorkSpace란?

모노레포 방식으로 여러 프로젝트(패키지)를 단일 레포지토리에서 관리하는 방식

의존성 관리를 한 곳에서 관리하기 때문에 공통된 의존성 모듈을 재사용하고, 중복되는 의존성 설치 문제를 피할 수 있다.

  • workspace: 모노레포의 패키지를 의미

Yarn Berry

Yarn v2 에서 사용하는 패키지 매니저

  • 기본적으로 명시적인 의존관계를 나타내야 사용 가능

  • node_modules 에 패키지를 저장하는 방식이 아닌 패키지를 압축하여 한개의 파일을 .yarn/cache/ 폴더에 수평적으로 저장한다. 이러한 방식을 Plug'n'Play(PnP) 라 한다.

    • 수평적으로 존재하여 빠르게 탐색 가능

    • 압축파일을 설치하기 때문에 파일 개수가 감소하여 설치가 빠름

    • Zero Install을 이용하여 저장소에서 함께 관리 가능

      • 저장소에 올라가기 때문에 저장소 자체가 매우 커지게 될 수 있음 (push, pull등 느리게 됨)

      • Zero Install이 아예 설치하지 않는것은 아님, 여러 환경에서 새로운 파일을 만들어내는 경우 때문에 설치 필요

    • Phantom Dependency가 발생하지 않음

  • PnP 모드를 기본적으로 지원

    • PnP 방식은 IDE에서 직접 사용하는 많은 도구들을 SDK 를 통해 우회 호출할 수 있도록 추가적인 설정 필요

  • workspaces plugin 지원

circle-info

workspaces plugin이란 yarn의 workspace를 좀 더 쉽게 관리하기 위해 제공되는 플러그인

yarn workspace 명령어를 사용해서 워크스페이스에 속한 패키지들에 대해 일괄적으로 작업을 수행할 수 있다.

node_modules 문제점

  • 의존성 탐색 알고리즘 비효율

    • 모듈을 검색할 때 의존성 경로의 깊이 만큼 상위 node_modules 를 검색하게 된다.

  • node_modules 폴더 아래에 수 많은 패키지가 저장되어 공간을 많이 차지하게 되고 그만큼 설치하는데 오래 걸린다.

  • 유령 의존성이란 프로젝트에 실제로 사용하지 않지만 lock 파일에는 존재하는 의존성 패키지

    • 의존성 중복 방지를 위한 호이스팅 기법의 Side Effect

    • 불필요한 공간을 차지하고 느리게 만든다.

circle-info

패키지 매니저(npm, yarn)에서 중복되는 의존성 설치를 방지하기 위해 호이스팅기법arrow-up-right을 사용한다.

Plug & Play

패키지 의존성을 설치할 때, node_modules 폴더를 생성하지 않고, 의존성 패키지들을 .yarn/cache에 수평적으로 압축파일로 설치하여 필요한 패키지를 빠르게 가져와서 사용하는 방식

  • 여러 패키지에서 중복되는 의존성 패키지들을 전역으로 설치해서 재사용하는 방식

  • 해당 모듈을 사용하기 전 메모리에서 ZipFS라는 도구를 사용해서 압축을 해제하고 필요한 부분만 추출하여 가져오는 방식으로 효율적으로 접근한다.

  • 의존성이 .yarn/cache에 수평적으로 설치되므로 모든 패키지에 대한 접근 시간이 O(1)

  • 호이스팅 방식을 사용하지 않기 떄문에 유령 의존성이 발생하지 않는다.

  • 압축파일로 된 의존성을 git으로 관리하게 되면 설치 과정을 생략(zero-install)할 수 있다.

circle-info

PnP 모드를 지원하지 않는 라이브러리를 사용하게 된다면 의존성 관리 방식을 node_modules 방식으로 변경해서 사용해야 한다.

Monorepo 환경 세팅하기

NVM

Node Version Manager, 여러 노드 버전을 스위칭하여 관리할 수 있게 도와주는 도구

  • 여러 프로젝트에서 서로 다른 Node 버전을 사용할 수 있게 도와준다.

  • 각 프로젝트마다 Node를 관리할 필요가 없게 된다.

환경변수 설정하기

설치된 Node version list 확인

'abumalick.vscode-nvmarrow-up-right' vscode extension 추가

vscode에서 nvm을 사용하기 쉽도록 도와주는 확장 프로그램

프로젝트 루트경로에 .nvmrc 설정 파일을 추가하여 사용할 노드 버전을 지정하면 nvm use 명령어를 실행하지 않고도 특정 노드 버전을 자동으로 사용할 수 있도록 관리해준다.

.nvmrc

해당 프로젝트의 vscode가 열리면 자동으로 nvm use 명령어가 실행되어 지정한 노드버전을 사용하도록 변경해준다.

nvm use는 로컬에 설치된 특정 노드 버전을 사용하도록 설정하는 명령어이다.

.vscode/extensions.json에 추가

.vscode/extension.json 에 추가하여 자동으로 해당 익스텐션을 설치할 수 있도록 설정하자.

yarn이 기본적으로 설치되어 있다고 가정

yarn version 변경하기

Yarn workspace 생성하기

루트 워크스페이스는 모든 프로젝트에 공통적으로 사용되는 패키지 의존성을 한번에 관리할 수 있다.

즉, 하위 워크스페이스에서 yarn install 명령어를 통해 루트에 설치된 패키지들을 사용할 수 있다.

yarn init -w 명령어는 yarn을 이용해서 프로젝트를 생성하는 명령어이다. -w 옵션은 현재 디렉토리를 루트 워크스페이스 디렉토리로 설정 (package.json 생성됨)

yarn berry cli 명령어 참고arrow-up-right

yarn cache 확인하기

  • enableGlobalCache 설정은 .yarnrc.yml 파일 내부에 설정 되있는것을 확인해 볼 수 있다.

apps/ 디렉토리 생성

실제로 서비스할 어플리케이션들을 모아놓는 디렉토리

circle-info

packages/apps/에서 사용할 공통 라이브러리 패키지를 모아놓는 디렉토리

package.json

추가한 apps 디렉토리를 워크스페이스 디렉토리의 package.json에 등록

프로젝트 패키지 추가해보기

apps/ 디렉토리 내에서 프로젝트를 생성해보자.

프로젝트 생성이 완료되었다면 해당 프로젝트의 package.json 을 수정

package.json

패키지의 범위를 설정하기 위해 프로젝트의 네임을 @ 접두어를 붙힌 @org/package 형식으로 변경

워크스페이스로 돌아가서 상태를 갱신

프로젝트가 추가되면 워크스페이스로 돌아가서 상태를 갱신 해주어야 한다.

해당 정보는 .pnp.cjs 에서 관리 된다.

yarn workspace [package name] [scripts] 로 워크스페이스 특정 패키지의 명령어를 사용하여 간단하게 실행할 수 있다.

circle-info

.pnp.cjs란? yarn berry pnp 관련 정보를 모아놓은 캐시 파일로 모든 의존성의 메타 정보(zip 경로, 의존성)와 ZipFS에 대한 처리 코드가 들어있다

Typescript 설정하기

타입스크립트 코드에 빨간줄이 생기면서 인식을 못하는 에러가 발생한다.

  • yarn berry는 node_modules 대신 패키지 의존성을 zip 파일 형태로 .yarn/cache에 저장하여 관리하는 plugin & play 모드를 사용한다.

  • 이런 방식의 차이 때문에 추가적인 설정이 필요하다.

circle-info

yarn dlx @yarnpkg/sdks vscode

  • yarn dlx 명령어를 통해 @yarnpkg/sdks 패키지를 vscode 환경에 설치

  • yarn에서 제공하는 플러그인 중 하나인 yarn sdk는 yarn을 이용해서 설치한 프로그램을 실행할 수 있도록 도와준다.

  • 즉, vscode가 zip 파일로 된 패키지들을 읽어올 수 있게끔 설정하는 것

  • typescript, eslint, prettier 이 패키지들은 .yarn/sdks 내에 설치된다.

'arcanis.vscode-zipfsarrow-up-right' vscode extension 추가

Yarn SDK와 함께 사용하면 캐시에서 파일을 원활하게 열고 편집할 수 있다.

.vscode/extensions.json에 추가

chevron-rightNext.js 모노레포 Typescript 이슈hashtag

다른 패키지(React.js)에서 내보내는 컴포넌트를(ts) 사용할 때 ts 해석을 하지 못한다.

  1. javascript로 변환시켜 주는 툴 설치

  1. next.config.json 수정

공통 패키지를 만들어보기

여러 패키지에서 공유하여 사용할 유틸 함수나 라이브러리를 관리하기 위해 packages/lib 폴더를 생성

package.json name 수정

tsconfig.json 설정

circle-info

패키지를 추가했다면 워크스페이스로 돌아가서 yarn 명령어를 입력해 갱신해주자.

다른 패키지에 의존성 추가하기

루트 워크스페이스 경로로 돌아가서 A 패키지에 B 패키지 의존성을 추가해보자.

@jtwjs/web 패키지를 확인해보면 아래와 같이 의존성이 추가된걸 확인할 수 있다.

circle-info

개발환경 설정 공유하기

tsconfig 설정 공유하기

프로젝트에서 공통적으로 사용되는 타입스크립트 설정을 한 곳에서 관리하여 중복되는 설정을 최소화한다.

circle-info
  1. 워크스페이스 경로에 tsconfig.base.json 파일을 생성하여 공통적으로 사용할 설정

  2. 각 프로젝트 패키지의 tsconfig.json 에서 extends 속성을 사용하여 재사용한다.

eslint & prettier 설정 공유하기

여러 패키지에서 공통적으로 사용되는 eslint & prettier 규칙을 공유하여 재사용하자.

기타 vscode 설정 추가

chevron-right.vscode/settings.jsonhashtag
chevron-right.vscode/extensions.jsonhashtag

Eslint & Prettier설정

eslint 설정 공유하기arrow-up-right

eslint 잘 활용하기arrow-up-right

chevron-rightEslint 설정 hashtag

가장 최상위 eslint 설정에 root: true 설정하고 커스텀을 위한 하위 eslint는 root: false 설정을 해주자.

chevron-rightPrettier 설정hashtag

모든 프로젝트에 공통적으로 실행할 명령어

workspace-toolsarrow-up-right 플러그인 설치

각 패키지 마다 공통적으로 동일한 네이밍의 스크립트를 일괄적으로 실행 시킬 수 있다.

circle-info

yarn workspaces foreacharrow-up-right 여러 패키지 대해 일괄적인 작업을 수행할 수 있는 명령어

  • -p: 병렬 실행

  • -v: workspace name 출력

typecheck

circle-info

개별적으로 특정 스크립트 실행하려면

Deploy

Github actions

  • .github/workflows 디렉토리 내에서 워크플로우(.yml)를 생성하여 배포 작업을 정의한다.

  • 모노레포의 경우 각 하위 프로젝트에 대해 배포 작업을 개별적으로 정의해야 한다.

  • 배포하기 전 관련 의존성을 모두 설치하는 작업이 추가 되어야 한다.

  • 관련 의존성을 설치하는 작업은 각 배포 워크플로우에서 공통으로 사용되기 때문에 composite actions를 사용하여 액션을 재사용해보자.

chevron-rightComposite actionshashtag

....

배포 하기 전 관련 의존성 설치하는 액션

chevron-rightdeploy.ymlhashtag

workflow dispatch를 사용하여 깃헙 저장소에서 수동으로 workflow를 실행할 수 있다.

여러 워크스페이스를 관리하는 상황에서는 수동으로 배포할 워크스페이스를 선택하는 방식도 꽤 유용해 보인다.

chevron-rightworkflow dispatchhashtag
circle-exclamation

Last updated