Building a Monorepo
Note: this tutorial builds upon knowledge in the Getting Started tutorial so if you haven't gone through it, you should do that first.
We're going to setup a monorepo that uses Preconstruct to build its packages. We're also going to use Yarn Workspaces for linking. Yarn Workspaces isn't the only monorepo linking tool that you can use with Preconstruct, Lerna, Bolt and any other tool that does this will also work.
We have our a-random-number
package from the the Getting Started guide which is awesome but we want to create a new set of packages with some other numbers, the-number-one
and the-number-two
. We're going to use a monorepo to manage it because we want to be able to manage all our packages together.
Setting up Yarn Workspaces
Before we can use Preconstruct, we need to setup Yarn Workspaces and create our packages.
To setup Yarn workspaces, we're going to create a new directory and make a package.json
that looks like this.
{
"name": "not-random-numbers",
"version": "1.0.0",
"license": "MIT",
"private": true,
"workspaces": ["packages/*"]
}
We're also going to create our first two packages.
So we need to create a packages/the-number-one
directory and packages/the-number-two
directory.
Now we can run yarn init
in both of the package directories and answer yes to all the questions.
We'll also need to create our source files.
packages/the-number-one/src/index.js
export default 1;
packages/the-number-two/src/index.js
export default 2;
Setting up Preconstruct to build all our packages
Now that we have Yarn workspaces and our packages setup, we can install and setup Preconstruct.
yarn add @preconstruct/cli -W
yarn preconstruct init
🎁 ? not-random-numbers what packages should preconstruct build? packages/*
🎁 ? preconstruct is going to change the main field in your package.json, are you okay with that? (Press <space> to select, <a> to toggle all, <i> to invert selection)the-number-one, the-number-two
🎁 ? would you like to generate module builds? this will write to the module field in your package.json (Press <space> to select, <a> to toggle all, <i> to invert selection)the-number-one, the-number-two
🎁 success initialised project!
Preconstruct has asked us some slightly different questions since it's detected that we're in a monorepo. We're going to explain exactly what all these questions mean in the future but for now, answering yes to everything will work fine (TODO: write things explaining that stuff)
Setting up preconstruct dev
preconstruct dev
is a command in Preconstruct that lets you import your packages without having to build them every time you make a change or alias the dist files to source files in another tool like webpack, see the Using Preconstruct dev in a monorepo guide for more info. If you are using Windows, you need to enable Developer Mode before using preconstruct dev
by following the instructions here.
We're going to add it to a postinstall script so that yarn will run it after packages are installed. Our package.json will now look like this.
{
"name": "not-random-numbers",
"version": "1.0.0",
"license": "MIT",
"private": true,
"workspaces": ["packages/*"],
"dependencies": {
"@preconstruct/cli": "^2.8.1"
},
"preconstruct": {
"packages": ["packages/*"]
},
"scripts": {
"postinstall": "preconstruct dev"
}
}
Adding Babel
We'll also want to add Babel so that we can use modern features when writing our code but consumers don't have problems using it like the building your first package tutorial.
We're going to install @babel/core
and @babel/preset-env
and add it our Babel config.
yarn add -W @babel/core @babel/preset-env
babel.config.js
module.exports = {
presets: ["@babel/preset-env"],
};
If you'd like to use TypeScript, read the Building TypeScript packages guide. You'll want to add @babel/preset-typescript
to the presets
array.
Curious about why we're using a babel.config.js file here instead of a .babelrc file? Read the Configuring Babel guide
Now we can run preconstruct build
to build our packages. 🎉