DEV Community

with-heart
with-heart

Posted on

Set up our pnpm monorepo

In this post, we'll implement the basic monorepo structure we mentioned at the end of High level technical overview.

As a quick refresher, we'll have three packages:

  • app
  • bot
  • db

We'll only generate a basic package structure for each. Here's what the end structure will look like (with some files/directories excluded to focus on the changes we'll be making):

.
├── app
│  ├── package.json
│  ├── pages
│  ├── public
│  ├── README.md
│  └── tsconfig.json
├── bot
│  ├── package.json
│  ├── src
│  │  └── index.ts
│  └── tsconfig.json
├── db
│  ├── package.json
│  ├── src
│  │  └── index.ts
│  └── tsconfig.json
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── README.md
└── tsconfig.json
Enter fullscreen mode Exit fullscreen mode

Additional monorepo setup like using the packages as dependencies of each other, build tooling, etc. will come later.

Create pnpm workspace

Since we're using pnpm, monorepo setup doesn't require much setup on our part.

Essentially, we just need to create a pnpm-workspace.yaml file that defines the package directories in our monorepo:

packages:
  - 'app'
  - 'bot'
  - 'db'
Enter fullscreen mode Exit fullscreen mode

With this change, pnpm knows that the app, bot, and db directories are packages in our monorepo.

Now that we have this file in place, we can set up our package directories.

Create the app package

Since app is a Next.js app, we'll use create-next-app to generate that package: pnpm create next-app --ts app.

The setup runs as expected and dependencies are added to the root pnpm-lock.yaml file.

We can start our app to test that it works: pnpm --filter app run dev


I just really want to note how cool pnpm is. The --filter flag allows us to zoom in on specific packages to execute our commands. In the above command, we use --filter app to target pnpm run dev to the app directory.


Before we move on, we need to fix an eslint error in the app directory: Parsing error: Cannot find module 'next/babel'.

To resolve that, we need to update app/.eslintrc.json to extend from next/babel:

{
  "extends": ["next/babel", "next/core-web-vitals"]
}
Enter fullscreen mode Exit fullscreen mode

Create the bot and db packages

Prepare typescript

Since bot and db will both be libs and not React apps, we can configure typescript at the root and have both packages extend their configuration from that.

To get started, we'll install a few packages: pnpm i typescript @types/node -w @tsconfig/node16-recommended

The -w flag tells pnpm that we want to install the dependencies at the root.

The @tsconfig/node16-recommended package contains a tsconfig.json file with recommended TypeScript configuration. We'll use that in our root tsconfig.json file:

{
  "extends": "@tsconfig/node16-strictest/tsconfig.json",
  "exclude": ["app"]
}
Enter fullscreen mode Exit fullscreen mode

We also exclude the app directory because Next.js uses its own tsconfig.json file.

Create the bot package

bot
├── package.json
├── src
│  └── index.ts
└── tsconfig.json
Enter fullscreen mode Exit fullscreen mode

We'll create the bot folder and a package.json inside of it:

{
  "name": "bot",
  "version": "0.0.0",
  "private": true
}
Enter fullscreen mode Exit fullscreen mode

We'll also create bot/tsconfig.json:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "dist"
  },
  "include": ["src"]
}
Enter fullscreen mode Exit fullscreen mode

This configuration includes src in the files TypeScript will compile and the extends option means we reuse the configuration specified in our root tsconfig.json.

Create the db package

db
├── package.json
├── src
│  └── index.ts
└── tsconfig.json
Enter fullscreen mode Exit fullscreen mode

To create this package, we'll do everything we did to create the bot package except we replace the word bot with db.


Awesome! We now have a monorepo! This gives us a lot of flexibility and clarity in how we configure and use our packages.

To check out the PR for this post, look here: https://github.com/Developer-DAO/discord-server-info/pull/10

Top comments (1)

Collapse
 
nathan_ofzion_ddc0e4fb243 profile image
Nathan Ofzion

This is great we’re working on an open source monorepo using pnpm too would love your input if at all possible
Here our project would love your vote: dev.to/nathan_ofzion_ddc0e4fb243/z...