Priority of ‘.yarnrc’, ‘.npmrc’

로고 출처: https://yarnpkg.com/

회사에서 yarnrc와 npmrc로 인해 발생한 이슈를 해결하다가 발생한 이유 그리고 진행한 실험을 블로그로 정리해보았습니다. 빠르게 결론만 보고 싶으신 분은 결론 섹션으로 가시면 됩니다.

내용에 틀린점이 있거나 피드백이 있으면 코멘트 남겨주세요!

시도 배경

회사에서 구매한 외부 private 라이브러리를 쓸 일이 생겨서, 문서화와 세팅을 같이 할겸 로컬과 CI/CD 툴에 .yarnrc세팅을 시도했었습니다(회사에서 yarn을 사용중이기 때문에 yarn에 세팅을 저장해뒀습니다). 총 3군데에 .yarnrc를 세팅했습니다.

  1. 회사에서 작업하기 위한 개인용 컴퓨터
  2. PR 검증을 위한 Github Actions 빌드
  3. 실배포를 위한 CI/CD 툴 빌드

1번과 같은 경우 다른 프로젝트에서도 같은 라이브러리를 사용할 일이 있을 것 같아 세팅을 루트 디렉터리에 저장했습니다. 다만 루트 디렉터리에 생성되는~/.yarnrc는 자동생성되기 때문에 직접 건드리는 파일이 아니라서 ~/.npmrc에 세팅을 추가하였습니다.

2, 3번은 직접적으로 private 저장소의 토큰을 노출시키는 것은 위험하기 때문에 Secrets와 같은 위치에 저장한 다음, 빌드 스크립트에서 아래와 같은 라인을 추가했습니다.

yarn config set {auth_token} {secret}

빌드 세팅을 하면서 테스트를 진행했는데, 1번을 제외한 나머지 2, 3번에서 문제가 발생했었는데 저장소에 접근하지 못하는 이슈였습니다.

// previous settings// private registry 세팅은 프로젝트 최상위의 .yarnrc에 들어있다.
yarn config set //foo.bar.baz/:_authToken {auth_token}
// Install dependencies

정상적으로 registry와 auth token을 설정해줬음에도 불구하고, 401 오류가 뜨면서 계속 빌드 오류가 났었고 토큰에 문제가 있었는지, 아니면 레지스트리가 잘못됐는지를 계속 스크립트를 수정하면서 재시도했지만 모두 실패했었습니다.

처참한 빌드 실패의 현장

열심히 스크립트를 수정하면서 해결책을 찾다가 우연히 팀원분의 도움으로 yarn이 아닌 npm에 config을 적용해보면 어떨까하셔서 npm config으로 변경했습니다.

// previous settings// private registry 세팅은 프로젝트 최상위의 .npmrc에 들어있다.
npm config set //foo.bar.baz/:_authToken {auth_token}
// Install dependencies

성공했다. ??

왜 성공했는지 궁금해져서 이것저것 시도를 해보기로 했고, 다음 섹션에 진행과정을 적어보았습니다.

우선순위 실험

npmrc와 yarnrc 중 어느 설정이 우선순위가 높은지 실험을 진행해보았습니다. 사실 npm만 사용한다면 yarn 설정은 신경 쓸 이유가 없기 때문에 yarn을 사용하시는 분들에게만 실험 내용이 쓸모있을 것 같습니다.

먼저 맥을 기준으로 설정 파일들의 종류와 위치를 정리했습니다.

Global npm config

~/.npmrc에 저장되어 있습니다.

Global yarn config

앞에서도 설명했듯이 ~/.yarnrc에 저장되어 있지만, 이 파일은 자동으로 생성되는 파일이기 때문에 건드리지 않았습니다.

# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


lastUpdateCheck 1606286290542

Local npm config

package.json이 있는 디렉터리의 .npmrc

Local yarn config

package.json이 있는 디렉터리의 .yarnrc

실험을 진행하기 위해 각 설정 파일들에 레지스트리를 넣어보았습니다.

~/.npmrc

@test:registry=https://foo.foo

local .npmrc

@test:registry=https://bar.bar

local .yarnrc

"@test:registry" "https://baz.baz"

설정을 모두 완료한 뒤, yarn add @test/test 를 입력하여 디펜던시를 설치하면 어느 URL이 registry에 등록되었는지 확인해보았습니다.

info There appears to be trouble with your network connection. Retrying...
error An unexpected error occurred: "https://bar.bar/@test%2ftest: getaddrinfo ENOTFOUND bar.bar".
출처: 자이언트 펭TV

local npm config을 먼저 받고 있었습니다. 혹시나 yarnrc에 설정이 제대로 들어가지 않았나 궁금해서 yarn config list 를 입력하였습니다.

info yarn config
{
'@test:registry': 'https://baz.baz'
}
info npm config
{
'@test:registry': 'https://bar.bar'
}

잘 들어간걸 확인할 수 있었습니다.

??

yarn 설정이 있어도 npm 설정이 있다면 우선순위를 더 높게 쳐주는 듯 했습니다.
그렇다면 local npm 설정을 제거하고 global npm 설정과 local yarn 설정만 남겨놓는다면 어떻게 될지 궁금하여 프로젝트의 .npmrc를 지운뒤 다시 디펜던시 설치를 시도했습니다.

info There appears to be trouble with your network connection. Retrying...
error An unexpected error occurred: "https://foo.foo/@test%2ftest: getaddrinfo ENOTFOUND foo.foo".

???

global npm 설정이 local yarn 설정보다 우선순위가 높았습니다. 왜 그런지는 정확히 알 수가 없었는데 이유를 아시는 분은 코멘트를 부탁드립니다. 🙏

결론

실험 결과는 npmrc가 yarnrc보다 우선순위가 높았습니다.

local npmrc > global npmrc > local yarnrc
// global yarnrc는 자동생성이므로 우선순위 대상에서 제외

결론적으로는 레지스트리 설정을 할 일이 있다면 npmrc에 저장해도 yarn 사용에 문제가 없을 것 같습니다.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store