Open xenoterracide opened 2 years ago
If you're not publishing the root workspace, I don't think it makes sense to run prepack on the root. The root workspace is not "special" in any way.
I'm not a yarn maintainer but my recommendation would be to add a "prepack" entry to each child workspace that calls out to the root (to deduplicate the code). The yarn berry project actually does this. Here's an example on a 3rd party project (one I maintain): https://github.com/tophat/monodeploy/blob/00cd6c10dab0343dfdc6bfbd095b1c7f66a8d213/packages/logging/package.json#L27
There's an additional advantage to having a prepack script defined per workspace, you can support the git protocol with a workspace selector to install a specific workspace from git directly (yarn runs prepack on the target workspace automatically).
Yeah but that's a lot of duplicate code, which is why I'm saying that it would be better to do the tolerate private approach. Also if I did it in every single one, they would all be running typescript build again and again and again and there's only one typescript built at the root because it's a typescript composite repo.
I'm of course not saying that it should necessarily be run automatically, simply that if I say tolerate private, then it runs for that workspace but doesn't actually try to push it. All the advantages, none of the disadvantages in my opinion.
"--tolerate-private" sounds like it'd run all private workspaces, not just the top level workspace. It also seems contradictory to the "no-private" flag.
For your use case, isn't it simpler to just run the following?
yarn prepack && yarn workspaces foreach --no-private npm publish --tolerate-republish
for mine, that's more or less what I'm doing now. The new command would be
yarn workspaces foreach npm publish --tolerate-private --tolerate-republish
which also has the benefit of documenting this as it's not really documented that you have to do any workarounds to publish all the modules in a repo.
there is another use case, what if I have modules that I don't want to publish but I need to run prepack for them in order to build other modules. For example, as you suggest, instead of one single compile I had one per module. For example a types module where I'm not publishing the types, instead I'm publishing other modules that are (esbuild) flattened programs. I still have to build the types to build the programs. That is actually a potential problem down the pipeline for us.
it's not really documented that you have to do any workarounds to publish all the modules in a repo
You don't have to do any workarounds to publish all the modules in a repo. What you're trying to do is run a lifecycle script for a package that you're not publishing.
It's worth noting that there's no connection between yarn workspaces foreach
and yarn npm publish
. You're running yarn npm publish
via yarn workspaces foreach
.
what if I have modules that I don't want to publish but I need to run prepack for them in order to build other modules
Prepack is a lifecycle hook that is meant to be run prior to packing. We only pack prior to publishing. It sounds like you want to prepack even packages that won't be published. It's an interesting problem, one I hadn't considered for my own publishing toolchain (should be easy to support this in monodeploy π ).
Either way, I'll let a yarn maintainer chime in here, but I suspect what you're trying to do is best handled by a build plugin/tool.
Describe the user story
As a developer I want to compile my packages before packing but the root
prepack
script doesn't run when doingyarn workspaces foreach --no-private npm publish --tolerate-republish
Describe the solution you'd like
Perhaps the best option I can think of is a
--tolerate-private
which would run the prepack step, and pack the private modules but not actually push it.Describe the drawbacks of your solution
still requires developer knowledge to work
Describe alternatives you've considered
The workaround is to call prepack directly in my prepublish step for my custom yarn script. note: "publish:yarn" naming is due to some company internal CI stuff. The root package here is private and thus skipped, there's only one root typescript build that builds all workspaces using composite.