yarn berry 적용기(2) 프로젝트 적용기

Donghoon Nam
원티드랩 기술 블로그
10 min readJul 14, 2021

--

안녕하세요. 프론트엔드 팀 남동훈 입니다.

이전내용에는 yarn berry가 나오게 된 배경에 대해서 설명을 드렸고,
이번에는 실질적으로 프로젝트에 적용한 것과 적용하면서 알게 된 것들을 공유해보고자 합니다.

사례를 두 가지로 나눠서 얘기할 수 있도록 해보겠습니다.

업그레이드 성공 사례와 실패 사례

1편 기존 npm, yarn v1의 이슈와 yarn v2에 대한 이야기
2편 실질적으로 프로젝트에 적용한 사례
3편 monorepo에 적용한 사례

우선 업그레이드를 진행하기 전에 현재 진행하고 있는 여러 프로젝트 중에 어떤 프로젝트에 적용하는게 수월할지에 대해 호환성 테이블을 참고 하였습니다.

Compatibility Table

업그레이드 성공 사례

위의 호환성 테이블 이상의 버전을 쓰고 있는 프로젝트가 다행히 존재하고 있어 해당 프로젝트를 진행하는 팀분에게 양해를 구하고 적용을 진행하게 되었습니다.

해당 프로젝트의 주요 패키지 버전 리스트 입니다.

Compatibility Table과 현재 적용할 프로젝트의 패키지와 비교해보니 이상 무
Node버전도 14.x버전 이상 무
자 이제 기반은 준비되어 있으니 시작해보려고 합니다.

  1. yarn upgrade
yarnV2.sh

간단한 shell script를 만들어 yarn2를 쉽게 설치/사용할 수 있도록 만들었습니다.
실행 기준은 bin/sh이고, 한번만 실행하면 되고 혹시나 다시 실행한다고 해도 다시 설치하지 않고 skip합니다.

  • vscode-zipfs
    yarn2에서는 패키지를 zip파일로 관리하기 때문에 extract, resolve를 하기 위해서 vscode내에서는 확장 프로그램을 추가로 설치하여 사용합니다.

아래와 같이 vscode-zipfs를 사용하면 packageLocation에서 처럼 zip파일내의 node_modules디렉토리를 resolve할 수 있습니다.

위와 같이 yarn set version <version>설치 시 현재 repository에만 적용이 됩니다.
https://yarnpkg.com/cli/set/version

위에서는 설정되어 있지않지만 yarn2에서는 typescript, eslint를 vscode와 연동을 해줄 수 있습니다.

위의 문서에 있는 다음과 같은 명령어를 실행할 때에는 제약이 있습니다.

nodejs12버전 이하에서는 아래와 같은 명령어를 실행 시 다음과 같은 work_threads가 선언되어 있지 않아 접근할 수 없다는 에러가 발생합니다.

$) yarn dlx @yarnpkg/pnpify --sdk vscode

Error: @yarnpkg/core tried to access worker_threads, but it isn’t declared in its dependencies; this makes the require call ambiguous and unsound.

node12이상 버전에서만 아래의 코드가 실행 가능합니다.

2. .gitignore 파일 설정

위의 FAQ를 참고하여 Zero-Installs를 사용한다는 가정하에 ignore를 설정하였습니다.
참고로 node_modules를 사용하지 않기 때문에 기존에 설정했던 내용들은 삭제해 주시면 됩니다.

3. .yarnrc.yml설정

.yarnrc.yml파일은 yarn의 internal setting이며 프로젝트의 최상단에 yarn2설치 시 자동으로 생성이 됩니다.

yarn또는 패키지, 환경변수들을 세팅할 수 있습니다.

원티드에서는 패키지 관리를 github packages를 이용해 관리하고 있어 url을 https://npm.pkg.github.com 으로 설정하였습니다.
url은 패키지를 관리하는 곳의 url을 설정하시면 됩니다.

4. yarn install

위의 내용을 다 설치하고 나면 yarn install 을 통해 패키지 설치를 합니다.

배포를 하고 나면 다음과 같이 .yarn/cache 디렉토리에 package들이 zip파일로 압축되어 있습니다.

yarn package

위와 같이 completed in seconds 메세지가 나오면 설치가 완료된 겁니다.
앞의 YN00XX는 에러 코드 메세지 입니다.

위의 YN0000은 log메세지 입니다. 에러코드가 아니니 저게 나오면 신경 안쓰셔도 됩니다.
에러 메세지는 다음을 참고해주시면 됩니다.

5. dev, build실행

위의 yarn설치, 세팅이 다 완료가 되었다면 local에서 dev, production build실행을 꼭 해보셔야 합니다.

이유는 이전에 얘기되었던 yarn v1버전의 이슈 중 유령의존성(ghost dependency)에 의해 설치되었고, 내가 설치하지 않았지만 사용되어졌던 패키지들이 존재하기 때문에 관련된 에러를 발견하고 수정해야 합니다.

  • dev실행

위와 같이 설치되어 있지 않은 패키지는 설치를 진행해주면 됩니다.

주의해야할 점은 패키지 설치 시 기존 연동된 패키지의 버전을 고려하여 패키지를 설치해주어야 합니다.

  • build

위에서 dev 서버 실행/수정 등에 문제가 없었다면 production형태로 빌드도 진행해보아야 합니다.

dev상의 문제는 해결을 했지만 production형태의 빌드는 다른 설정, 코드들이 있기 때문에 이 부분까지 해결해야 합니다.

위와 같이 production형태의 build도 무사히 통과되었습니다.

나머지는 체크와 CI빌드 테스트가 남았습니다.

6. 다시 yarn install로 설치 속도 확인 및 이상 여부 재체크

7. dev, build재실행

8. git에 .yarn/cache, .pnp.js, .yarnrc.yml commit/push

6,7번이 문제가 없었다면 yarn2의 설정, 설치 패키지들을 commit/push하여 Zero-Installs을 사용할 준비를 합니다.

기존 yarn1에서 설치했던 node_modules의 크기가 330MB정도였고,
yarn2로 옮긴 다음에 .yarn/cache의 용량은 100MB로 줄어들었습니다.

이제 CI를 통해 배포를 진행하면 속도가 얼마나 빨라지는지 확인해보도록 하겠습니다.

9. ci(github actions)에서의 캐시 설정

yarn2의 Zero-Installs를 쓰고 있다면 yarn install 외의 별도의 캐시는 필요하지 않다고 합니다.

Zero-Installs를 쓰지 않는 경우 cache를 사용하는 방법에 대해서도 설명하고 있습니다.

CircleCI의 yarn2.x 문서를 참고하시면 좋을거 같습니다.

10. ci 배포 단축 시간 확인

  • 패키지 설치 및 next.js build

yarn1.x 사용

yarn1.x를 사용한 yarn install, build 시간

yarn2.x 사용 Zero-Installs

yarn2.x를 사용한 yarn install, build 시간

네트워크 속도 등에 따라 조금의 오차가 존재하긴 하지만 약 50초가량의 시간을 절약이 되었습니다.

  • docker 용량

yarn1.x 사용

약 340MB

yarn2.x 사용

약 273MB

Docker Image용량을 약 70MB를 절약할 수 있었습니다.

위의 내용의 결과는 다음과 같이 전체 배포 시간이 2분가량 줄어드는 효과를 보았습니다.

기존 : 7~8분

변경 : 5~6분

성공한 케이스를 신나게 얘기했으니 실패한 케이스에 대해서도 얘기해보려고 합니다.

업그레이드 실폐 사례

위의 성공에 고무되어서 기존 도메인들도 업그레이드 해보자 하고 시도해 보았으나 적용하지 못한 사례를 얘기해보려고 합니다.

  1. 기존 패키지의 버전이 위의 호환성 버전에 맞지 않아 패키지가 제대로 설치되지 않았습니다.
  2. CopyWebpackPlugin 을 사용하는 도메인도 있었는데, 플러그인 자체도 예전 버전이고 node_modules(yarn2는 .yarn/cache에 패키지가 설치됩니다.)의 파일을 참조하여 복사하는 부분이 있었는데 이 부분이 해결 되지 않았습니다.
  3. 1, 2번 내용 중 패키지 버전을 넘어 레거시 호환을 유지하면서 설치 할 수 있는 Yarn Migration 문서를 참고하였으나 이전 yarn1에서 설치되었을 때는 생기지 않았던 typescript 에러(__spreadArray) 에러가 발생하여 진행하지 않았습니다.
    아마도 yarn2에서 패키지를 설치하면서 yarn1에서 하는 방식이랑 다르다보니 유령 의존성 관련해서 깨지는 부분이 있는게 아닌가 의심을 해보았습니다.
  4. 위의 내용들을 해결해보고자 패키지 버전을 업그레이드 해보는 테스트를진행했고 Migration을 성공했으나 변경된 패키지에 맞게 모든 코드를 손보는 상황이 되다보니 더 이상 진행하지 않았습니다.

yarn 버전을 업그레이드 진행해보면서 느낀 점은 신규 프로젝트 진행 시에 적용하거나 호환성 테이블에 맞는 버전이 있다면 충분히 적용해서 그에 따른 효과를 볼 수 있지만 호환성 테이블에 맞지 않는 버전을 쓰는 프로젝트에 적용하기에는 부수적인 문제와 테스트의 한계를 느끼게 되었습니다.

하지만 할 수 있다면 하는게 설치, 배포, 코드 빌드의 속도에 좋은 효과를 볼 수 있다고 생각됩니다.

다음 편은 시간이 걸릴거 같긴 하지만 lerna제거와 yarn workspace, yarn plugins로 monorepo를 구축하는 것에 대해서 얘기해보려고 합니다.

Yarn Workspaces vs Lerna

Despite the appearances, the Yarn workspaces and Lerna don’t compete. In fact, Lerna will use Yarn’s workspaces if possible. In a sense, you can see Lerna as a high-level layer on top of the low-level Yarn implementation.

이렇게 얘기해주고 있긴 하지만…

원티드에서 현재 다양한 포지션을 채용하고 있습니다.

원티드 채용공고 확인하기

--

--