Создание монорепо с помощью pnpm Workspace


Аннотация

현재 다양한 tool들이 monorepo 개념을 지원하고 있다. 기본적인 package 레벨에서의 지원 yarn berry, pnpm workspace 이나 관련 도구들 Nx, 최근에 Nx 에 인수되어 새로운 버전을 발표한 lerna, Vercelturborepo 등 여러가지 инструмент 들이 그 예이다.
이번 포스팅에서 다룰 내용은 이중에서 가장 쉽고 간단하게 monorepo 개념을 구현할 수 있는 pnpm workspace를 사용하는 방법이다.

참고할만한 링크: https://monorepo.tools/


Предварительные условия

pnpm 설치가 필요하다.

Терминал
npm i -g pnpm
Войти в полноэкранный режим Выход из полноэкранного режима

Начало работы

빈 프로젝트 폴더를 만들고 monorepo 프로젝트를 생성

Терминал
pnpm init
Вход в полноэкранный режим Выйти из полноэкранного режима

pnpm-workspace.yaml 파일을 생성하고 아래와 같이 입력

pnpm-workspace.yaml
packages:
  - 'packages/*'
Вход в полноэкранный режим Выход из полноэкранного режима

package.json 에 다음과 같이 입력.
pnpm 의 버전은 최신 버전으로 맞춰주면 된다.
(2022/08/08 기준 7.9.0)

package.json
{
  "name": "@soom/root", 
  "private": true,
  "scripts": {
    "preinstall": "pnpm dlx only-allow pnpm"
  },
  "workspaces": ["packages/*"],
  "engines": {
    "node": ">=16.14.2", 
    "pnpm": ">=7.9.0" 
  },
  "packageManager": "pnpm@7.9.0", 
  "devDependencies": {
    "pnpm": "^7.9.0"
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

package.json 기반으로 설치

Терминал
pnpm install
Войти в полноэкранный режим Выход из полноэкранного режима

packages 폴더를 만들고 common, app 폴더를 생성
구조는 다음과 같다.

.
├── packages/
│   ├── app
│   └── common
├── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml
Вход в полноэкранный режим Выход из полноэкранного режима

common, app 각각 폴더에서 프로젝트를 생성
여기서는 vite를 사용해 프로젝트 생성
реак-ты 템플릿을 이용하였다.

Терминал
pnpm create vite

✔ Select a framework: › react
✔ Select a variant: › react-ts
Войти в полноэкранный режим Выход из полноэкранного режима

각각 폴더에서 프로젝트가 작동하는지 확인

предварительный просмотр


common 프로젝트에 간단한 버튼을 생성

packages/common/src/components/Button.tsx
import type { FC, PropsWithChildren } from 'react';

interface Props extends PropsWithChildren {
    textColor: string;
}

const Button: FC<Props> = (props) => {
    return <button style={{ color: props.textColor }}>{props.children}</button>;
};

export default Button;
Вход в полноэкранный режим Выход из полноэкранного режима

main.tsx, package.json 을 다음과 같이 수정

packages/common/src/main.tsx
import Button from './components/Button';

export { Button };
Вход в полноэкранный режим Выход из полноэкранного режима
packages/common/package.json
{
    "name": "@soom/common",
    "private": true,
    "version": "0.0.0",
    "type": "module",
    "main": "./src/main.tsx",
...
}
Войти в полноэкранный режим Выход из полноэкранного режима

app 폴더로 가서 package.json에 다음과 같이 수정하고 pnpm install을 통해 설치한다.
여기서 @soom/common 패키지는 common 폴더의 프로젝트 이름이다.

packages/app/package.json
{
    "name": "@soom/app",
...
    "dependencies": {
        "@soom/common": "^0.0.0",
        "react": "^18.2.0",
        "react-dom": "^18.2.0"
    },
...
}
Вход в полноэкранный режим Выход из полноэкранного режима
Терминал
pnpm install

dependencies:
+ @soom/common 0.0.0 <- ../common
Войти в полноэкранный режим Выход из полноэкранного режима

App.tsx 에서 방금 설치한 @soom/common패키지에서 버튼을 불러온다.

packages/app/src/App.tsx
import './App.css';
import { Button } from '@soom/common';

function App() {
    return (
        <div className='App'>
            <h1>Monorepo Button?</h1>

            <Button textColor='red'>Hello Common Package Button</Button>
        </div>
    );
}

export default App;
Вход в полноэкранный режим Выход из полноэкранного режима
предварительный просмотр


➕ P.S.

마지막으로 monorepo 루트 폴더에서 직접 app폴더에 접근하지 않고 구동시키기 위해서 package.json에 다음과 같이 스크립트를 사용할 수 있다.

package.json
{
    "name": "@soom/root",
...
    "scripts": {
        "preinstall": "pnpm dlx only-allow pnpm",
        "dev:app": "pnpm --filter @soom/app dev"
    },
...
}
Вход в полноэкранный режим Выход из полноэкранного режима
Терминал
pnpm dev:app
Войти в полноэкранный режим Выход из полноэкранного режима

➕➕ Образец Stackblitz


Заключение

pnpm workspace 를 이용해서 monorepo 를 구성해보았다.
이 프로젝트에 turborepo, lerna 등을 이용해 다양한 관리를 할 수 있다.
monorepo를 구성하는 방법은 여러가지가 있지만 개인적으로 pnpm workspace를 이용하는 방법이 가장 가볍고 직관적이었다.

pnpm 의 자세한 내용은 하기 링크를 참고.

https://pnpm.io/ko/

Оцените статью
devanswers.ru
Добавить комментарий