pnpm으로 mono-repo를 구현한다. #18
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
그렇다면 pnpm으로 cra를 설치하는 방법과 craco 설정도 함께 보여줘 특히 CRA 설치를 어디서 해야하는지 명확히 짚어주고
ChatGPT의 말:
ChatGPT
모노레포 구조에서 pnpm을 사용해 **Create React App (CRA)**을 설치하고 Craco를 설정하는 방법을 단계별로 설명드리겠습니다.
먼저, 프로젝트 디렉토리 구조를 아래와 같이 설정하겠습니다.
java
코드 복사
my-monorepo
├── packages
│ └── front
│ ├── public
│ ├── src
│ ├── package.json
│ ├── craco.config.js
│ └── tsconfig.json
├── node_modules
└── package.json
my-monorepo는 루트 디렉토리입니다.
packages/front가 CRA 프로젝트가 위치할 디렉토리입니다.
2. 루트 package.json 설정
루트 디렉토리 (my-monorepo)에 package.json 파일을 생성하고, 워크스페이스 설정을 추가합니다.
my-monorepo/package.json:
json
코드 복사
{
"name": "my-monorepo",
"version": "1.0.0",
"private": true,
"workspaces": ["packages/*"]
}
private: true는 모노레포 설정을 위해 필수입니다.
workspaces 설정에서 packages 폴더 하위에 있는 모든 디렉토리를 워크스페이스로 인식하도록 합니다.
3. CRA 설치하기
이제 pnpm을 사용하여 packages/front 디렉토리에 CRA를 설치합니다.
packages/front 폴더로 이동:
bash
코드 복사
cd packages
mkdir front
cd front
Create React App 설치 및 생성: pnpm을 사용해 CRA를 설치합니다. --template typescript를 사용하여 TypeScript 템플릿을 사용합니다.
bash
코드 복사
pnpm create react-app . --template typescript
.을 지정하여 현재 front 폴더에 CRA를 생성합니다.
이제 packages/front 폴더가 CRA 프로젝트로 설정되었으며, 이곳에 package.json 및 src, public 폴더가 생성됩니다.
4. Craco 설치 및 설정
Create React App은 기본적으로 Webpack 설정을 덮어쓸 수 없습니다. 이를 가능하게 하려면 Craco를 설치하고 설정해야 합니다.
Craco 설치: packages/front 디렉토리에서 Craco를 설치합니다.
bash
코드 복사
pnpm install @craco/craco
Craco 설정 파일 추가: packages/front 디렉토리에 craco.config.js 파일을 생성하고 필요한 설정을 추가합니다.
packages/front/craco.config.js:
javascript
코드 복사
const path = require('path');
module.exports = {
webpack: {
alias: {
'@': path.resolve(__dirname, 'src'), // src 디렉토리 별칭 설정
},
},
};
package.json 수정: CRA에서 기본적으로 사용하는 react-scripts 명령을 Craco로 대체합니다. packages/front/package.json의 scripts를 다음과 같이 수정합니다.
packages/front/package.json:
json
코드 복사
{
"name": "front",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-scripts": "5.0.1",
"typescript": "^4.0.0",
"@craco/craco": "^6.0.0"
},
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
}
}
react-scripts 대신 craco 명령어를 사용하도록 start, build, test 스크립트를 변경했습니다.
의존성 설치: 루트 디렉토리에서 모든 의존성을 설치합니다.
bash
코드 복사
cd ../../ # 루트 디렉토리로 이동
pnpm install
pnpm은 워크스페이스 설정에 따라 각 패키지의 의존성을 node_modules에 설치하고 공유합니다.
프로젝트 실행: CRA 프로젝트 (front)를 실행하려면 다음 명령어를 사용합니다.
bash
코드 복사
pnpm -F front start
-F는 --filter의 약어로, 특정 워크스페이스에서만 명령을 실행하도록 합니다. 이 명령어는 front 워크스페이스 내에서 craco start를 실행하여 개발 서버를 시작합니다.
최종 디렉토리 구조
구성 후의 디렉토리 구조는 다음과 같습니다:
java
코드 복사
my-monorepo
├── packages
│ └── front
│ ├── public
│ ├── src
│ ├── package.json
│ ├── craco.config.js
│ └── tsconfig.json
├── node_modules
├── package.json // 루트-level package.json with workspaces
└── README.md
요약
pnpm을 사용하여 모노레포 환경에서 CRA를 설치하고, front 폴더를 하나의 워크스페이스로 설정했습니다.
Craco를 통해 CRA의 Webpack 설정을 덮어쓸 수 있도록 구성했습니다.
pnpm -F front start 명령을 사용해 front 워크스페이스를 실행할 수 있습니다.
이렇게 설정하면 pnpm과 CRA를 함께 사용하는 모노레포 구조가 완성됩니다! 😊
나의 말:
나는 여기서 궁금한게 cra를 하고 나면 node_modules가 front에 생성되지 않아?
ChatGPT의 말:
ChatGPT
네, 맞습니다! pnpm의 워크스페이스 기능을 사용하면 front 디렉토리에 별도의 node_modules 폴더가 생성되지 않습니다. 대신, 모든 의존성은 루트 디렉토리의 node_modules에 설치되고, front와 같은 워크스페이스 패키지들은 이곳의 의존성을 공유하게 됩니다.
이유
pnpm의 워크스페이스 구조에서는 각 워크스페이스가 필요로 하는 의존성을 모두 루트 node_modules에서 관리하여 중복 설치를 방지하고, 전체 프로젝트의 디스크 사용량을 줄입니다.
워크스페이스에서 사용하는 모든 의존성은 루트의 package.json에 명시된 워크스페이스 설정에 따라 하나의 node_modules 폴더에서 공유됩니다.
결과적으로:
packages/front 내부에는 node_modules 폴더가 생성되지 않습니다.
루트의 node_modules에서 모든 의존성을 관리하며, 각 워크스페이스는 필요한 모듈을 이곳에서 가져다 씁니다.
이 방식은 모노레포 환경에서 중복된 의존성 설치를 줄이고, 의존성 관리의 일관성을 유지하는 데 큰 장점이 있습니다.
나의 말:
그런데 설치하는 과정에서 왜 pnpm을 먼저 설치하지 않고 나중에 설치하는거야? 이유가 있어?
ChatGPT의 말:
ChatGPT
좋은 질문입니다! 일반적으로 pnpm을 프로젝트 시작 전에 먼저 설치하는 것이 좋습니다. 제가 설치 순서를 나중에 안내한 것은 pnpm 설치가 이미 되어 있다고 가정했기 때문입니다. 그러나 실제로는 pnpm을 먼저 설치한 후 모노레포를 설정하는 것이 올바른 순서입니다.
올바른 설치 순서
pnpm 설치: 시스템에 pnpm이 설치되어 있지 않다면, 먼저 전역으로 설치합니다.
bash
코드 복사
npm install -g pnpm
프로젝트 디렉토리 구성 및 CRA 설치: 이후, pnpm을 사용하여 CRA를 설치하고 워크스페이스를 구성합니다.
이유: pnpm을 먼저 설치해야 하는 이유
모노레포 기능 활용: pnpm은 자체적으로 모노레포 환경에서 의존성을 효율적으로 관리하는 기능을 가지고 있습니다. pnpm이 설치된 상태에서 CRA와 다른 패키지를 설치해야, 의존성을 루트 node_modules에 한 번만 설치하고 모든 워크스페이스가 공유할 수 있습니다.
의존성 관리: 만약 pnpm을 먼저 설치하지 않고 CRA를 설치하면, npm 또는 yarn이 사용되어 각 워크스페이스에 node_modules가 생성되거나 불필요한 중복 설치가 발생할 수 있습니다. pnpm을 먼저 설치하고 나서 워크스페이스 내에서 모든 패키지를 설치하면, pnpm의 효율적인 의존성 관리 방식을 활용할 수 있습니다.
따라서, 실제로는 pnpm을 먼저 설치하고 나서 CRA를 설치 및 설정하는 것이 올바른 순서입니다.
나의 말:
npm install -g pnpm 설치된걸 확인하려면 어떻게 해야해?
ChatGPT의 말:
ChatGPT
pnpm이 제대로 설치되었는지 확인하려면 터미널에서 다음 명령어를 사용하세요:
bash
코드 복사
pnpm -v
또는
bash
코드 복사
pnpm --version
이 명령어를 입력하면 pnpm의 버전 번호가 출력됩니다. 예를 들어, 8.6.0과 같은 버전 번호가 출력된다면 pnpm이 제대로 설치된 것입니다.
추가 확인 방법
pnpm의 설치 경로를 확인하려면 다음 명령어를 사용할 수 있습니다:
bash
코드 복사
which pnpm
이 명령어는 pnpm 실행 파일의 경로를 표시하며, 설치가 올바르게 되었는지 확인하는 데 도움이 됩니다. (Linux 및 macOS에서 사용 가능, Windows에서는 Git Bash 또는 WSL에서 가능)
Windows 사용자는 다음 명령어를 사용할 수도 있습니다:
bash
코드 복사
where pnpm
이렇게 확인하면 pnpm이 전역으로 설치되었는지 알 수 있습니다.
나의 말:
만약 내가
my-monorepo
├── front
│ ├── public
│ ├── src
│ ├── package.json
│ ├── craco.config.js
│ └── tsconfig.json
├── node_modules
├── package.json // 루트-level package.json with workspaces
└── README.md
이렇게 구현하려면 workspace를
"workspaces": [
"front"
],
이렇게 설정하면 돼?
ChatGPT의 말:
ChatGPT
네, 맞습니다!
현재 구조에서 front 폴더를 루트 디렉토리 바로 아래에 두고 워크스페이스로 설정하려면, 루트 package.json 파일의 workspaces 설정을 다음과 같이 작성하시면 됩니다:
json
코드 복사
{
"name": "my-monorepo",
"version": "1.0.0",
"private": true,
"workspaces": [
"front"
]
}
이렇게 설정하면, front 폴더가 루트 바로 아래에 있어도 pnpm이나 Yarn이 이 디렉토리를 워크스페이스로 인식합니다.
정리
workspaces 설정에서 "front"와 같은 상대 경로를 지정하면, my-monorepo/front가 독립된 워크스페이스로 인식됩니다.
이제 pnpm install을 루트에서 실행하면, front 폴더의 package.json에 있는 의존성들도 함께 설치되어 루트의 node_modules에서 공유됩니다.
이렇게 하면 원하는 모노레포 구조로 front 디렉토리를 설정할 수 있습니다! 😊
나의 말:
그런데 설치하고 나니깐 node_modules가 루트에서도 생성되고 front에서도 생기는데?
ChatGPT의 말:
ChatGPT
node_modules가 루트와 front 모두에 생성되는 현상은 pnpm의 설정이나 프로젝트 초기화 과정에서 발생할 수 있는 일반적인 상황입니다. 이를 해결하기 위해 몇 가지 점을 확인하고, 정확한 설정을 적용해야 합니다.
pnpm은 기본적으로 루트 디렉토리에서 node_modules를 관리하고, 워크스페이스 내부에서는 심볼릭 링크를 사용하여 node_modules를 가리킵니다. 그러나 특정 조건에서 front 디렉토리 내부에 실제로 node_modules가 생성될 수 있습니다.
확인해야 할 점:
pnpm 버전 확인:
bash
코드 복사
pnpm -v
최신 버전을 사용하고 있는지 확인하세요. 최신 버전이 아니라면 업데이트합니다.
bash
코드 복사
npm install -g pnpm
pnpm 설정 확인: 루트 디렉토리에 .npmrc 파일을 생성하거나 확인하고, 다음 설정을 추가합니다:
plaintext
코드 복사
node-linker=hoisted
이 설정은 모든 의존성을 루트의 node_modules로 호이스팅하고, 워크스페이스 내부에 node_modules가 생기는 것을 방지합니다.
front 내부에 node_modules가 생성되는 주요 원인은 다음과 같습니다:
pnpm이 제대로 설정되지 않고, 기본적으로 개별 디렉토리에서 의존성을 설치한 경우.
pnpm install 대신 npm install을 실행한 경우 (npm은 워크스페이스 설정을 지원하지 않음).
front 디렉토리에서 직접 pnpm install을 실행한 경우.
3. 해결 방법
A. 루트에서 의존성 설치
모노레포 환경에서는 항상 루트 디렉토리에서 pnpm install을 실행해야 합니다.
bash
코드 복사
cd my-monorepo
pnpm install
B. front 내부의 node_modules 삭제
front 디렉토리 내부에 생성된 node_modules를 삭제합니다:
bash
코드 복사
rm -rf front/node_modules
C. .npmrc 설정 확인
루트 디렉토리에 .npmrc 파일이 없으면 생성하고, 다음 내용을 추가합니다:
plaintext
코드 복사
node-linker=hoisted
이 설정을 통해 pnpm이 모든 의존성을 루트의 node_modules로 호이스팅합니다.
설정 후, 디렉토리 구조는 다음과 같이 되어야 합니다:
java
코드 복사
my-monorepo
├── front
│ ├── public
│ ├── src
│ ├── package.json
│ ├── craco.config.js
│ └── tsconfig.json
├── node_modules // 루트에서 모든 의존성 관리
├── package.json // 루트-level package.json with workspaces
├── pnpm-lock.yaml
└── README.md
front 내부에 node_modules가 다시 생성되지 않고, 필요한 의존성은 루트의 node_modules를 통해 접근됩니다.
의존성 링크 상태를 확인하려면 다음 명령어를 실행하세요:
bash
코드 복사
pnpm list --depth 0
이 명령어는 모든 워크스페이스와 의존성을 출력하며, 올바르게 설치되었는지 확인할 수 있습니다.
요약
항상 루트에서 pnpm install을 실행하세요.
node-linker=hoisted 설정으로 모든 의존성을 루트에서 관리하세요.
front 내부의 node_modules는 삭제하고, 필요할 경우 의존성을 다시 설치하세요.
이 방법으로 node_modules가 루트에서만 생성되고, front 내부에서 생기지 않도록 설정할 수 있습니다. 😊
나의 말:
$ pnpm install
WARN The "workspaces" field in package.json is not supported by pnpm. Create a "pnpm-workspace.yaml" file instead.
Already up to date
이렇게 나와
ChatGPT의 말:
ChatGPT
pnpm은 package.json의 workspaces 필드를 지원하지 않습니다. 대신, pnpm-workspace.yaml 파일을 사용해야 합니다. 이 파일은 루트 디렉토리에서 워크스페이스를 정의하는 역할을 합니다.
해결 방법
pnpm-workspace.yaml 파일 생성 루트 디렉토리에 pnpm-workspace.yaml 파일을 생성하고, 다음 내용을 추가합니다:
yaml
코드 복사
packages:
이 설정은 front 폴더를 워크스페이스로 등록합니다. 필요에 따라 추가 워크스페이스를 지정할 수도 있습니다.
예를 들어, 추가적으로 backend 폴더를 워크스페이스로 포함하고 싶다면:
yaml
코드 복사
packages:
workspaces 필드 제거 루트 package.json에서 workspaces 필드를 제거합니다. pnpm은 pnpm-workspace.yaml 파일만 사용합니다.
의존성 설치 루트 디렉토리에서 pnpm install을 다시 실행합니다:
bash
코드 복사
pnpm install
최종 파일 구조
구조는 다음과 같아야 합니다:
java
코드 복사
my-monorepo
├── front
│ ├── public
│ ├── src
│ ├── package.json
│ ├── craco.config.js
│ └── tsconfig.json
├── node_modules
├── package.json // 루트-level package.json
├── pnpm-workspace.yaml // pnpm의 워크스페이스 정의 파일
└── README.md
주의사항
pnpm-workspace.yaml 파일은 반드시 루트 디렉토리에 있어야 합니다.
pnpm install을 실행하면 이제 워크스페이스가 제대로 인식되고, 모든 의존성이 루트 node_modules에 설치됩니다.
확인
의존성이 올바르게 설치되었는지 확인하려면 다음 명령어를 실행하세요:
bash
코드 복사
pnpm list --depth 0
출력 결과에서 front 워크스페이스의 의존성도 함께 표시되어야 합니다. 이제 pnpm 워크스페이스가 정상적으로 작동할 것입니다! 😊
나의 말:
pnpm list --depth 0
이렇게 명령하면 아무것도 안나와
ChatGPT의 말:
ChatGPT
pnpm list --depth 0 명령어를 실행했을 때 아무것도 출력되지 않는다면, 이는 pnpm이 워크스페이스나 의존성을 제대로 인식하지 못한 상태일 수 있습니다. 아래 단계를 확인하고 문제를 해결해 보세요.
pnpm-workspace.yaml 파일이 루트 디렉토리에 정확히 존재하고, 설정이 올바른지 확인하세요.
예시:
yaml
코드 복사
packages:
front 디렉토리 내부의 package.json 파일에 의존성이 포함되어 있는지 확인하세요.
예시 (front/package.json):
json
코드 복사
{
"name": "front",
"version": "1.0.0",
"private": true,
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
dependencies가 비어 있거나 설정이 잘못되었으면, pnpm install이 의존성을 설치하지 않을 수 있습니다.
루트 디렉토리에서 의존성을 다시 설치합니다.
bash
코드 복사
pnpm install
이 명령어는 pnpm-workspace.yaml에 정의된 모든 워크스페이스의 의존성을 설치합니다.
의존성을 설치한 후, 다시 pnpm list --depth 0 명령어를 실행하여 의존성을 확인합니다.
bash
코드 복사
pnpm list --depth 0
출력 예시:
perl
코드 복사
my-monorepo@1.0.0
├── front@1.0.0
└── react@18.0.0
5. 디버그 명령어 사용
의존성이 여전히 표시되지 않는다면, 다음 디버그 명령어를 사용하여 pnpm이 워크스페이스를 인식하고 있는지 확인하세요.
bash
코드 복사
pnpm --filter front list --depth 0
이 명령어는 front 워크스페이스의 의존성만 표시합니다. 만약 여전히 출력되지 않는다면, front 디렉토리와 pnpm-workspace.yaml 설정을 다시 확인하세요.
pnpm이 최신 버전인지 확인하세요. 버전이 낮으면 최신 버전으로 업데이트하세요.
bash
코드 복사
pnpm -v
npm install -g pnpm
요약
pnpm-workspace.yaml 파일이 올바르게 설정되어 있는지 확인.
front/package.json에 의존성이 포함되어 있는지 확인.
루트에서 pnpm install을 실행하여 의존성을 설치.
pnpm list --depth 0 또는 pnpm --filter front list --depth 0 명령으로 의존성 확인.
이 과정을 통해 의존성이 제대로 설치되고, pnpm list 명령어로 출력될 것입니다. 😊
나의 말:
그런데 pnpm -F front start를 실행하면 node_modules/cache/babel-loader가 생기는데?
ChatGPT의 말:
ChatGPT
pnpm -F front start를 실행할 때 node_modules/.cache/babel-loader 디렉토리가 생성되는 것은 정상적인 동작입니다. 이 폴더는 Babel과 Webpack에서 사용하는 캐시(cache) 파일을 저장하기 위한 디렉토리입니다.
왜 node_modules/.cache/babel-loader가 생성되나요?
Babel Loader의 캐싱:
CRA(Create React App)와 Craco를 통해 Webpack이 Babel을 사용하여 JavaScript 및 TypeScript 코드를 트랜스파일합니다.
이 과정에서 트랜스파일링 속도를 높이기 위해 결과를 캐싱합니다.
이 캐시 파일이 node_modules/.cache/babel-loader에 저장됩니다.
Webpack 설정의 기본 동작:
CRA 또는 Craco에서 Webpack 설정은 기본적으로 Babel 로더의 캐싱을 활성화합니다.
이렇게 하면 이후의 빌드나 개발 서버 실행에서 이전 빌드 결과를 재사용하여 속도를 높입니다.
이 디렉토리를 삭제해도 괜찮은가요?
삭제 가능: 개발 중에 node_modules/.cache/babel-loader 폴더를 삭제해도 큰 문제가 없습니다. 삭제하면, 다음 번 빌드나 개발 서버 실행 시 다시 생성됩니다.
삭제 권장 상황:
캐시와 관련된 문제가 발생하거나, Babel/Craco 설정을 변경한 후 빌드 과정에서 예상치 못한 문제가 발생할 경우.
이 디렉토리를 생성되지 않게 할 수 있나요?
만약 node_modules/.cache/babel-loader 생성 자체를 막고 싶다면, Webpack 설정에서 Babel 로더의 캐싱을 비활성화해야 합니다. 하지만 이렇게 하면 빌드나 개발 서버 실행 속도가 느려질 수 있습니다.
Craco 설정에서 캐싱 비활성화:
craco.config.js 파일을 수정합니다.
babel-loader 설정에 cacheDirectory: false를 추가합니다.
javascript
코드 복사
module.exports = {
webpack: {
configure: (webpackConfig) => {
webpackConfig.module.rules.forEach((rule) => {
if (rule.loader && rule.loader.includes('babel-loader')) {
rule.options.cacheDirectory = false;
}
});
return webpackConfig;
},
},
};
이 설정을 추가하면 Babel 로더가 더 이상 캐싱하지 않으므로 node_modules/.cache/babel-loader 폴더가 생성되지 않습니다.
결론
node_modules/.cache/babel-loader는 정상적으로 생성되는 폴더이며, 트랜스파일링 속도를 높이기 위해 필요한 캐시 파일을 저장합니다.
생성되지 않게 할 수 있지만, 개발 환경의 성능이 저하될 수 있으므로 특별한 이유가 없다면 삭제하거나 비활성화하지 않는 것이 좋습니다. 😊