yarn berry, workspace

jojo·2022년 5월 2일
0

Yarn berry workspace를 활용한 프론트엔드 모노레포 구축기

이 글을 참고하여 yarn berry와 workspace를 이용한 monorepo 구축을 해봤습니다.
vscode를 사용한다고 가정하고 진행하겠습니다.

사전지식


모노레포?

모노레포에 대해서는 저번에 작성한 글에 있으니 참고하시면 좋을 것 같습니다.

yarn berry

yarn berry는 npm, yarn1 과 같은 package manager입니다.
기존 npm, yarn1에서 사용하는 node_module의 단점을 해소하기 위해 만들어졌습니다.

여러 특징이 있는데, 간략하게만 적자면

1. pnp 지원
pnp는 plug&play의 약자로 기존의 node_module 방식과 다르게 pnp.cjs 파일로 dependency를 관리하고 zero install을 사용한다면 cache된 파일들을 직접 git에 올려놓음으로써 사용자들이 같은 환경에서 개발을 할 수 있다는 장점이 있습니다.

2. 유령 의존성 문제가 생기지 않는다.
node_module을 사용하다 보면, node_module이 최적화를 위해서 밑의 그림과 같이 모듈들의 끌어올리게(hoisting) 되는데 이때문에 package.json에 명시되지 않은 모듈들을 사용하는 유령의존성 문제가 생길수 있습니다. (하단 그림 참고)

3. require, import 명령어에 걸리는 시간이 node_module 사용할때보다 빠르다.
node_module을 통한 패키지 찾기는 해당 패키지를 찾기 위해서 계속해서 상위 디렉토리의 node_modules 폴더를 탐색하는데, 바로 찾지 못한다면 느린 I/O 명령어를 계속 실행하게 되어 비효율적입니다.

하지만, pnp를 사용하게 되면 pnp.cjs에 path에 대한 정보가 명시되어 있기 때문에, 위의 그림처럼 느린 I/O 명령어로 찾아갈 이유가 없습니다.

	//pnp.cjs
 	["react", [\
        ["npm:18.0.0", {\
          "packageLocation": "./.yarn/cache/react-npm-18.0.0-fdbcb4c477-293020b965.zip/node_modules/react/",\
          "packageDependencies": [\
            ["react", "npm:18.0.0"],\
            ["loose-envify", "npm:1.4.0"]\
          ],\
          "linkType": "HARD"\
        }]\
      ]],\

yarn workspace

IDE에서 여러 프로젝트가 모여 있는 공간을 작업 공간을 워크스페이스라고 부릅니다. yarn에서 말하는 workspaces도 같은 뜻입니다. 이 워크스페이스에 있는 프로젝트들은 서로 참조하는 연관 관계를 맺을 수 있습니다. Lerna와 Yarn workspaces를 활용한 패키지 관리

구성 계획 및 방법

yarn 설치

npm install -g yarn

프로젝트 폴더 생성 및 yarn berry set

mkdir {workspace 이름}
yarn set version berry

init

yarn init

project.json 설정

{
  ...
  "private": true,
  "workspaces": {
    "packages": [
      "package/*"
    ]
  },
  "scripts": {
    "lint": "eslint ./package --ext .ts,.tsx,.js,.jsx --cache",
    "project-a": "yarn workspace project-a",
    "project-b": "yarn workspace project-b",
    "test:all": "yarn workspaces foreach --parallel run test"
  }
  ...
}

project-a, project-b 만들기

mkdir package
yarn create vite 
or
npx create-react-app

common-styles 만들기

제 경우에는 그냥 테스트여서 밑에 참고 링크에 있는 예제 코드중 하나를 복붙해서 만들었습니다.

typescript 설정

각 프로젝트로 들어가게 되면, 아마 type에러가 뜰텐데 root로 가서

yarn add -D typescript prettier eslint
yarn dlx @yarnpkg/sdks vscode

command + shift + p 
typescript select를 root의 .yarn/sdks/typescript/lib에 있는 버전을 선택한다.
그럼 해결될겨

workspace 설정

1. root에 workspace.code-workspace 생성

2. workspace.code-workspace
//
{
  "folders": [
    {
      "path": "package/common-styles"
    },
    {
      "path": "package/project-a"
    },
    {
      "path": "package/project-b"
    }
  ],
  "settings": {
    "typescript.tsdk": "../../.yarn/sdks/typescript/lib",
    "typescript.enablePromptUseWorkspaceTsdk": true
  }
}

tsconfig.base.json 작성

//tsconfig.base.json
{
  "references": [
  	// 여기에 lib가 추가될때마다 이런식으로 path 작성해주면됨.
    {
      "path": "package/common-styles"
    }
  ],
  "exclude": ["package/**/dist/**"],
  "include": []
}

각 프로젝트의 tsconfig.json 작성

{
  "extends": "../../tsconfig.base.json",
   ...
}

prettier, eslint 작성은 생략하겠습니다. 코드 참고해주세요.

prettier는 별거 없이 똑같이 root에 작성하면 됩니다.
하지만, eslint의 경우 타입스크립트 프로젝트에서 alias 설정을 통해 import 경로를 단축해 사용하고자 하는 경우 보통 tsconfig.json의 compilerOptions → paths 옵션을 설정하게 됩니다. 저희는 eslint에서 import 관련 린팅을 담당해 주는 플러그인인 eslint-plugin-import에서 typescript의 resolve 로직을 활용할 수 있도록 eslint-import-resolver-typescript 플러그인을 함께 사용했는데, 단독 프로젝트의 경우 resolver에 아래 설정을 더해주면 편하게 사용이 가능했습니다.
Yarn berry workspace를 활용한 프론트엔드 모노레포 구축기

https://github.com/Kwonkunkun/test-yarn-workspace


참고

Yarn berry workspace를 활용한 프론트엔드 모노레포 구축기
node_modules로부터 우리를 구원해 줄 Yarn Berry
Lerna와 Yarn workspaces를 활용한 패키지 관리

profile
프론트 주니어

0개의 댓글