Thoughts on yarn workspaces support
ds300 opened this issue · comments
patch-package already works with yarn workspaces if you only use it from the root directory and only ever call yarn
or yarn install
from the root directory. Things break down when working from a package directory or trying to patch packages that haven't been hoisted.
Here are some things that will need to change to fix that. There might be other gotchas I'm not identifying.
Making patches:
-
It currently assumes that the package you specify when you run e.g.
patch-pacakge react-native
is at$PWD/node_modules/react-native
. This might not be true if$PWD
is a package dir rather than the repo root. So the object returned bygetPackageDetailsFromCliString
would need to have itspath
property resolved usingrequire.resolve
-
If the package to be patched has actually been hoisted, I want to hoist the patch file to the repo root too. So you might end up with a structure like
/ node_modules/ react/ react-spring/ patches/ react+17.0.0.patch packages/ client/ node_modules/ react-spring/ patches/ react-spring+4.3.1.patch
It should end up like this even if you run
patch-package react
andpatch-package react-spring
both frompackages/client
-
The readme should state that you'll need to have patch-package installed both in the root project and in any sub projects you intend to use it from.
Applying patches:
- Ideally, one invocation of
patch-package
in the repo root should apply all the patches for the entire repo. - So when finding patch files to apply, patch-package needs to find out where all the package dirs are. That means inspecting the
package.json
"workspaces"
field. Obviously someone has written that code before, so hopefully it'll be easy to get at. - If you run
yarn
from a package dir, thepostinstall
step defined in the rootpackage.json
doesn't get called. So we'll need to instruct people to add"postinstall": "cd ../../ && patch-package"
to childpackage.json
s (or something that'll work both on windows and *nix). - the patch application process currently assumes the paths in patch files are relative to
$PWD
. So this function will probably want to figure out the appropriate working directory (i.e. a child package directory or the root directory) from the patch's file path and then pass that down toexecuteEffects
.
That's all I can think of right now.
edit: oh and obviously tests. patch-package is mainly tested with integration tests. You can make a new one with yarn new-integration-test my-test-name
and then it'll create a little npm package with a shell script in it. The shell script is the test file, the npm package is the test fixture. Check out the existing integration tests to see the patterns I've been using and how to take snapshots, if you decide to work on this.
Closing this. After more investigation I can get an MVP by only fixing the yarn.lock resolution in detectPackageManager so that you can make patches in package dirs.
@ds300 can you elaborate a bit about how you fixed it? I'm facing the issue you described.
To clarify, I'm trying to make patch-package work in a yarn workspaces project with per-package patches.
I'm running yarn workspace package1 install
and I'm getting Error: Patch file found for package XYZ which is not present at node_modules/XYZ
. This means it's looking in ./package1/node_modules
, but the package exists in ./node_modules/XYZ
@the21st did you manage to solve it? Having the same issue
@mattvb91 we set it up in a hacky way for e.g. package1's package.json
: "postinstall": "cd .. && patch-package && patch-package --patch-dir <package1>/patches"
. It isn't stable though. We're considering migrating to yarn2's patch
isntead.