Let us say you have a monorepo that uses the latest Yarn with workspace-tools plugin. There you have two child workspaces, e.g. frontend
and backend
. They list some linting scripts like lint:js
and 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
run
and 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 lint:css
from 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.
Conclusions
- In Yarn, use colons (
:
) in script names only if you want those scripts to be callable from any workspace. - The
yarn workspaces foreach run
command does skip a workspace if the specified script is missing there. Just make sure that the script name does not contain colons.
Top comments (0)