yarn berry(pnp)에서 lint 동작시 synckit 관련 에러가 발생할 때

myungki chun·2024년 1월 1일
1

이 이야기는 또 똑같은 삽질을 방지하기 위해 기록해두는 내용임을 알려드립니다.

yarn berry(pnp) + eslint + typescript + prettier + NextJS 조합으로 프로젝트를 구성하던 중 eslint를 테스트하다 발생한 에러를 가지고 장장 2주 정도를 고민하며 결국 끈기와 근성으로 에러를 해결한 이야기입니다. 인간은 매번 똑같은 실수를 반복하지만 실수를 겪는 과정이 꽤나 고통스러워 기록으로 남겨두면서 해결했던 분투기를 나름 정리해 봅니다.

yarn berry는 생각보다 개발자에게 깊은 사용법을 요구할지도 모릅니다.

우리가 yarn이나 npm을 자주 사용하는데요. node_modules의 의존성 관리 문제를 해결할 수단으로 yarn berry를 선택할수 있습니다. 이러한 패키지 매니져들은 전역과 지역에 설치되는 패키지들을 어떠한 순서로 사용할지 나름의 규칙을 가지고 있고 그 규칙을 개발자가 알고 있어야 에러가 나도 삽질하는 시간을 줄여 줍니다.

문제는 이 규칙들이 패키지 매니져들 마다 다르고 업데이트도 자주 있다는 겁니다. 그 과정에서 버그도 존재하겠죠?
우린 언제나 등뒤에 닌자도처럼 삽을 가지고 있으니까 그 삽을 놓지만 않으면 되는 겁니다.

발생했던 에러는 이렇습니다.

저는 테스트를 해보기 위해 터미널에서 yarn lint 를 실행했습니다.

package.json > scripts 에 lint는 next lint 입니다. eslintrc는 구글링만 해도 많이 나오는 내용 중 필요한 내용들만 짜집기해 만들었습니다.

synckit tried to access ", but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.

Required package: " (via ""/var/folders/js/xf2g55cn2tn4fg4_w1mqmb300000gn/T/ec7437886cd2460735c97dfbf6df5f0b.cjs"")
Required by: synckit@npm:0.8.8 (via /Users/a1/working/{프로젝트명}/.yarn/cache/synckit-npm-0.8.8-f5ee4a6dac-c3d3aa8e28.zip/node_modules/synckit/lib/)

Require stack:
- /Users/a1/working/{프로젝트명}/.yarn/cache/synckit-npm-0.8.8-f5ee4a6dac-c3d3aa8e28.zip/node_modules/synckit/lib/index.cjs
- /Users/a1/working/{프로젝트명}/.yarn/__virtual__/eslint-plugin-prettier-virtual-b750797a37/0/cache/eslint-plugin-prettier-npm-5.1.2-d18bb6313f-e16c9fbb0e.zip/node_modules/eslint-plugin-prettier/eslint-plugin-prettier.js
- /Users/a1/working/{프로젝트명}/.yarn/cache/@eslint-eslintrc-npm-2.1.4-1ff4b5f908-32f67052b8.zip/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
Occurred while linting /Users/a1/working/{프로젝트명}/src/app/FirebaseInitialize.tsx:1
Rule: "prettier/prettier"

이런 에러가 발생했습니다. 구글링과 깃헙 이슈를 거의 틈날 때 마다 봤던것 같습니다. eslint, synckit, prettier on yarn pnp 등등 생각나는 키워드나 문장들을 계속 검색해보면 읽었던글 또 읽고 읽고 그랬습니다.

이 에러가 왜 발생했는지는 짐작 조차 못할 때 쯤 문득 이런 생각이 들었습니다. yarn 관련 globla, project, user 단위마다 캐시가 존재 할거고 그걸 삭제해보면서 테스트 하면 될수도 있지 않을까?
프로젝트 디렉토리에 있는 패키지를 사용한게 아닌 전역에 캐싱된 패키지를 우선해서 사용한게 아닐까 하는 추측이 바로 이어서 생각났습니다.

곧바로 해봤습니다.

  1. 처음엔 $HOME_DIR 에 있는 캐시 폴더들을 전부 삭제 -> lint가 동작함!(두둥)
  2. 이번엔 어떤 캐시 때문에 그런지 알아보기위해 삭제한 폴더들을 복원하고 하나씩 삭제 해보며 테스트 진행
  3. 범인은 바로 console ninja 라는 플러그인을 사용할 때 생기는 .console-ninja라는 폴더
  4. 그럼 이건 어디서 참조가 되었길레 내 프로젝트의 lint 실행을 방해 하는 것인가 고민...
  5. 아니나 다를까 $HOME_DIR.yarnrc.yml 파일 > plugins 필드 > ./.console-ninja/어쩌구/저쩌구/plugin.js 값을 발견

아하... 참 이런 XXXXX... (육두문자만이 제 머릿속을 가득 채웠습니다.)

결국 이문제는 캐시문제 였던거죠.

암튼 이제 다시 제 삽은 제 손이 아닌 등으로 갔습니다.

위에서 서두에 설명했듯 yarn berry는 설정파일의 우선순위가 당연히 있습니다. 아래는 그 우선순위 입니다.

yarn berry 동작 시 설정파일(.yarnrc.yml)의 우선순위

  1. Command Line Flags:
    # example
    yarn install --frozen-lockfile
    이런 명령어 레벨에서의 설정이 최우선 순위를 가집니다.
  2. Per-Project Configuration (.yarnrc.yml): 프로젝트 단위의 .yarnrc.yml
  3. Workspace Configuration (.yarnrc.yml in Workspaces): workspace 단위의 .yarnrc.yml, workspace 구성을 하지 않았다면 skip!
  4. User-Level Configuration (.yarnrc.yml in the User's Home Directory): 사용자 레벨에서의 .yarnrc.yml. ~/.yarnrc.yml 여기에 있는 설정파일
  5. Yarn Configuration (yarnrc.yml in the Yarn Installation Directory): 전역 Yarn 설치 디렉터리에는 .yarnrc.yml이라는 기본 구성 파일이 포함되어 있습니다. 이 파일은 구성 설정에 대한 전역 대체 역할을 합니다.
  6. Environment Variables: 환경변수에서 설정된 내용, YARN_SILENT 또는 YARN_REGISTRY와 같은 환경 변수를 사용하여 구성 설정을 지정할 수도 있습니다. 환경 변수의 우선 순위가 가장 낮습니다.

결론

저는 $HOME_DIR의 캐시폴더를 날려서 해결했다고 생각했는데 사실 프로젝트 폴더의 .yarnrc.yml에서 plugins 필드를 빈값으로 추가해주면 잘 됩니다. 위에서 설명했다 시피 전역 설정 보다 project 레벨의 설정이 우선시 되니까요.
알고보면 간단한데 막상 이걸 알게 되기까지의 과정이 꽤나 정신적으로 힘들었습니다.
다른 분들에게 조금이라도 도움이 된다면 더할 나위 없겠습니다.

profile
개발을 끝까지 하고 싶은 개발자

5개의 댓글

comment-user-thumbnail
2024년 1월 7일

안녕하세요. 글 잘봤습니다.
저도 같은 증상을 겪고 있는데 .yarnrc.yml에 plugins 필드를 빈값으로 추가한다는것이
그냥 .yarnrc.yml 파일에 plugins: 이렇게만 작성하면 되는 건가요?

이렇게 작성했는데도 계속 같은 에러가 나는데...
혹시 좀만 더 자세히 설명해주실 수 있나요?
아님 console.ninja를 지워야하는 건가요ㅠ?

2개의 답글