
npm의 비효율적인 node_modules 설치와 관리, 유령 의존성과 같은 단점을 보완하기 위하여
yarn berry를 도입하기로 결정하였고, yarn berry를 도입하면서 기대하는 이점은 아래와 같다.
전체적인 큰 틀과 흐름은 비슷하지만 프로젝트를 관리하는 폴더 구조에 따라서 조금씩 달라지기 때문에 해당 게시글의 기반이 되는 프로젝트 구조를 첨부하면 다음과 같다.
우리의 목표는 npm으로 관리하던 React 프로젝트만 yarn berry로 마이그레이션하고, Node.js 서버는 npm으로 유지하는 것이다.
우선, GitLab에서 의존성 설치가 되어 있지 않은 파일을 다운로드 받고 프로젝트 루트에서 vscode를 연다.
다음으로, 상단 폴더 구조에 따라 app/frontend/templates/ 폴더로 이동한다.
1$ > cd app/frontend/templates다음으로, 불필요한 폴더와 파일들을 삭제한다.
app/frontend/templates/node_modules/app/frontend/templates/package-lock.json다음으로, 이동한 폴더에서 yarn 버전을 berry로 변경해준다.
1$app/frontend/templates > yarn set version berry위 명령어를 실행하면 templates 폴더에만 변화가 생기는 것이 아닌 frontend 폴더에도 변화가 생기는데,
이는 yarn이 package.json이 존재하는 최상단의 루트 경로를 찾아서 해당 경로에 세팅을 해주게 되기 때문이다.
frontend 폴더에 세팅된 yarn 파일과 옵션들을 templates 폴더로 이동시켜주는 다음 과정을 따라하자.
frontend/.yarn/releases/yarn-3.6.3cjs 파일을 frontend/templates/.yarn/releases/ 폴더 아래로 이동시킨다.frontend/.yarn/ 폴더는 삭제해준다.frontend/.yarnrc.yml 파일도 frontend/templates/ 폴더 아래로 이동시킨다.frontend/package.json 파일의 마지막에 추가된 코드를 frontend/templates/package.json 파일로 옮겨 적고 frontend/package.json 파일을 원래대로 돌려놓는다.frontend/templates/ 폴더에 비어있는 yarn.lock 파일을 추가한다. 이를 추가하지 않으면 아래와 같은 에러가 발생한다.위 과정들 모두 마치고 나면 본격적으로 의존성 설치를 진행한다.
yarn berry 3.6.3 버전의 경우 기본적으로 pnp 방식으로 의존성을 해결하므로, .yarnrc.yml 파일에 속성을 추가해줄 필요는 없다.
1$app/frontend/templates > yarn install설치를 완료하면 yarn.lock 파일이 채워지면서 다음과 같은 폴더와 파일들이 추가된 것을 확인할 수 있다.
.yarn/cache/ : 압축된 dependencies들이 위치한 곳.pnp.cjs : Plug’n’Play module resolver, dependencies들을 찾을 수 있는 정보가 기록된다.디스크 I/O 없이 어떤 패키지가 어떤 라이브러리에 의존하는지, 각 라이브러리는 어디에 위치하는지를 바로 알 수 있다.
.yarn/**.pnp.loader.mjsReact 프로젝트의 패키지 매니저가 npm에서 yarn으로 변경되었으니, npm으로 실행하던 명령어를 yarn으로 변경해야 한다.
우리 프로젝트에서는 /app/frontend/package.json에서 Node 서버가 실행되면서 React를 띄워주고 있었으므로, /app/frontend/package.json 파일의 script를 다음과 같이 변경해줘야 한다.
Node 서버에서 실행시킬 명령어는 npm run *으로 유지하고, React 서버를 실행시킬 명령어만 npm run에서 yarn으로 변경했다.
이제 frontend 폴더에서 npm install로 Node 의존성을 설치해 준 다음 프로젝트를 실행시켜보자.
1$app/frontend > npm run start실행 결과, 무시무시한 에러들이 등장했다.
이슈 트래킹을 하기 위해 에러 메시지로 등장한 VirtualTable.tsx라는 임의의 파일로 가봤더니 아래 이미지와 같이 외부 라이브러리 모듈을 모두 참조하지 못하고 있는 것을 발견했다.
우선 해당 문제는 타입스크립트 버전 이슈로, yarn 공식 문서에서는 다음과 같은 단계를 따르라고 권장하고 있다.
1$app/frontend/templates > yarn dlx @yarnpkg/sdks vscode해당 명령어를 실행시키면 app/frontend/templates/.vscode/ 폴더에 아래와 같은 두 개의 파일이 추가된 것을 볼 수 있다.
ctrl + shift + p를 눌러 VSCode 명령어 팔레트를 실행시킨 후,하지만.. 여기까지 잘 따라온 독자라면 아무리 찾아도 작업 영역 버전 사용이라는 탭이 보이지 않는 것을 확인할 수 있다.
참고로 우리가 선택해야 하는 타입스크립트 버전은 4.9.5 버전이다.
무엇이 문제일까? 그리고 왜 이전에는 이런 문제가 발생하지 않았던 것일까?
이전에 npm으로 관리하던 프로젝트에서는 typescript 버전을 따로 관리하거나 선택하지 않아도 전혀 문제가 되지 않았다.
이는 npm 패키지 매니저로 실행시킨 CRA 프로젝트는 node_modules/ 폴더 안에 있는 타입스크립트 버전을 추적해서 해당 버전으로 실행을 시키기 때문이다.
하지만, yarn berry 정책 상 타입스크립트 버전을 명시적으로 선택해 줘야 하기 때문에 전역으로 설치된 타입스크립트 버전과 프로젝트 워크스페이스 내부의 버전이 달라서 문제를 직면하게 된 것이다.
만약, 전역으로 설치된 타입스크립트의 버전을 4.9.5로 다운그레이드하면 문제가 해결될 수도 있다.
하지만, 이는 좋은 방법은 아닌 것으로 생각이 든다.
많은 서치 끝에 아래와 같은 게시글을 만날 수 있었다.
위 해결책을 우리 프로젝트에 적용해보면, 프로젝트 루트가 React 프로젝트 루트가 아니기 때문에 app/frontend/templates/ 폴더를 루트로 하는 VSCode를 열어보면 문제가 해결될 여지가 있는 것이다.
1$app/frontend/templates > code .예상했던 대로 타입스크립트 파일을 선택한 후, 타입스크립트 버전 선택을 들어가보니 “작업 영역 버전 사용”이 선택 가능한 상태로 되었다!
그리고 이를 선택했더니 에러가 거짓말 처럼 사라졌고,
라이브러리를 타고 들어가도 라이브러리 코드를 예전과 같이 확인할 수 있다.
흥미로운 점은 react 라이브러리를 타고 들어가서 파일의 경로를 확인해보면 아래와 같다.
rktk\app\frontend\templates\.yarn\cache\@types-react-npm-18.2.22-bd0a04edf5-44289523da.zip\node_modules\@types\react\ts5.0\index.d.ts
이는 앞서 설치한 ZipFS Extension 덕분에 zip 파일을 타고 들어가서 코드를 확인할 수 있게 된 것이다.
아쉬운 점은 위 이미지에서 여전히 rc-resize-observer, lodash의 경우 의존성 모듈을 찾지 못하고 있는데, 이는 잠시 후에 다시 살펴볼 예정이다.
위에서 간접적으로 해결한 문제를 원래 작업하던 환경(root 경로, 글로벌 타입스크립트 버전)을 그대로 한 채로 해결할 수 있는 방법은 없을까?
.vscode/settings.json 파일의 속성 중에 typescript sdk를 참조하는 경로가 있다는 것을 확인했다.
VSCode의 루트가 서로 달라서 워크스페이스 내 타입스크립트 선택이 안 되었던 문제였으므로, .vscode를 루트로 올리고 sdk를 참조하는 경로를 바꾸면 해결이 되지 않을까?
.vscode/ 폴더를 프로젝트 루트로 이동시킨 후, .vscode/settings.json 속성을 아래와 같이 변경해보았다.
그리고 VSCode를 재부팅 했더니 아래와 같이 성공적으로 경로를 읽은 모습이 보인다!!
그리고 성공적으로 의존성을 참조할 수 있는 상태가 되었다.
추가적인 문제 해결에 앞서 yarn berry 플러그인 설치를 하나 진행하고 가자.
1$app/frontend/templates > yarn plugin import typescript해당 플러그인은 타입스크립트 외부 모듈을 설치 시, devDependencies에 @types/*를 따로 추가로 설치해 줘야 하는 것을 자동으로 설치해 주는 플러그인이다.
위에서 보였던 참조 에러 라이브러리인 rc-resize-observer, lodash는 알고보니 package.json에 없는 유령 의존성이었던 것이다!!
이와 같이 유령 의존성을 참조하고 있는 것들을 해결하기 위해서 아래에 해당하는 라이브러리들을 추가로 설치했다.
1{2 "dependencies": {3 "@ant-design/icons": "^5.2.6",4 "@nivo/colors": "^0.83.0",5 "@nivo/tooltip": "^0.83.0",6 "d3-scale": "^4.0.2",7 "lodash": "^4.17.21",8 "rc-resize-observer": "^1.3.1",9 "react-is": "^18.2.0",10 "redux": "^4.2.1",11 },12 "devDependencies": {13 "@types/d3-scale": "^4",14 "@types/lodash": "^4",15 "@types/prettier": "^3",16 "@types/react-is": "^18",17 "prettier": "^3.0.3",18 }19 // ...20}21 설치가 완료되니 모든 에러 메시지들이 사라진 것을 볼 수 있다.
yarn berry를 도입하면서 생긴 루트에 추가해야 하는 .vscode/ 폴더 내 파일들은 아래와 같다.
1{2 "search.exclude": {3 "**/.yarn": true,4 "**/.pnp.*": true5 },6 "eslint.nodePath": "app/frontend/templates/.yarn/sdks",7 "typescript.tsdk": "app/frontend/templates/.yarn/sdks/typescript/lib",8 "typescript.enablePromptUseWorkspaceTsdk": true,9 "editor.defaultFormatter": "esbenp.prettier-vscode",10 "editor.formatOnSave": true,11 "editor.codeActionsOnSave": {12 "source.fixAll.eslint": true13 },14 "prettier.ignorePath": ".prettierignore"15}node_modules에 비해 의존성 파일들의 크기가 현저히 작아지면서 아예 의존성 파일까지 Git으로 관리하여
CI/CD 시 install 하는 시간까지 절약하는 Zero-Installs 방법이 있다.
이를 반영할 지, 반영하지 않을 지에 대한 .gitignore 파일 설정은 아래와 같다.
Questions & Answers | Yarn
A list of answers to commonly asked questions.
yarnpkg.com/getting-started/qa
↗
Zero-Installs 설정
1git config --local http.postBuffer 157286400Zero-Installs 설정 안 함
기준 커밋 SHA 7d9d72b250728b8338405c6e477a5f8a1189cb1a
의존성 설치 시간
npm 1분 9초 468yarn berry 38초 466빌드 시간
npm 2분 18초 674yarn berry 47초 586의존성 파일 용량
npm 615MByarn berry 155MB