Skip to content

Commit 80e2071

Browse files
ianstormtaylorbestander
authored andcommitted
update workspace-run-commands to more detail (#87)
1 parent 38dd9c8 commit 80e2071

File tree

1 file changed

+96
-21
lines changed

1 file changed

+96
-21
lines changed

accepted/0000-workspace-run-commands.md

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,128 @@
44

55
# Summary
66

7-
Allow Yarn CLI to execute a package script on each packages from the workspace root.
7+
Allow Yarn CLI to execute a package script on each workspace package from the workspace root.
88

99
# Motivation
1010

11-
"Lerna". Lerna does a great job for handling monorepos. Since Yarn has a built-in
12-
workspaces feature, we could use some of the functionalities that being used in
13-
lerna (not entirely though!) for handling the monorepo more efficiently.
11+
Lerna does a great job for handling monorepos. Yarn's built-in workspaces feature would benefit from borrowing more of functionality that Lerna exposes, to handle monorepos more easily.
1412

15-
Just like installing all dependencies from one place (workspace root), it'd be great
16-
to execute all the sub-package scripts from the workspace root using a single command.
17-
Not only this would make a less back-and-forth traveling between the packages to
18-
execute scripts, but also it'll help a lot for CI/CD configuration.
13+
Just like installing all dependencies from one place (workspace root), it'd be useful to execute a specific package script for each of the workspace packages from the workspace root using a single command. Not only this would make for less back-and-forth traveling between the packages to execute scripts, but also it'll help a lot for CI/CD configuration.
1914

2015
# Detailed design
2116

22-
As @BYK mentioned [here](https://github.com/yarnpkg/yarn/issues/4467#issuecomment-330873337),
23-
we could create two commands for this feature.
17+
As @BYK mentioned [here](https://github.com/yarnpkg/yarn/issues/4467#issuecomment-330873337), to start we'd create two commands for this feature:
2418

2519
* `yarn workspaces list`
2620
* `yarn workspaces run <command>`
2721

28-
By introducing `workpaces` command, it brings a modular approach from the CLI's perspective.
22+
Unifying all of the workspace-specific commands under the `workpaces` namespace allows for a modular approach from the CLI's perspective, making future commands easy to add.
2923

30-
## `yarn workspaces list --args`
24+
## `yarn workspaces list [flags]`
3125

32-
This command will list out all the packages for all the workspaces (alphabetically). If no workspace is found, this will fail with error.
26+
This command lists all of the packages for all of the workspaces alphabetically. If no workspaces are found it will error.
3327

34-
Additionally, we can pass a `--filter` argument followed by a workspace name. In that case, it'll list out all the package inside that specified workspace.
28+
## `yarn workspaces run [flags] <command> ...`
3529

36-
## `yarn workspaces run <command>`
30+
This command runs a specific package script (as defined in the `scripts` property in `package.json`) for all of the packages for all of the workspaces.
3731

38-
This will execute the specified `<command>` in all workspaces. For a _fail fast_ operation, we could traverse all the workspaces to check whether the specified command exists within that workspace, before we actually start executing. If not found, display an error with which workspace is missing that command.
32+
Just like the `yarn run` command, any arguments after the command name will be passed as arguments to the package script.
3933

40-
The ordering of execution is also important. It must be executed _topologically_. So that it won't break the inter-dependant workspaces.
34+
For a _fail fast_ operation, we could traverse all the workspaces to check whether the specified command exists within that workspace, before we actually start executing. If not found, display an error with which workspace is missing that command.
35+
36+
The ordering of execution is also important. It must be executed _topologically_, so that it won't break the inter-dependant workspaces. From the Lerna documentation:
37+
38+
> By default, all tasks execute on packages in topologically sorted order as to respect the dependency relationships of the packages in question. Cycles are broken on a best-effort basis in a way not guaranteed to be consistent across Lerna invocations.
39+
>
40+
> Topological sorting can cause concurrency bottlenecks if there are a small number of packages with many dependents or if some packages take a disproportionately long time to execute. The --no-sort option disables sorting, instead executing tasks in an arbitrary order with maximum concurrency.
41+
>
42+
> This option can also help if you run multiple "watch" commands. Since lerna run will execute commands in topologically sorted order, it can end up waiting for a command before moving on. This will block execution when you run "watch" commands, since they typically never end. An example of a "watch" command is running babel with the --watch CLI flag.
43+
44+
The output should be prefixed with the name of the workspace (eg. `packages/package-a:`), so the user has a better idea of what is currently running.
45+
46+
### `--concurrency`
47+
48+
The `--concurrency` flag changes the number of child processes that are spawn when commands are run in parallel, defaulting to `4` (like Lerna).
49+
50+
### `--parallel`
51+
52+
If the `--parallel` flag is passed, it will runs the commands in parallel in separate child processes, instead of running them in series. This command will ignore the concurrency flag and topological sorting requirements. (Just like Lerna.)
53+
54+
## `yarn workspaces exec ...`
55+
56+
This commands runs an arbitrary shell command in each package. It is similar to `yarn workspaces run`, and respects the same flags, but instead of running a package script defined in `package.json` you can pass it arbitrary shell commands.
57+
58+
This is helpful for cases where you want to execute something that isn't worthy of storing in `package.json`, often when debugging or running a one-off.
59+
60+
For example:
61+
62+
```
63+
$ yarn workspaces exec babel --out-dir ./lib ./src
64+
```
65+
66+
## Common Flags
67+
68+
### `--packages`
69+
70+
The `--packages` flag takes a package name or glob, and it restricts the command being run to only take affect in those packages.
71+
72+
**Note:** this flag operates on the package names, as defined by the `name` field in `package.json` files.
73+
74+
For example:
75+
76+
```
77+
$ yarn workspaces list --packages 'babel-*' build
78+
```
79+
80+
81+
### `--workspaces`
82+
83+
The `--workspaces` flag takes a workspace name or glob, and it restricts the command being run to only take affect in those workspaces.
84+
85+
**Note:** this flag operates on the workspace names, not the package names. For example `packages/my-package` would be a workspace name. This is helpful when working with multiple directories of workspaces.
86+
87+
For example, with a `workspaces` setup of:
88+
89+
```json
90+
[
91+
"packages/*",
92+
"services/*",
93+
"utils/*"
94+
]
95+
```
96+
```
97+
packages/
98+
package-a/
99+
package-b/
100+
...
101+
services/
102+
api/
103+
cdn/
104+
utils/
105+
...
106+
```
107+
108+
You could restrict the command to only run in `services/api` and `services/cdn by doing:
109+
110+
```
111+
$ yarn workspaces run --workspaces 'services/*' start
112+
```
41113

42114
# How We Teach This
43115

44-
Since this is a new feature and doesn't affect existing functionalities, it shouldn't affect existing/new users. However, a slight documentation should be written under the workspace CLI.
116+
Since this is a new feature and doesn't affect existing functionality, it won't change any existing user behavior. However, documentation should be added to explain the new features to those who want to opt-in to them.
45117

46118
# Drawbacks
47119

48-
Complexity. Especially while executing the package scripts. We need to keep track of the package dependencies. And also, there's already a library (lerna) does the same thing and is compatible with yarn without any extra configuration.
120+
This will increase the complexity of Yarn, instead of letting it live in Lerna and work in tandem. Especially while executing the package scripts, because we need to keep track of the package dependencies.
49121

50122
# Alternatives
51123

52-
Don't have an alternative way (I can think of) inside yarn.
124+
There's no current alternative using Yarn. You have to use Lerna and Yarn in concert, which causes confusion as to which one to use when.
53125

54126
# Unresolved questions
55127

56-
How to handle multiple workspaces?
128+
- Should package names and workspace names be handled? or only packages?
129+
- What does Yarn define as a single "workspace"?
130+
- Should parallel execution be handled?
131+
- Should an `exec` command be added as well, similar to Lerna?

0 commit comments

Comments
 (0)