DEV Community

Cover image for Building a Monorepo with pnpm Workspace
soom
soom

Posted on • Edited on

2 2

Building a Monorepo with pnpm Workspace

Abstract

Introducing the Monorepo Approach through pnpm Workspace.

Multi Repo, Mono Repo, Micro Frontend Architecture 등 최근에는 효율성을 높이기 위한 다양한 접근 방법이 소개되고 있다.

본 포스팅에서는 pnpm workspace 릁 통해 간단한 Monorepo 구조를 구현해 보겠다.

p.s 지난번 dev.to 쪽 이슈로 글이 날아가버려서 다시 쓰는 내용이기 때문에 기억이 잘 나지 않아 아쉽다.
역시 백업은 중요한 것


Getting Started

Prerequisite

  • pnpm global 설치가 필요
Terminal
# Node Version <16.14
npm install -g pnpm

# Node Version >16.17
corepack enable

corepack prepare pnpm@latest --activate
Enter fullscreen mode Exit fullscreen mode

Set Project Structure

프로젝트 구조를 구성해보자

├── packages/
│   ├── app/
│   └── common/
├── package.json
└── pnpm-workspace.yaml
Enter fullscreen mode Exit fullscreen mode

파일 생성 뒤 다음과 같이 작성

/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"
    }
}
Enter fullscreen mode Exit fullscreen mode
/pnpm-workspace.yaml
packages:
  - 'packages/*'
Enter fullscreen mode Exit fullscreen mode

packages/app/ packages/common/ 폴더 안에 리액트 프로젝트를 생성

여기서는 vite 를 통해 생성

pnpm create vite .
Enter fullscreen mode Exit fullscreen mode

Setting Common Component

먼저 packages/common/ 폴더 쪽에 다음과 같이 Button Component를 생성

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;
Enter fullscreen mode Exit fullscreen mode

main.tsx 에서 방금전 생성한 Button Component 를 export

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

export { Button };
Enter fullscreen mode Exit fullscreen mode

package.json을 다음과 같이 수정

packages/common/package.json
{
    "name": "@soom/common",
    "type": "module",
    "main": "./src/main.tsx",
    ...
}
Enter fullscreen mode Exit fullscreen mode

Run App with Imported Shared Component

이제 app 폴더로 가서 package.json 을 다음과 같이 수정 후 패키지 설치 재실행

packages/app/package.json
{
    "name": "@soom/app",
    "private": true,
    "type": "module",
    ...
    "dependencies": {
        "@soom/common": "^0.0.0",

    },
    ...
}
Enter fullscreen mode Exit fullscreen mode

패키지 설치

pnpm install
Enter fullscreen mode Exit fullscreen mode

App.tsx 에서 좀전에 설치한 @soom/common 패키지를 이용해 버튼을 import

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;
Enter fullscreen mode Exit fullscreen mode

app 폴더에서 프로젝트 실행

이제 common 프로젝트의 버튼이 무사히 app 프로젝트에 적용이 된것을 확인할 수 있다.

pnpm dev
Enter fullscreen mode Exit fullscreen mode

Result

👉 CodeSandBox Sample Link

Result


➕ P.S

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

package.json
{
    "name": "@soom/root",
...

    "scripts": {
        "preinstall": "pnpm dlx only-allow pnpm",
        "dev:app": "pnpm --filter @soom/app dev"
    },

...
}

Enter fullscreen mode Exit fullscreen mode
Terminal
pnpm dev:app
Enter fullscreen mode Exit fullscreen mode

Conclusion

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

pnpm 의 자세한 내용은 하기 링크를 참고.
https://pnpm.io/ko/

Monorepo Tool에 대한 자세한 내용은 하기 링크를 참조.
참고 링크: https://monorepo.tools/

Image of Docusign

Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (3)

Collapse
 
devnyang profile image
Dok6n

정말 감사합니다~~

Collapse
 
daehyunthevc profile image
daehyun • Edited

기존의 pnpm을 이용한 monorepo 구성 포스트가 다른 포스트로 덮어졌네요. 기존 글은 어디서 볼 수 있을까요?

Collapse
 
soom profile image
soom

글 자체는 dev.to 문제로 날아갔다고 하네요 ㅠㅠ
복구가 어렵다고해서 해당하는 내용 다시 포스팅 했어요

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs