-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Describe the feature you'd like to request
I've been thinking about this for some time now. The idea keeps nagging me. Imagine - I have a dts task that I can run for every package in my monorepo, but that task doesn't have any value for the end user (read developer in a team using the monorepo) by itself - meaning user will never run that task manually via turbo run or pnpm run. The task is needed to run another dts-bundle task - essentially dts produces an intermediate artefact that allows dts-bundle that depend on it to succeed without errors. Now the problem is that dts-bundle needs to run dts for all dependencies.
This seem to work nicely:
"pipeline": {
"dts": {
"inputs": [...],
"outputs": [".tsc-out"]
},
"dts-bundle": {
"dependsOn": ["^dts"],
"inputs": [...],
"outputs": ["dist/**/*.d.ts"]
},
}But little issues creep up - mostly scalability:
- Every package has to have that
dtstask declared inpackage.jsonscripts - it probably wouldn't make sense to have to copy-paste it everywhere since the task is basically single script that can work in every package sub-folder and produces output in that package sub-folder, but has no input other than source code and doesn't need any configuration on per package basis - The
dtstask must be run for every dependency of a package where we about to rundts-bundle, but a developer might forget to add a script topackage.jsonfor one of those dependencies - when adding thatdtsscript they might also make a mistake and pass wrong parameters or things like that - When a developer decides that they want to start using
dts-bundlefor their package they have to go and check every dependency and whether that dependency hasdtstask declared. Hopefully it's very easy change and a quick PR away, but those packages could be owned by other teams.
In addition to that it's also possible that inputs of some other build task in one package is different to another package's inputs. But the fact that those differences should be specified in the root of the monorepo in a single file is kind of limiting. If we look at monorepos with huge number of packages I feel single turbo.json might become a bottleneck (with some merge issues maybe even?). Sometimes a script can determine those inputs/outputs programmatically and can operate in the entire monorepo for any sub-package. E.g. I imagine a script could determine all the dependent *.ts files imported and build a graph of files that it depends on (inputs) - and that would probably be more efficient than using globs like src/**/*.ts that could hit hundreds of files.
Another script could determine which dependencies need to have dts task run and which don't. There is generally a lot of things that can and should be automated and turbo doesn't provide too much here. The CLI could be considered as API and turbo.json can be generated - but it makes it harder to use hybrid approach - use ability of the turbo to cache and also allow devs to use turbo.json without having to deal with a script.
Describe the solution you'd like
- Allow specifying commands right in the
turbo.json, example:
"pipeline": {
"dts": {
"command": "node ./monorepo-scripts/generateDts.js",
// ^-- no need to copy-pasta in every package
"inputs": [...],
"outputs": [".tsc-out"]
},
}turbo would assume the command exists in every package as if it was added to every package's scripts config.
- Allow passing location of a custom
turbo.dts.jsonfile OR preferably - allow it to be passed asstdin. If location of theturbo.jsonimplies root of the monorepo we could also add extra parameter or assume it's cwd. This will maketurbosuper powerful tool that would allow caching any task - whether it can be described byturbo.jsonmanually or generated by a script.
Both of the above seem like a simple change on the surface. But there must be some caching implications. E.g. we would need to store hash of the stdin config somewhere which could serve as a cache key for the rest of the data associated with the run ...
Describe alternatives you've considered
Generating turbo.json is possible, but writing scripts to every package.json - seem like a less desired path as it's often modified manually.