루트의 package.json 생성
yarn init -y
{
"name": "gloddy",
"version": "1.0.0",
"description": "",
"main": "index.js",
"private": true,
"workspaces": {
"packages": [
"packages/*"
],
"nohoist": [
"/packages/app/**"
]
},
"packageManager": "[email protected]",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"web": "yarn workspace @gloddy/web",
"app": "yarn workspace @gloddy/app"
},
"devDependencies": {
"husky": "^9.0.7"
}
}
루트의 package.json은 workspace에서 공통으로 사용할 모듈을 관리한다. 현재, husky만 설치되어 있으며, prettier, typescript같은 공통으로 사용할 모듈을 추가할 것이다.
.gitignore 추가
packages/web으로 폴더 묶기
package.json의 name 수정
{
"name":"@gloddy/web"
}
여기서 name은 모노레포의 다른 패키지에서 접근할 때 사용할 이름이다.
packages/app으로 폴더 묶기
package.json 수정
{
"name":"@gloddy/app"
}
no-hoist 설정
모듈을 hoist할 경우, 루트에 모듈이 설치된다. 그래서 ios, android의 네이티브 코드에서 직접 경로를수정해야 한다. 이러한 과정을 하지 않기 위해서는 no-hoist설정을 통해 루트가 아닌, react-native 폴더에 모듈을 설치하도록 할 수 있다.
// packages/app/package.json
{
// ..
"nohoist":[
"/packages/app/**"
]
}
yarn berry가 아닌, yarn classic 설정
기존 React Native에서 사용하던 패키지 관리자는 npm이었다. yarn berry의 PNP로 마이그레이션을 할 경우 의존성 문제를 마주할 것을 생각해, 우선 yarn으로 마이그레이션만 하기로 결정했다. 나중에 순차적으로 yarn berry의 pnp로 마이그레이션을 할 예정이다.
모노레포의 전체적인 패키지 매니저는 yarn berry이므로, react-native패키지에 한해서 yarn classic으로 설정할 것이다.
// packages/app/package.json
{
// ..
"packgeManager" : "[email protected]",
}
// packages/app/.yarnrc.yml
nodeLinker:node-modules
// .yarnignore
packages/app/**
tsconfig는 루트에서 base를 설정하고, 각 패키지에서 상속받아 설정한다.
typescript는 루트와 각 패키지에서 설치한다. 루트의 tsconfig에서 공통된 tsconfig를 설정하고, 각 패키지에서 루트의 tsconfig를 상속받아 설정할 수 있다.
// tsconfig.json
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"moduleResolution": "Node",
"resolveJsonModule": true,
"esModuleInterop": true,
"strict": true,
"target": "es5",
"lib": ["ES5", "ES6", "ESNext", "DOM"],
"skipLibCheck": true,
"baseUrl": ".",
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"isolatedModules": true
},
"exclude": ["packages/**/dist/**"]
}
// packages/web/tsconfig.json, packages/app/tsconfig.json
{
"extends":"../../tsconfig.json",
// ..
}