Skip to content

Maintainer's Guide

zallen edited this page Feb 12, 2020 · 7 revisions

The Monorepo

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 npm install modules directly from GitHub
  • ???

Dependencies

PatternFly uses yarn workspaces to manage our monorepo dependencies and inter-dependencies. Everything can be hoisted fine on Windows, OSX, and Linux. Node module resolution works great, except for with node-sass in PF3, which we created an importer for.

Scripts

We use lerna to manage scripts and package publishing. Its docs are most helpful, as it is rather complicated coming from a single-package mindset.

Building

We are a component library, so we differ from a traditional SPA in distributing our JS and CSS. Rather than using Webpack for our components to create a bundle of ES5 JS, we use Babel to convert our source JS/TS files to various module types, including esm, commonjs, and umd. To create our types for PatternFly 4, we use tsc but discard its JS output.

We use Babel plugins to support language features. PF3 uses Babel 6, and PF4 uses Babel 7.

Feature Example PF3 Extension PF4 Extension
Class Properties class Foo { classMember = 1 } transform-export-extensions @babel/proposal-class-properties
Default Export export * as ns from 'mod'; transform-export-extensions @babel/plugin-proposal-export-default-from
Rest Spread const newObj = {...oldObj}; transform-object-rest-spread @babel/proposal-object-rest-spread

PF4 uses Typescript, so it uses typescript-to-proptypes to create PropTypes for JS consumers from our TS.

Incremental build

Running yarn build to build all our packages takes a while on a 2015 Macbook:

real    1m43.256s
user    4m12.904s
sys     0m29.120s

Many of our packages are not updated in-between local or CI builds. Our incremental build script hashes the contents of src for many of our packages to track changes and only rebuild necessary packages.

Continuous Deployment

We use CircleCI to continually test and generate preview links for PRs and create rolling-prereleases for pushes to master.

Our CircleCI flow for PRs looks like this:

CircleCI PR flow

Master gets an additional deploy_prerelease step, and updates the docs at https://patternfly-react.surge.sh:

CircleCI master flow

Our CircleCI config is here, along with our shell scripts for many of the steps.

Some things to note about the config:

  • We cache node_modules for each sub-project based off the root yarn.lock
  • We cache dist folders and selectively build the projects that have changed based off the contents of their src directories
Clone this wiki locally