@dotcom-tool-kit/monorepo v0.1.4
@dotcom-tool-kit/monorepo
Enables Tool Kit to run commands across monorepo workspace packages.
Installation
Install @dotcom-tool-kit/monorepo
as a devDependency
in your app:
npm install --save-dev @dotcom-tool-kit/monorepo
Add the plugin to your Tool Kit configuration:
plugins:
- '@dotcom-tool-kit/monorepo'
Tool Kit monorepo workflows
Most monorepos won't actually need to use this plugin.
When you don't need the plugin
Some common tooling, such as TypeScript and Jest, are already workspace-aware using configuration such as TypeScript's project references. You can run these at the root level of your monorepo across all packages instead of running them package-by-package via Tool Kit and this plugin.
In almost all cases that will work better; for example, running Jest separately in workspace packages will produce separate test summaries for each package, instead of one summary for all test suites across your monorepo.
When you do need the plugin
Where tooling isn't monorepo-aware itself, or you have tooling that you only want to run in a subset of your workspace packages, the @dotcom-tool-kit/monorepo
plugin allows the root-level .toolkitrc.yml
to run commands from workspace-package-level .toolkitrc.yml
files.
With this plugin, each workspace package is an independent Tool Kit root, which installs separate plugins for its own use cases. For example, a monorepo with an api
package which is deployed to Heroku would install the @dotcom-tool-kit/heroku
plugin as a dependency of the package, not at the root level, and would then include that plugin in the package .toolkitrc.yml
.
The root-level .toolkitrc.yml
can then use the WorkspaceCommand
task to forward commands such as deploy:production
to just the workspace packages that have that command defined (in this case, the api
package).
@dotcom-tool-kit/monorepo
vs npm run --workspaces
It's also possible to run package.json
scripts in workspace packages using npm run --workspaces
, and you can acheive a similar workflow by adding these commands as package.json
scripts at the root level. Depending on your use case that may be preferable for your team or project, but be aware of these tradeoffs:
- If we find there are common monorepo use cases between multiple projects, we can extract the Tool Kit configuration for that into a plugin that can be shared between projects. We can't do that if you're using
package.json
scripts. - Mixing between
package.json
scripts and Tool Kit tasks would require chaining them with shell syntax in thepackage.json
script, which is harder to read and less maintainable than having all the configuration in.toolkitrc.yml
, and has worse error-handling behaviour. - Due to a limitation in this plugin,
package.json
scripts in workspace packages can't be managed by Tool Kit. Any Tool Kit tasks in workspace packages you'd want to run vianpm run --workspaces
would have to be manually maintained aspackage.json
scripts, risking your scripts becoming out of sync with the Tool Kit tasks you expect to be running.
Plugin limitations
- Hooks in workspace packages are not installed, so configuration files like
package.json
in workspace packages can't be managed by Tool Kit. If you have a use case for this, please contact the Platforms team.
Tasks
WorkspaceCommand
Runs a Tool Kit command in all workspace packages that have that command. By default, runs the command that was used to run this task.
For example, imagine a monorepo with these .toolkitrc.yml
files:
commands:
run:local: WorkspaceCommand
build:local: WorkspaceCommand
commands:
run:local: Node
commands:
build:local: TypeScript
commands:
build:local: Webpack
run:local:
Webpack:
watch: true
Running dotcom-tool-kit run:local
at the root level will run the Node
task in packages/api
and the Webpack
task in watch mode in packages/components
; running dotcom-tool-kit build:local
will run TypeScript
in packages/client
and Webpack
in packages/components
.
To run a particular command in the workspace instead of dynamically inferring the command from which was run at root level, set the command
option for the task:
commands:
build:ci:
WorkspaceCommand:
command: build:local
Task options
Property | Description | Type |
---|---|---|
command | A specific command to run instead of the command that ran this task. | string |
packageFilter | By default, the command will run in every workspace command that has that command assigned to a task. This option is a glob pattern to further filter the packages the command will run on. For example, if your workspace has packages in the plugins and lib folders, set packageFilter to plugins/* to only run only in the packages in plugins which have a command assigned to a task. | string |
All properties are optional.