berry icon indicating copy to clipboard operation
berry copied to clipboard

[Feature] Generate production-only yarn.lock like `yarn1 install --production` used to do

Open PayBas opened this issue 1 year ago • 5 comments

  • [ ] I'd be willing to implement this feature (contributing guide)
  • [x] This feature is important to have in this repository; a contrib plugin wouldn't do

Describe the user story

Not all security/dependency scanners are created equal. Whereas npm audit might be able to differentiate between dependencies and devDependencies (via yarn npm audit --environment production for instance), other tools might not. Our enterprise has multiple such tools which can parse the yarn.lock, but cannot augment the lock-file with all the relevant workspace package.json files to reliably determine exactly which artifacts are "production" and which are not.

In Yarn 1 we used to have a workaround for this:

yarn install --production

Which would generate a new yarn.lock file which only contained the production dependencies. This reduced the amount of "noise" in the security scans drastically for our massive mono-repository.

In Yarn 4 however, there is no such option. The documentation and discussions mention this replacement:

yarn workspaces focus --all --production

But that doesn't actually modify the yarn.lock. It doesn't even generate a new one of the file is completely absent.

Describe the solution you'd like

The same yarn install --production[=true|false] that we used to have with Yarn 1, which did the trick neatly.

Plus a way like yarn install --ignore-scripts so that workspace postinstall scripts don't trigger (which often require devDependencies). And yes: I have read https://github.com/yarnpkg/berry/issues/4780#issuecomment-1219778585 but that assumption ignores use-cases like this.

Describe the drawbacks of your solution

I am not familiar enough with the intricacies of Yarn 4 to really comment. As a laymen: "none" of course ;).

Describe alternatives you've considered

Writing a bash+jq script that parses all package.json files in the repository and removes all devDependencies and then generates a new yarn.lock file. No idea if that would actually work.

PayBas avatar May 31 '24 09:05 PayBas

Since this request is gaining no traction, I have resorted to using:

find . -type f -name 'package.json' -exec yq -i -p=json -o=json 'del(.devDependencies)' {} \;
YARN_ENABLE_CONSTRAINTS_CHECKS=false yarn --mode=update-lockfile

While this obviously creates a very "dirty" workspace, it does seem to clean up the yarn.lock considerably. I use yq instead of jq because of the --inplace flag which makes life much easier.

PayBas avatar May 09 '25 15:05 PayBas

This can be done as a separate command via a plugin. You can reference the source for yarn workspaces focus as the basis of the new command.

Specifically, you need to:

  1. Loop through project.workspaces and remove dev dependencies (in-memory) with workspace.manifest.devDependencies.clear()
  2. Call project.install with persistProject: false and mode: InstallMode.UpdateLockfile

Then you can either use await project.persistLockfile() to overwrite the lockfile, or project.generateLockfile() to get the new lockfile as a string.

clemyan avatar May 10 '25 10:05 clemyan

Hi! 👋

It seems like this issue as been marked as probably resolved, or missing important information blocking its progression. As a result, it'll be closed in a few days unless a maintainer explicitly vouches for it.

yarnbot avatar Jun 09 '25 11:06 yarnbot

This can be done as a separate command via a plugin. You can reference the source for yarn workspaces focus as the basis of the new command.

But wouldn't that require first to actually do a yarn install to obtain the relevant dependencies to manipulate the Yarn project? That would be somewhat annoying since then you would need to obtain all dependencies first (including all devDependencies). My shell workaround doesn't require any such steps.

Besides: I'm in no position to actually write the suggested plugin. I'm no JS/TS developer.

PayBas avatar Jun 11 '25 18:06 PayBas

But wouldn't that require first to actually do a yarn install to obtain the relevant dependencies to manipulate the Yarn project?

No. Even yarn workspaces focus can be run without an install. It's just not recommended as any new resolution is not locked. It calls project.install, which is the underlying API for yarn install.

The hypothetical command I proposed does, more or less, the same thing as your script. The main difference is that it works with the parsed package.jsons in-memory without writeback and thus keeps the filesystem clean.

clemyan avatar Jun 15 '25 16:06 clemyan

Hi! 👋

It seems like this issue as been marked as probably resolved, or missing important information blocking its progression. As a result, it'll be closed in a few days unless a maintainer explicitly vouches for it.

yarnbot avatar Jul 15 '25 17:07 yarnbot

A proper support of this feature will be greatly valuable as we also have the same difficulties identifying what dependencies in yarn.lock (generated by Yarn berry) are from devDependencies and what are ONLY from (non-dev/production) dependencies for security scan purposes.

mma-atl avatar Aug 04 '25 01:08 mma-atl