yarn link vs yalc, 공통 모듈 관리를 부탁해!

GY·2023년 9월 4일
1

monorepo

목록 보기
1/1
post-thumbnail

Overview

  • 모노레포를 도입하는 과정에서, 모노레포 도입이 완료되기 전까지 다른 업무를 병행하면서 개발생산성을 향상시키기 위한 방법이 필요했습니다.

  • 여러 레포들이 공통으로 사용하는 utils함수와 컴포넌트들이 흩어져있었고, 각각의 레포들에 동일한 모듈에 대한 수정 PR을 올려주어야 했습니다.
    그래서 모노레포가 도입되기 전까지 개발 생산성 향상을 위해 공통모듈을 관리하기 위한 방법을 도입하기로 했습니다.

  • 처음에 yarn link를 도입했고,

  • 의존성 관리에 대한 단점을 발견해 이후 yalc를 사용했습니다.


그래서...

  • 어떤 고민을 하고 있었고
  • yarn link는 무엇이고, 왜 사용했고
  • yarn link를 사용했을 때의 문제점은 무엇이었고
  • yalc로 어떻게 해결했는지

이야기 해보려 합니다.


yarn link를 도입하자

여러 선택지가 있었지만 yarn link를 사용하기로 최종적으로 결정했습니다. 패키지매니저로 yarn을 사용하고 있었기 때문에 yarn에서 제공하는 yarn link를 사용하는 것이 간편한 선택지였고, 사용법 또한 충분히 쉽고 간편했습니다.

다른 선택지들은 고려하지 않았나?

여러 선택지들이 있었습니다!

  • Yarn workspace
  • yarn pack
  • yarn link
  • yalc
    ...

다른 선택지들도 있었지만 빠르게 yarn link를 사용하기로 결정했습니다.
애초에 목적이 모노레포 도입 전의 개발 업무를 돕기 위함이었으므로, 이 경우에는 너무 많은 선택지를 충분히 조사하고 고려하는 것보다는 빠른 결정과 실행이 더 중요했습니다.


심볼릭 링크로

yarn에서 제공하는 커맨드로, 개발환경에서 패키지 폴더에 대한 심볼릭 링크를 생성하는 원리입니다.
node_modules/<package>와 로컬 환경의 package 폴더가 심볼릭 링크로 연결되어 패키지를 배포하지 않아도 로컬환경에서 테스트할 수 있습니다.

따라서 별도의 공통 패키지를 생성한 다음 개발 환경에서 yarn link를 사용해 별도 배포 없이 수정사항을 반영해 개발할 수 있었습니다.

간편한 사용법

yarn link로 심볼릭 링크를 생성한 다음,
yarn link <package>로 심볼릭 링크를 원하는 패키지에 연결해줍니다.


yarn link의 단점

그러나 사용해보니 심볼릭 링크를 사용하는 yarn link의 특성상 막상 고려해야 하는 부분들이 더 존재했습니다.


의존성 관련 문제

먼저 yarn link의 심볼릭 링크 생성을 통한 로컬 패키지 관리 방식을 살펴봐야 합니다.

오류가 발생하는 상황을 가정해볼게요.

projectA, projectB, projectC 세 개의 프로젝트가 있습니다.
각 프로젝트에서는 공통으로 packageD import해 사용합니다.

편의상 projectA와 packageD의 경우만 다루겠습니다. (다른 프로젝트도 동일한 이슈이기 때문에)

projectA를 실행하면 packageD를 import해 사용하려 할 때 packageD 내부에서 react가 null이기 때문에 useEffect를 사용할 수 없어 오류가 발생했습니다.

yarn link의 의존성 문제 (1)

stack overflow - Does yarn link follow yarn-links in dependencies

Unsolving the mysteries of yarn/npm link for libraries development
이 글을 참고했을 때, 링크된 패키지의 React 의존성으로 인해 로컬로 연결했을 때 여러개의 React 의존성이 생겨 디버그 하기 어려운 오류가 발생합니다.

여러 오류가 발생할 수 있는데, 그 중엔 이런 오류들도 있습니다.

Unhandled Rejection (Invariant Violation): Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.

이를 해결하기 위해 packageD에서 projectA로 react에 대한 심볼릭링크를 생성해 사용해야 합니다.
혹은 웹팩 구성에 특정 패키지를 위한 resolver를 추가해 해결할 수 있는 방법도 있다고 합니다.


yarn link의 의존성 문제 (2)

Yalc: npm 패키지를 테스트하는 더 나은 방법

이 글에서도 의존성 관리 측면에서 yarn link 사용시 고려해야 할 점을 찾아볼 수 있습니다.

각각의 패키지에서 동일한 버전의 동일한 의존성을 갖고 있다고 했을 때,

packageA
    peerDependency: typeorm >= x.y.z

packageB
    dependency: typeorm x.y.z

프로젝트에서 각 패키지를 설치하면 해당 의존성이 설치가되지만

node_modules
    packageA
    packageB
    typeorm x.y.z

yarn link의 심볼릭 링크가 패키지B 폴더 전체에 생성되어 두개의 의존성 버전이 존재하게 됩니다.

node_modules
    packageA
    packageB (symlinked)
        node_modules
	    typeorm x.y.z (1)
    typeorm x.y.z (2)

이때 B 는 자신의 typeorm (B/node_modules/typeorm)을, A 는 프로젝트의 typeorm (node_modules/typeorm)을 사용하게 되는 것이죠.

이럴 경우 패키지B에서 import해 사용하는 모듈이 에러가 발생할 수가 있습니다.

이럴 경우 해당 의존성을 사용하는 모든 모듈이 강제로 한 경로를 바라보게 만드는 방법으로 해결할 수 있으나, 추가적인 코드가 필요하다는 단점이 있습니다.


yalc로의 전환

그래서 yarn link를 사용하며 계속해서 이러한 이슈들을 핸들링하기보다는, yalc로 전환하는 것이 더 효율적인 방법이라 판단해 방식을 교체했습니다.

yalc?

yalc는 yarn link와는 다른 방식으로 패키지를 로컬에서 사용할 수 있도록 해줍니다.

~/.yalc 경로에 패키지를 패키징한 뒤, 로컬 레포지토리를 만들어 패키지를 손쉽게 설치/업데이트하도록 합니다.

yarn link와의 차이

yarn link는 node_modules까지 심볼릭 링크를 생성하지만
yalc는 패키징된 결과물만 저장하기 때문에 동일한 패키지의 여러 다른 경로로 인한 문제가 발생하지 않습니다. 따라서 이 문제를 해결하기 위한 추가적인 코드도 필요하지 않습니다.

yalc 사용법

yalc publish로 로컬 레포지토리에 패키지를 배포합니다.
yalc add <package>로 프로젝트에 패키지를 설치합니다.

수정하는 방법도 간단합니다.
yalc publish해 수정사항을 퍼블리시하고 yalc update <package>로 수정된 패키지를 업데이트 하면 됩니다.

yarn link말고 yalc에서 지원하는 yalc link도 있습니다.
yarn link는 로컬 환경에 저장된 패키지 파일에 직접 심볼릭 링크를 생성하지만,
yalc link는 로컬 레포지토리에 패키징된 패키지 파일에 심볼릭 링크를 겁니다. 따라서 package.json을 수정하지 않아도 테스트할 수 있습니다.


profile
Why?에서 시작해 How를 찾는 과정을 좋아합니다. 그 고민과 성장의 과정을 꾸준히 기록하고자 합니다.

0개의 댓글