lerna react typescript yarn workspaces cypress github actions
Lerna & Yarn workspaces monorepo with React TS apps, Cypress tests at app level, CI running with Github Actions workflows depending on the changed files.
yarn install / yarn i / yarn --registry # at root level; all sub-level dependencies are taken care of
yarn start:a / start:b / start:c # start app-*
# on a different tab
yarn cy:open-a / cy:open-b / cy:open-c # open cypress test runner at app level
# on a different tab
yarn cy:run-a / cy:run-b / cy:run-c # run cypress headlessly at app level
# if you are not using GitHub actions, or if you want to test locally, server-test can be utilized
# make sure the app is not running
yarn test:ci-a / test:ci-b / test:ci-c # start app-*, run tests headlessly against it
Lerna & Yarn workspaces config makes it so that we can install at root, and not worry about sub-level app dependencies.
While at the root, utilize lerna --stream --scope
to execute scripts within packages/app-*
context.
Cypress is installed at the root, but the spec files live with the packages. To run/open tests per app:
cypress run/open
from root-level, in order to hit app-level package.json
scriptpackage.json
script, invoke the node_modules back at the root (ex: "../../node_modules/.bin/cypress open"
)For CI
wait-on: 'http://localhost:3000'
)project: ./packages/app-a
) . This is the key difference to local test execution.Lerna: provides tooling to manage multi-repository structure inside a single repository by separating out subsets of the repository into their own “sub” repositories; monorepo.
Yarn workspaces: manages our dependencies. Rather than having multiple node_modules directories, it intelligently optimizes the installing of dependencies together and allows for the cross-linking of dependencies in a monorepo.
yarn config set workspaces-experimental true # enable yarn workspaces, has to be a private repo
yarn init # generate package.json
yarn add lerna --dev # add lerna
lerna init # creates packages/ folder and lerna.json file
Edit lerna.json
to enable yarn workspaces:
{
"packages": [
"packages/*"
],
"version": "0.0.1",
"npmClient": "yarn",
"useWorkspaces": true
}
Add workspaces property to package.json
root level:
"workspaces": [
"packages/*"
]
npx create-react-app packages/app-a --template typescript
npx create-react-app packages/app-b --template typescript
npx create-react-app packages/app-c --template typescript
The assumption is that we do not have cross dependencies between our packages.
Since we are using Yarn workspaces, we do not need
lerna bootstrap --hoist
at this point, which is used to move common dependencies to root node_modules (if using npm).
Install it at the root, that is it.
Monorepo examples: Jannik Buschke's blog, JSilvax's blog, Jonathan Creamer's blog.
# note: can use run or open
# with lerna, use triple -- to pass a cmd line arg
# strings
yarn cy:run-a -- -- --env grep=app-a
yarn cy:run-a -- -- --env grepTags=@a
yarn cy:run-a -- -- --env grep="grep test spec"
yarn cy:run-a -- -- --env grepTags="@2"
A while after this repo got created, GHA came up with reusable workflows.
There are 2 called worfklows for test burning.
There are two pairs of caller workflows for app-a and app-b, using the called workflows:
.github/workflows/repeat-spec-called.yml
.github/workflows/repeat-a-spec-caller.yml
.github/workflows/repeat-b-spec-caller.yml
.github/workflows/repeat-tag-called.yml
.github/workflows/repeat-a-tag-caller.yml
.github/workflows/repeat-b-tag-caller.yml
The original test burners for app-c have been left in place for comparison
.github/workflows/repeat-c-spec.yml
.github/workflows/repeat-c-tag.yml