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
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'
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"]
}
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"]
}
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
We'll create the bot
folder and a package.json
inside of it:
{
"name": "bot",
"version": "0.0.0",
"private": true
}
We'll also create bot/tsconfig.json
:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "dist"
},
"include": ["src"]
}
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
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)
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...