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

Gompro
직방 기술 블로그
6 min readApr 22, 2021

--

안녕하세요. 직방 백엔드 팀에서 메세징 시스템을 담당하고 있는 이준형입니다.

백엔드 팀은 현재 10여 개의 사내 패키지를 개발 및 운영하고 있는데요.

오늘은 패키지를 배포하지 않고, 로컬 환경에서 효과적으로 테스트하는 방법에 관해 얘기해보려 합니다.

Yarn link

yarn 패키지 매니져는 패키지를 로컬 환경에서 테스트할 수 있게 해주는 yarn link 커맨드를 제공합니다. 문서에 의하면 yarn link

Symlink a package folder during development

즉, 개발하는 동안 패키지 폴더에 심볼릭 링크를 생성합니다.

이 말은 프로젝트의 node_modules/<package> 와 로컬 환경의 package 폴더 간에 심볼릭 링크가 생긴다는 말인데요. link후에 패키지의 코드를 수정하면 수정 사항이 곧바로 프로젝트에 반영되기 때문에, 패키지를 배포 - 설치할 때보다 훨씬 빠르게 테스트를 할 수 있습니다.

사용법도 복잡하지 않습니다. 문서를 보면

명령어만 몇 번 입력해주면 됩니다.

Problem?

하지만 yarn link 가 만능은 아닙니다.

아래와 같은 상황을 생각 해봅시다.

packageApackageB (편의상 A, B 라고 부르겠습니다.)는 각각 peerDependency / dependency 로써 typeorm 을 사용하는 상황입니다.

(참고: node.js의 peerDepdency란?)

두 패키지를 프로젝트에 설치하면 node_modules 는 아래와 같은 구조가 됩니다.

여기서 typeorm 은 한 버전만 설치됩니다.

하지만 yarn link 를 사용할 경우 B 패키지 폴더 전체에 심볼릭 링크가 생성되기 때문에 아래와 같이 두 개의 typeorm이 존재하게 됩니다.

이때 B 는 자신의 typeorm (B/node_modules/typeorm)을, A 는 프로젝트의 typeorm (node_modules/typeorm)을 사용합니다.

이 경우 아래 코드에서 의도하지 않은 현상이 발생합니다.

  1. B 패키지는 typeormexport
  2. 프로젝트는 Bexport 하는 typeormRepository 클래스를 상속
  3. A 는 인자로 받은 엔티티가 typeormRepository 클래스인지 확인한 뒤 레포지토리명을 리턴

yarn link를 사용하지 않는 경우에는 프로젝트에 하나의 typeorm 패키지만 존재하므로 instanceof 가 참이 되어 제대로된 레포지토리명을 리턴하지만, 반대의 경우 에러가 리턴를 리턴합니다.

이를 해결하는 한 가지 방법은 typeorm을 의존하는 모든 모듈이 강제로 한 경로를 바라보게 만드는 방법입니다.

이 방식은 간단하지만 별도의 코드를 요구합니다. yarn link를 사용하는 모든 프로젝트에 동일한 코드를 넣어야된다는 점이 부담으로 다가오죠.

Yarn pack

다른 방법은 yarn pack 명령어를 이용하는 방법입니다. (문서)

yarn pack 은 설치 가능한 패키지 압축 파일을 생성하는 명령어인데요.

프로젝트의 package.json 에 해당 압축 파일을 사용한다고 명시하고, 인스톨하면 패키지를 사용하는 모든 파일에서 압축 파일의 내용을 바라봅니다.

이 방법을 사용할 경우 실제 배포된 패키지와 동일한 파일 구성을 가지고 있기 때문에, 앞서 언급한 문제가 발생하지 않습니다. 하지만 심볼릭 링크를 사용할 때처럼 간단히 코드를 고치는 것만으로 변경 사항이 반영되지 않습니다. 매번 압축 파일을 빌드하고, 인스톨하는 과정을 거쳐야만 하죠.

Yalc to the rescue!

yalc는 더 나은 yarn link를 목표로 하는 라이브러리입니다. yalc 는 직접 압축 파일을 생성/복사하고 설치하는 대신, 로컬 레포지토리를 만들어 패키지를 손쉽게 설치/업데이트할 수 있게끔 도와줍니다. (참조: yalc~/.yalc 경로에 패키지를 저장합니다.)

yalc 는 패키지를 패키징한 뒤 (yarn pack), 해당 파일을 로컬 레포지토리에 저장합니다. yalc 를 사용할 경우 node_modules 까지 심볼릭 링크를 생성하는 yarn link 와 달리 패키징된 결과물만 저장하므로, 서로 다른 경로에 존재하는 동일한 패키지 문제가 발생하지 않습니다.

yalc의 다른 장점은 사용법이 직관적이라는 것입니다.

  • npm에 배포하듯 패키지를 로컬 레포지토리에 배포하고 (yalc publish),
  • 프로젝트에서 yalc add <package> 를 통해 설치하고,
  • 수정 사항이 생기면 패키지에서 다시 yalc publish 하고,
  • 프로젝트에 yalc update <package> 합니다.

publish - add/update 로 이어지는 플로우는 기억하기 쉽고 자연스럽습니다.

yalc 는 편의 기능도 함께 제공하는데요, 최초 설치 (yalc add) 이후 수정 단계에서는 yalc publish - yalc update 대신에 yalc push 명령어를 사용하여 한 번에 배포와 수정을 진행할 수 있습니다.

별도로 빌드가 필요한 타입스크립트 프로젝트 같은 경우에는 아래 명령어를 통해 transpile 과정과 yalc push 를 함께 사용할 수도 있습니다.

이제 코드를 수정하면 빌드된 코드가 자동으로 프로젝트에 반영됩니다! 🎉

yalclink 도 지원합니다. yalc link 를 사용하면 yarn link 처럼 로컬 환경에 저장된 패키지 파일에 직접 심볼릭 링크를 생성하는 대신 로컬 레포지토리 의 패키징된 패키지 파일에 심볼릭 링크를 겁니다. yalc link 를 사용하면 package.json 을 수정하지 않고도 테스트할 수 있죠.

더 나은 개발자 경험

yalc는 패키지 테스트 과정을 단순하고 직관적으로 만드는 툴입니다. 명령어를 몇 번 입력해보면 금방 사용법을 파악하고 사용할 수 있죠. 테스트 과정이 덜 고통스러울수록 더 자주, 더 많이 테스트를 진행하고, 결과적으로 코드 퀄리티를 높일 수 있습니다. 사용자에게 직접적으로 영향을 미치는 기능을 추가하고 고도화하는 것도 중요하지만, 개발자 경험(Developer Experience, DX)을 높이는 일도 그에 못지 않게 중요합니다. 현재 사용 중인 툴의 문제점을 찾아내고, 더 나은 툴을 도입하면 시간을 절약하고 실수를 줄일 수 있습니다.

긴 글 읽어주셔서 감사합니다!

--

--