concurrently icon indicating copy to clipboard operation
concurrently copied to clipboard

[Feature Request] Run `scripts` for all configured workspaces concurrently

Open cinderblock opened this issue 4 years ago • 8 comments

Since Npn has added workspaces (and Yarn has them too), it would be nice to have a "concurrently" version of those.

For instance, with npm run --workspaces test, the test package.json#scripts will be run for all workspaces sequentially.

A "concurrently" version of the above might be: concurrently --workspaces npm:test.

cinderblock avatar Jul 13 '21 19:07 cinderblock

As I understand, this is more complex than creating a way to run commands from workspaces.

When you execute npm run --workspaces test or yarn workspace test, the command will be handled by Yarn and NPM to use the workspace context but referencing other things from the parent (such as node_modules).

I use concurrently with Yarn Workspaces.

Suppose you have a project with two packages (client and server) and have configured Yarn Workspaces (I'm considering you are using Yarn Berry).

I add Concurrently as a Dev Dependency for my root package.json. yarn add -D concurrently

Then, create scripts to execute server and client.

{
  "scripts": {
    "dev:client": "yarn workspace client dev",
    "dev:server": "yarn workspace server dev",
    "dev": "concurrently \"yarn:dev:*\""
  }
}

daniloraisi avatar Oct 01 '21 17:10 daniloraisi

Yes, that works. But the point of this feature request is basically that the list of dev:* scripts should not be necessary.

I'd (personally) rather concurrently automatically try each workspace's dev script, silently failing if one is missing (possibly). It seems to me this behaviour could be unlocked with a new cli option and not mess with any existing setups.

Throwing a wrench in here, Yarn and Npm handle workspaces completely differently...

cinderblock avatar Oct 02 '21 22:10 cinderblock

@cinderblock, after some analysis and tests, I think it's possible to create something to solve this.

Note that the solution will only work with NPM 7+ and Yarn (I'll try my best to support Yarn 1 and 2) since NPM < 6 has no support for Workspaces.

The best way is to create a flag, as you suggest, to tell concurrently to use Workspaces.

So we have commands like:

concurrently --workspace npm:test
concurrently --workspace yarn:test
concurrently -w npm:test
concurrently -w yarn:test

Behind the scenes, concurrently will execute the regular commands:

yarn workspaces test         #Yarn v1
yarn workspaces foreach test #Yarn v2+
npm run test --workspaces    #NPM v7+

Due to the way workspaces are handled by Yarn and NPM, only single commands will be available. No wildcards, no multiple commands.

Are you ok with that?

@gustavohenke, I'll start as soon as possible and draft a PR!

daniloraisi avatar Oct 05 '21 21:10 daniloraisi

Personally, I think using the yarn: or npm: prefix is confusing and overloading of namespaces.

Ideally, one could ignore that Yarn or Npm are used under the hood. --workspaces might be able to detect which one is currently in use, with an optional modifier like --workspaces=yarn or --workspaces=npm if you want to specify one or the other.

That being said, I don't think what you're proposing would work. Running npm run test --workspaces would run the test script on each workspace sequentially - exactly the opposite of what I'm trying to achieve. Concurrently basically needs to get the list of workspaces and run each npm run test --workspace=foobar for every one.

cinderblock avatar Oct 05 '21 22:10 cinderblock

The use of npm: or yarn: keeps the standard used by concurrently. The user specifies which package manager he is using.

With Yarn, we have a --parallel flag. As npm Workspaces is very recent, there's no option like that (yet). I don't think it is reasonable to create such a structure to validate if we are using Workspaces to run in parallel. In my opinion, It might be an unnecessary overhead.

Also, npm v7+ is available in Node v15+. To use it with Node LTS, we must install it manually. Some tools support Node LTS only with npm ^6.0.0, and migrating to npm v7 can break some things.

That said, I'll start a draft for this task and, as the development evolves, we can discuss the better way to solve things.

daniloraisi avatar Oct 06 '21 14:10 daniloraisi

For anyone looking for a quick workaround, this seems to be working fine for me

.bin/concurrently: (with chmod +x)

#!/usr/bin/env node

const concurrently = require("concurrently")
const package = require("../package.json")
const script = process.argv[2]

concurrently(package.workspaces.map((workspace) => ({
    command: `npm run ${script} -w ${workspace} --if-present`,
    name: `${workspace}`
})))

and in package.json:

{
  "scripts": {
    "watch": ".bin/concurrently watch"
  },
  "devDependencies": {
    "concurrently": "^7.0.0"
  }
}

ghost avatar Feb 04 '22 15:02 ghost

@adambubenicek Nice. Better to use node binary directly so that you don't need chmod +x so that it works on Windows.

cinderblock avatar Feb 05 '22 01:02 cinderblock