오랜만에 monorepo
를 새로 만들어야 할 일이 생겨 이참에 yarn berry
의 workspaces
를 이용해서 monorepo
를 구축하는 것을 정리해보려고한다.
먼저, yarn berry
를 사용할거기 때문에 폴더 생성 후 아래의 커맨드를 통해 yarn berry
의 version 을 set해준뒤 확인해주고 package.json
을 생성해준다. (여기서는 4.0.2.ver
사용)
$ yarn set version berry
$ yarn -v
$ yarn init
package.json
에서 코드가 위치할 workspaces
를 설정해준다. 나는 아래와 같이 구성하였다.
apps
: 프로젝트들이 위치할 workspace 폴더common
: 각 프로젝트에서 공통으로 사용할 코드들이 위치할 workspace 폴더// package.json
{
"name": "hoon-monorepo",
"packageManager": "yarn@4.0.2",
"private": true,
"workspaces": [
"apps/*",
"common/*"
]
}
각 workspace
에 공통으로 적용될 typescript
, eslint
, prettier
를 root 경로에서 설치해준다.
yarn add -D typescript eslint prettier ... (eslint, prettier plugins...)
설치 후 .eslintrc
, .prettierrc
와 같은 설정파일을 set해준 뒤tsconfig.base.json
을 설정해준다. (아래는 예시)
// tsconfig.base.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"allowJs": false,
"skipLibCheck": false,
"useDefineForClassFields": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowImportingTsExtensions": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"jsx": "react-jsx"
}
}
이제 apps
경로에 들어가 react
프로젝트를 하나 생성해준다.
여기서 생성한 프로젝트의 package.json
의 name은 workspace
의 이름이므로 아래와 같이 설정해 주었다.
// package.json
{
...
"name": "@hoon-monorepo/react-app",
"version": "1.0.0",
...
}
또한 앞에서 설정한 tsconfig.base.json
을 가져와 추가 설정도 해주었다. (아래는 예시)
{
"extends": "../../tsconfig.base.json",
"include": ["./src"],
"compilerOptions": {
...
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
...
}
}
앞의 과정을 진행하면 아마 프로젝트에 빨간줄이 가득할것이다. vscode
에서 정상적으로 로드하고, 작업하기 위해 아래의 ZipFS
extension을 설치해주자.
추가로 아래의 명령어로 sdk
도 설치해준다. 이때 주의할 점은 sdk
부터 설치하면 안되고 typescript
처럼 문법에 영향을 주는 것들은 먼저 설정하고나서 설치해야한다.
$ yarn dlx @yarnpkg/sdks vscode
설치 후 아래와 같이 선택해준다.
이제 앞에서 생성한 react
프로젝트에 대해 해당 경로로 이동하여 접근할수도있지만 root 에서 script
로 접근할 수 있도록 아래와 같이 설정해주었다. (추가로 위의 sdk
설치도 script로 설정)
// package.json
{
"name": "hoon-monorepo",
"packageManager": "yarn@4.0.2",
"private": true,
"workspaces": [
"apps/*",
"common/*"
],
"scripts": {
"dlx:vscode": "yarn dlx @yarnpkg/sdks vscode",
"react-app": "yarn workspace @hoon-monorepo/react-app"
},
"devDependencies": {
"eslint": "^8.55.0",
"prettier": "^3.1.0",
"typescript": "^5.3.3"
}
}
이제 yarn react-app dev
와 같은 명령어로 root 경로에서도 접근할 수 있다.
각 프로젝트에서 공통으로 사용될 함수를 common
폴더에 만들어서 react
프로젝트에서 사용할려한다.
common/utils
경로에 package.json
을 아래와 같이 설정해준다.
// package.json
{
"name": "@hoon-monorepo/utils",
"version": "1.0.0",
"main": "index.js",
}
index.ts
를 생성해 아래와 같이 간단한 함수를 작성해주었다.
export const sum = (a: number, b: number) => {
return a + b;
};
다시 root
로 돌아가 react
프로젝트에 utils
의 의존성을 추가해준다. (여기서 react-app은 위에서 설정한 script)
$ yarn react-app add @hoon-monorepo/utils
이제 react
프로젝트에서 아래와 같이 작성한 함수를 가져와 사용할 수 있다.
import { sum } from '@hoon-monorepo/utils';
function App() {
return <div>sum function result : {sum(10, 20)}</div>;
}
export default App;