pnpm workspaces를 사용하여 React TS & tailwindcss를 적용해보자.
프로젝트마다 다르지만 보통 두 타입의 구조가 존재한다고 한다.
나는 서비스 개발이니까 후자를 선택한다. 하지만 폴더명은 변경가능하므로, apps 대신 projects를 사용할 것이다.
projects에는 실제 서비스가 담긴 프로젝트들: app, admin
packages에는 공통으로 사용되는 프로젝트들: component, tailwind-config을 위치시킬 계획이다.
tailwind-config는 공통 스타일 토큰이, component에는 tailwind-config를 사용한 공용 컴포넌트를, 그리고 projects 하단의 어플리케이션은 공용 컴포넌트를 가져다 쓸 계획이다.
시작에 앞서 pnpm이 없다면 설치해주자. pnpm 설치
npm이 있다면 간단하게 설치할 수 있다.
npm install -g pnpm
그리고 프로젝트 디렉토리를 만들고, 디렉토리 안에서 다음 명령어를 통해 프로젝트를 초기화한다.
pnpm init
이제 package.json이 생성되었다.
프로젝트 루트에 projects/ 폴더와 packages/ 폴더를 생성한다.
mkdir projects packages
프로젝트 루트에 pnpm-workspace.yaml을 생성한다. 공식 문서
packages 하단에 구조설계에서 정한 폴더명을 적어준다.
# pnpm-workspace.yaml
packages:
- "projects/*" # executable/launchable applications
- "packages/*"
package.json에도 workspaces를 추가한다. 구조설계에서 정한 폴더명을 넣는다.
{
// 추가
"workspaces": [
"projects/*",
"packages/*"
],
}
이제 packages와 projects 하단에 프로젝트들을 셋팅해준다. 리액트, NextJS, Angular 무엇이든 상관없다.
나는 tailwindcss + React TS를 사용할 예정이다.
공통으로 설정안해도 되긴 한데 모든 프로젝트에 동일하게 적용됐으면 해서 프로젝트 루트에 설정한다.
$ pnpm add -D eslint eslint-config-prettier eslint-plugin-prettier prettier
tailwind-config를 먼저 생성한다. packages > tailwind-config에 들어가서 pnpm init을 진행한다. (직접 package.json을 만들어도 된다.)
name에 구분을 위해 @packages를 붙여주었다.
// packages > tailwind-config >package.json
{
"name": "@packages/tailwind-config",
//...
}
이제 tailwindcss를 설치한다. 가이드대로 따라하면 된다.
pnpm add --filter @packages/tailwind-config tailwindcss postcss autoprefixer -D
pnpx tailwindcss init
postcss.config.js 생성
const config = require('./tailwind.config.js');
module.exports = {
plugins: {
tailwindcss: { config },
autoprefixer: {},
},
};
tailwind.config.js 설정
module.exports = {
content: ['**/*.{js,ts,jsx,tsx}', '**/*/index.html'],
theme: {
extend: {},
},
plugins: [],
}
이제 tailwind-config를 사용할 component 설정을 해준다.
packages 하단에 vite를 사용하여 ReactTS로 초기화를 진행해준다.
# packages > component
pnpm create vite . --template react-ts
// package.json
{
"name": "@packages/component",
// ...
"devDependencies": {
"@packages/tailwind-config": "workspace:^0.1.0",
// ...
}
}
tailwind.config.cjs
module.exports = require('@packages/tailwind-config/tailwind.config.js');
postcss.config.cjs
module.exports = require('@packages/tailwind-config/postcss.config.js');
루트 폴더에 projects > app을 생성하고 component와 마찬가지로 vite를 이용해서 react를 셋팅한다.
# projects/app/
pnpm create vite . --template react-ts
app > package.json 설정
{
"name": "@projects/app",
// ...
"devDependencies": {
"@packages/tailwind-config": "workspace:^0.1.0",
"@packages/component": "workspace:^0.0.0",
// ...
}
}
"scripts": {
"build:comp": "pnpm --filter @packages/component build",
"dev:comp": "pnpm --filter @packages/component dev",
"dev:app": "pnpm --filter @projects/app dev"
},
component에서 tailwind-config가 호출되는지 확인해보기 위해 tailwind-config에 공통 스타일을 추가해본다.
packages>tailwind-config>tailwind.config.js
module.exports = {
content: ['**/*.{js,ts,jsx,tsx}', '**/*/index.html'],
theme: {
extend: {
colors: {
main: '#414066',
},
},
},
plugins: [],
};
버튼에 적용해본다.
// Button.tsx
export function Button(props: any) {
return (
<button onClick={() => props.onClick()} className="bg-main">
{props.children}
</button>
);
}
export default Button;
잘된다.
https://blog.nrwl.io/setup-a-monorepo-with-pnpm-workspaces-and-speed-it-up-with-nx-bc5d97258a7e
https://dev.to/soom/building-a-monorepo-with-pnpm-workspace-1544
https://github.com/ashleydavis/pnpm-workspace-examples
https://dev.to/ynwd/how-to-setup-react-shared-components-in-monorepo-with-tailwind-webpack-and-npm-workspace-570n
https://github.com/mihailtd/demo-monorepo (vue + tailwindcss)