Search code examples
patchyarnpkg-v2

Getting errors when patching a npm package


when I patch a dependency like this:

package.json:

  "dependencies": 
    "react-native-webview": "patch:[email protected]#scripts/patches/react-native-webview+11.0.3.patch",
    ...

patches/react-native-webview+11.0.3.patch:

diff --git a/apple/RNCWebView.m b/apple/RNCWebView.m
index ff9ff9e0..dfea91a8 100644
--- a/apple/RNCWebView.m
+++ b/apple/RNCWebView.m
@@ -194,12 +194,18 @@ - (void)dealloc
...

everything works fine when I install things locally using yarn or yarn install. The patch gets applied, and there are no errors.

However, when things go into CI, I get an error like the following:

**ERROR** Failed to apply patch for package react-native-webview at path
  
    node_modules/react-native-webview

  This error was caused because patch-package cannot apply the following patch file:

    patches/react-native-webview+11.0.3.patch

  Try removing node_modules and trying again. If that doesn't work, maybe there was
  an accidental change made to the patch file? Try recreating it by manually
  editing the appropriate files and running:
  
    patch-package react-native-webview
  
  If that doesn't work, then it's a bug in patch-package, so please submit a bug
  report. Thanks!

    https://github.com/ds300/patch-package/issues

Things don't get better if I change the patch to use paths like a/node_modules/react-native-webview/apple/RNCWebView.m. I then get an error like

➤ YN0001: │ Error: react-native-webview@patch:react-native-webview@npm%3A11.0.3#../../scripts/patches/react-native-webview+11.0.3.patch::version=11.0.3&hash=d13297&locator=proj-core%40workspace%3Alib%2Fproj-core: ENOENT: no such file or directory, lstat '/node_modules/react-native-webview/node_modules/react-native-webview/apple/RNCWebView.m'
    at rn (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:172:9625)
    at kn (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:172:9889)
    at Qr.resolveFilename (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:177:21594)
    at Qr.resolveFilename (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:177:21498)
    at Qr.resolveFilename (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:177:21498)
    at Qr.lstatSync (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:177:18712)
    at Qr.lstatPromise (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:177:18671)
    at yt.lstatPromise (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:177:34701)
    at Zu (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:578:7908)
    at YB (/home/user/dev/proj-client/.yarn/releases/yarn-3.0.0.cjs:580:184)

Solution

  • The problem here is that you're using two different tools to patch the npm package, and using a different one locally than in CI:

    • patch-package as a post-install script (if you check the "postinstall" entry in your package.json, you'll see something like patch-package --patch-dir ./scripts/patches)
    • yarn's built-in package patching thing, which uses patch: in package.json.

    However, they work differently:

    patch-package yarn's patch:
    applies the patch from the project root, so you need to include node_modules/package-name in the diff. applies the patch from the package install directory, so you don't need to do that
    requires that the patch be named package-name+version.patch doesn't require any specific naming

    The solution here is to pick one, and to change the patch to work with that system. So, for example, if you rename the file to remove the +version, you'll be able to move forward using just yarn's patch:.