ds300 / patch-package

Fix broken node modules instantly 🏃🏽‍♀️💨

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 by getPackageDetailsFromCliString would need to have its path property resolved using require.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 and patch-package react-spring both from packages/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, the postinstall step defined in the root package.json doesn't get called. So we'll need to instruct people to add "postinstall": "cd ../../ && patch-package" to child package.jsons (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 to executeEffects.

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.