turbo: --parallel Does not honor build dependencies
Describe the feature you’d like to request
In the canonical example, turbo run dev --parallel --no-cache is used for development.
However, --parallel will build dependent tasks in parallel too, even though those might need to be executed in dependency order.
Given a graph like: A -> B and A -> C
And a turborepo definition like:
"turbo": {
"pipeline": {
"build": {
"dependsOn": ["^build"]
},
"dev": {
"dependsOn": ["build"]
"cache": false
}
}
}
Running turbo run dev --parallel --no-cache will break on the build step, because the builds of B and C depend on the build of A completing.
Describe the solution you’d like
One possible solution is to add a parameter like --parallel-depth=1 (default: Infinite), where only the dev commands are executed in parallel, but deeper dependent commands are not.
Describe alternatives you’ve considered
Removing build from dev: { dependsOn }, and executing 2 commands works:
turbo run build
turbo run dev --parallel --no-cache
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 31
- Comments: 25 (7 by maintainers)
Commits related to this issue
- Reproduction for https://github.com/vercel/turborepo/issues/460 — committed to VanTanev/turborepo-reproduce-460 by VanTanev 2 years ago
- Reproduction for https://github.com/vercel/turborepo/issues/460 — committed to VanTanev/turborepo-reproduce-460 by VanTanev 2 years ago
- Reproduction for https://github.com/vercel/turborepo/issues/460 — committed to VanTanev/turborepo-reproduce-460 by VanTanev 2 years ago
- Reproduction for https://github.com/vercel/turborepo/issues/460 — committed to VanTanev/turborepo-reproduce-460 by VanTanev 2 years ago
- Reproduction for https://github.com/vercel/turborepo/issues/460 — committed to VanTanev/turborepo-reproduce-460 by VanTanev 2 years ago
- Try fixing dev error module not found (#471) Manually build `@saleor/checkout-storefront` before running `dev` to avoid "Missing module" errors due to race conditions. This is related to the foll... — committed to saleor/storefront by typeofweb 2 years ago
- Try fixing dev error module not found (#471) Manually build `@saleor/checkout-storefront` before running `dev` to avoid "Missing module" errors due to race conditions. This is related to the foll... — committed to superman030129/saleor by superman030129 2 years ago
- Try fixing dev error module not found (#471) Manually build `@saleor/checkout-storefront` before running `dev` to avoid "Missing module" errors due to race conditions. This is related to the foll... — committed to happyguy0311/StoreFront by happyguy0311 2 years ago
So if you ended here as me, let’s reiterate how Turborepo dev works (and how not) because it’s confusing.
The workflow a developer would expect is to install modules and then run the dev script, but that’s now how Turborepo works. A dev task needs two things: generate code and run watchers. From Turborepo docs:
It’s confusing because Turborepo runs everything parallel, if possible. This configuration should be named --ignoreDependecyGraph
--parallelis required to run watchers, but before that, we need to build code in order so we can’t use--parallel. It’s a chicken-egg problem.I bet many developers just run a dev task, then they see some errors, then they will rerun it, and then it magically works. That’s not ideal.
Turborepo suggests that we should use
dependsOnhttps://turborepo.org/docs/handbook/dev#running-tasks-before-dev, but it solves nothing because--parallelis required for watchers.As I see it, there have to be two tasks run separately from the command line. Something like
buildForDevand thendev.Because my build does not do anything special, the recommended way (for me) is always to run
buildbeforedevorstart.I have watch modes with incremental rebuilds for all packages as their
devtask, one-off optimized builds as theirbuildtask.Because I want to run all
devtasks in parallel and the incremental watch builds output to the same directories the one-off optimized builds would also output, I need to have all packages built before I start their dev modes. In the repo’s root, I haveturbo run dev --continueas mydevtask at the root and this in myturbo.json:This starts all builds and after they finish, starts all watch modes. So far, so good.
However, if application A depends on package B which in turn depends on package C, what I’d like to see when I save a file in package C is that C does an incremental rebuild, followed by an incremental rebuild of B, followed of an incremental rebuild of A, followed by a browser refresh (which is out of
turboreposcope).What happens instead is an incremental rebuild of package C. That’s it. Is there any way to get what I want?
Since this feature is IMHO a very basic need, I don’t understand how we can use Turborepo dev mode when some packages relies on others. Did someone found any workaround on this ?
The docs do specifically say this ignores the dependency graph, but I’m struggling to see how this is useful?
In the meantime is there a workaround for local development where you build your dependencies with a
tsc -wor similar? If you remove the parallel flag, as the processes never exit (watch mode) the build just hangs 😦I also realized this, So I try to let the
devtask to depend on^buildas the like whats said here. https://github.com/vercel/turborepo/issues/460#issuecomment-1064161370But if you have a dependency graph like
A -> B. For example A is a typescript package, itsbuildscript istsc. If you are developing A and B at the same time which is a common case in monorepo. Once A has a type error during development, tsc will failed and exit then the wholeturbo run devexited.Nx seems planing to support a long runing task as dependency. https://github.com/nrwl/nx/pull/10706
It would be nice if turborepo also supported this.
The title and description here describes the intended behavior of
--parallel.What’s being described here is more like several feature requests put together. Something like
--watchand some health checking across tasks. We have an issue that we’re actively working on in #986 and have ideas about depending on long-running tasks.I’m going to close this issue since it’s describing the intended behavior - but rest assured that we hear the pains!
My understanding is that this currently works /fine/.
You must not pass
--parallelflag, because that breaks deps, but by default turbo runs with 10 concurrent tasks, and if you have tasks that “hang” and never exit likedev, those will work as long as they fit within the allotted concurrency slots.You’re welcome to use https://github.com/IPWright83/pnpm-monorepo as another example if needed. Requires pnpm, but using
pnpm run dev_idealillustrates the issue. I’ve added adevscript that also does a build to workaround it for now…turbo run build --scope=@iw* --no-deps && turbo run dev --no-cache --parallel --continue@jaredpalmer I just tried that, and unfortunately it doesn’t work either (though I was using
^devto keep the watch mode). The concurrency is going to max out at 2 at the start (due to the lowest level dependencies) and because they never finish it can’t start the next tasks, regardless of the concurrency limit.Sounds like what you want to do isn’t the parallel flag, but rather increase the allowed concurrency so that you are able to run through all build processes first, and then accumulate long running dev processes without running out of the 10 default go-routines.
So have
devdepend on^build, but then run withturbo run dev --concurrency=50