Let us say you have a monorepo that uses the latest Yarn with workspace-tools plugin. There you have two child workspaces, e.g.
backend. They list some linting scripts like
lint:css that use the common convention of separating the scope with a colon (
For obvious reasons,
backend doesn't have a
lint:css script. The root workspace exists only for grouping purposes and therefore doesn't have any linting scripts.
- root workspace - backend workspace - lint:js - frontend workspace - lint:js - lint:css
Now you want to lint all workspaces at once using the
yarn workspaces foreach run command that tries to run the specified script in each workspace, including the root one. You will do something like this:
# Lint all JS yarn workspaces foreach run lint:js # Lint all CSS yarn workspaces foreach run lint:css
As mentioned before, not all workspaces have the specified scripts, but that should not be a problem because the documentation states the following:
If the command is
runand the script being run does not exist the child [or current] workspace will be skipped without error.
However, linting all JS results in a cryptic message in the root workspace (as a side note, this is already fixed in the canary version):
Usage Error: Couldn't find a script named "lint:js".
Linting all CSS is even funnier: the
frontend is executed three times, once for each workspace.
This is because Yarn has a little-known feature that makes any script with a colon in its name global. For
lint:js, this means that there are two conflicting versions of this script in the root workspace, which leads to the "Couldn't find..." error (again, this is fixed in the canary version). For
lint:css, this means that the
frontend script is global, so it can be called from any workspace.
A script with a colon in its name implicitly "exists" in every workspace, so
yarn workspaces foreach run will always execute it in all workspaces (if there is only one version of the script). In contrast, missing scripts without colons are properly ignored.
The issue with implicit global scripts is described in detail in this feature proposal.
- In Yarn, use colons (
:) in script names only if you want those scripts to be callable from any workspace.
yarn workspaces foreach runcommand does skip a workspace if the specified script is missing there. Just make sure that the script name does not contain colons.