-
Notifications
You must be signed in to change notification settings - Fork 356
Maintainer's Guide
We use a monorepo because we have many inter-dependencies between our own packages (ex. react-core depends on react-styles). Taken from babel's monorepo:
Pros:
- Single lint, build, test and release process
- Easy to coordinate changes across modules
- Single place to report issues
- Easier to setup a development environment
- Tests across modules are run together which finds bugs that touch multiple modules easier
Cons:
- Codebase looks more intimidating
- Repo is bigger in size
- Can't use
npm install
- Makes @jeff-phillips-18 upset
PatternFly uses yarn workspaces to manage our monorepo dependencies and inter-dependencies. Node module resolution works great, except for sass
in catalog-view-extension, which we created an importer for.
Our packages themselves have few dependencies for better maintainability. Since PatternFly is widely used it's best to keep the dependencies to a minimum so the bundle size stays small.
We are a component library which differs from a traditional SPA in distributing our JS and CSS. Rather than using Webpack for our components to create a bundle of JS, we use Typescript to convert our source TS files to various module types, including esm
, commonjs
, and umd
. We also publish our .d.ts
types for our Typescript consumers which is currently about half of all consumers.
Our react-styles
package consumes CSS from our @patternfly/patternfly and extracts the class names to Javascript variables for use in React. react-styles
also writes require('component-name.css');
so that bundlers include CSS only for the components that they use.
Many of our packages are not updated in-between local or CI builds. We leverage tsc
s incremental build option to track file changes between builds and only rebuild necessary packages.
We use GitHub Actions to continually test and generate preview links for PRs and create rolling prereleases for pushes to main
.
Our pipeline looks like this:
Only pushes to main
trigger the deploy
step which uses lerna to publish packages. Lerna bumps the versions all changed packages and their dependents, pushes git tags, pushes a git commit to main
, and then publishes to npm using GH_TOKEN and NPM_TOKEN.
Our GitHub actions config is here, along with our scripts for some of the steps. It's difficult to conditionally check whether the workflow is running in a PR or on the main
branch so we need two workflow files. Most steps are duplicated between the 2, so in order to keep the pipeline DRY there's a simple templating script to generate the workflow files from the partials.
Some things to note about the config:
- We cache
node_modules
for each sub-project based off the rootyarn.lock
- We cache
dist
folders and selectively build the projects that have changed based off the contents of theirsrc
directories