Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to include package.json in the patch #49

Closed
davidlampon opened this issue Apr 20, 2018 · 23 comments
Closed

Not able to include package.json in the patch #49

davidlampon opened this issue Apr 20, 2018 · 23 comments
Labels

Comments

@davidlampon
Copy link

I was commenting on here as we are (for some unknown reason so far) not able to download the latest beta version which seem to fix the issue about the error after applying a patch.

@ds300 let me explain out situation so maybe you can point the way to go. We are having this issue: a third party package we are using has not properly set the folder directories to point to the /lib and /es folders.

We opened this PR for them to merge but even if that happens then the other package we want to use rc-slider. So in total this means waiting on two external PRs.

As a workaround we wanted to modify or local packages, patch them, to allow this changes which already make our build succesful but we are not able to include the package.jsonfile. We tried yarn patch-package rc-util --use-yarn --exclude /$.^/ as a void regexp to reenable the disbales package.json tracking for the patch but with no success.

As another workaround we modified the /es files to patch the package but the patch-package is presenting the whitespace error This is usually caused by inconsistent whitespace in the patch file.

TL,DR: What would be the way to include package.jsonin the patch?

@ds300
Copy link
Owner

ds300 commented Apr 20, 2018

Hi! 👋 Thanks for the thorough explanation :-)

The first thing I noticed is that you're using JS-style regexp literals with the --exclude override. Instead you should use regular strings. See the examples in include-exclude-paths.sh – particularly this one which uses interesting regexp syntax. Imagine you were passing the string to new RegExp(...)

Thanks for bringing this issue to my attention. I'll try to improve that section of the readme.

@dawnmist
Copy link

dawnmist commented Apr 24, 2018

If you can add an example for disabling the default exclude, that'd be fantastic.

The other time that being able to patch package.json is desirable is when adding typescript type definitions to a package that doesn't have its own type definitions, so that you can add the "types" field to the package's package.json file pointing to your new type definition file.

Edit: It doesn't seem to matter what the exclude regex is, package.json is hardcoded to be excluded in the diff inside makePatch at:

// don't commit package.json though
fs.unlinkSync(
path.join(tmpRepo.name, "node_modules", packageName, "package.json"),
)

and:
// remove package.json again
fs.unlinkSync(
path.join(tmpRepo.name, "node_modules", packageName, "package.json"),
)

At present, the only way to be able to include package.json in the diff is to first patch patch-package to comment out those two lines in the compiled code. There's a bit of humour there in using patch-package to patch patch-package itself...

Patch: patch-package+5.1.1.patch - to allow enabling patching of package.json if you also use a regex that doesn't include it (e.g. --exclude '\*.txt').

patch-package
--- a/node_modules/patch-package/dist/makePatch.js
+++ b/node_modules/patch-package/dist/makePatch.js
@@ -66,14 +66,14 @@ function makePatch(packageName, appPath, packageManager, includePaths, excludePa
         fs.writeFileSync(path.join(tmpRepo.name, ".gitignore"), "!/node_modules\n\n");
         tmpExec_1("git", ["init"]);
         // don't commit package.json though
-        fs.unlinkSync(path.join(tmpRepo.name, "node_modules", packageName, "package.json"));
+        // fs.unlinkSync(path.join(tmpRepo.name, "node_modules", packageName, "package.json"));
         tmpExec_1("git", ["add", "-f", slash(path.join("node_modules", packageName))]);
         tmpExec_1("git", ["commit", "-m", "init"]);
         // replace package with user's version
         rimraf.sync(tmpRepoPackagePath);
         fsExtra.copySync(packagePath, tmpRepoPackagePath, { recursive: true });
         // remove package.json again
-        fs.unlinkSync(path.join(tmpRepo.name, "node_modules", packageName, "package.json"));
+        // fs.unlinkSync(path.join(tmpRepo.name, "node_modules", packageName, "package.json"));
         // stage all files
         tmpExec_1("git", ["add", "-f", slash(path.join("node_modules", packageName))]);
         // unstage any ignored files so they don't show up in the diff

@ds300
Copy link
Owner

ds300 commented Apr 24, 2018

Oh yes, you're right! Really sorry about the mixup. I think those lines should have been removed when I added the --include and --exclude options.

@ds300 ds300 added the bug label Apr 24, 2018
ds300 pushed a commit that referenced this issue Apr 24, 2018
@ds300
Copy link
Owner

ds300 commented Apr 24, 2018

Just published a fix for this in patch-package@6.0.0-4 – Thanks for pointing this out @dawnmist and @davidlampon 🙇 ❤️

I'll close this once v6 leaves beta.

@brunolemos
Copy link

brunolemos commented May 23, 2018

I'm using 6.0.0-7 and I'm not able to patch a package.json from another package, how can I do that?

EDIT: Adding a --exclude '\*.txt' made it work.

I removed a package from a third party package.json but when I run yarn it gets added to yarn.lock anyway :( It makes sense, as it run a postinstall script.

Tried this but did not work: "preinstall": "patch-package --include 'package\\.json$'"

@ds300
Copy link
Owner

ds300 commented May 23, 2018

Hi @brunolemos 👋 !

Unfortunately what you want to do is not possible 😢 This is a common question about patch-package. I don't know of a way to get absolute control over which transient dependencies get installed. The best thing I've found is manually editing your own lock file, but that's only useful for making sure a specific version gets installed.

@ivikash
Copy link

ivikash commented Oct 18, 2018

I am trying to patch a dependency of a dependency in the package.json. It does generate the patch file with a little noise (using npm) but is unable to apply the patches -> **ERROR** Failed to apply patch for package somePackage. Can you include a short summary or documentation on the usage, like how to generate the patch file and especially what should be done in prepare step. I am currently using 6.0.0-v5 due to some constraints.

@ivikash
Copy link

ivikash commented Oct 23, 2018

@ds300 Any update on this? Also, as I am using npm so should the patch-package be applied on prepare or postinstall? While trying with preinstall its throwing an error saying patch-package is not found.

@danieldunderfelt
Copy link

danieldunderfelt commented Nov 19, 2018

@ds300 so when will v6 leave beta? At least the beta is installable with npm, so it's not a huge issue, but people who are looking to patch package.json need to be aware about the beta and actively install it.

And yes, the beta works very well, so far as this issue is concerned!

@ds300
Copy link
Owner

ds300 commented Jan 20, 2019

Closing this to tidy up, final 6.0.0 release will happen soon 🎉

@ds300 ds300 closed this as completed Jan 20, 2019
@nerdaliciousCH
Copy link

How to make an empty --exclude that doesn't match anything?? so --include 'package\.json$' --exclude '$'. That doesn't work for me :D

@dawnmist
Copy link

@nerdaliciousCH try making up a string that might be a filename but isn't.
e.g. --exclude 'IAmNotARealFile.txt'

The '$' in a regexp string means "at the end of the line" (or "end of the string" for something like filename strings). By having nothing before the $, you're actually matching every filename because every filename will have an end of the string.

@xstable
Copy link

xstable commented Jun 19, 2020

I use npx to run patch-package.
If I check for the Version I got:

npx patch-package -v
patch-package 6.2.0

So I'm right, that the include && exclude funcitonality still not implemented?
I use this:
postinstall": "patch-package --include 'package.json$' && jetify"
or double-escaped like this:
"postinstall": "patch-package --include 'package\\.json$' && jetify"

Both don't recognize the changes in package.json.

@dawnmist
Copy link

The --include and --exclude options are there - but they're used when creating patches for other packages, not during postinstall (where you're applying patches to the various npm packages). You also need to be providing the --exclude option to override the default setting if you want to include changes to the package.json in the patch.

So to use it, you would first:

  • Modify the files inside the node_modules/package-to-be-patched so that they contained what you needed, then
  • Create the patch for the package using:
patch-package --exclude 'nothing' package-to-be-patched
  • Check that the patch file generated contains what you expected it to. If not, return to step 1 to update the contents of the package that you want to patch so that it reflects the correct information and redo the patch creation again.
  • Then set up postinstall so it applies the generated patches after each installation:
"postinstall": "patch-package && jetify"

You won't be able to change the dependencies in another project's package.json, because the patch is only applied after the dependencies have been installed. But you can do things like add a typescript type definition file to a project and update its package.json file to point to your new types.

@DominikGuzei
Copy link

@dawnmist why not remove the default for --exclude? If we don't make changes to the package.json it wouldn't be picked up anyway, right?

@dawnmist
Copy link

dawnmist commented May 3, 2021

@dawnmist why not remove the default for --exclude? If we don't make changes to the package.json it wouldn't be picked up anyway, right?

@DominikGuzei You'd probably be better asking the project maintainer that question. I am just someone who uses patch-package (and highly recommends it for certain tasks) who also had to work out how to make changes to the package.json work (for adding typescript types to a few packages).

That said, my suspicion is that it's because any patch you apply to the npm package's package.json is only applied after all its dependencies have already been installed - so most changes you could potentially make to the npm package's package.json file would be applied too late for them to actually do what you intend them to do. If those changes were included by default, many people would try to use them in situations where they do not work and the maintainer would forever be answering issues about things like "I modified the package's dependencies using patch-package, but npm/yarn are still installing the old ones!?" due to people not understanding that the modification only gets applied after all packages are installed.

@DominikGuzei
Copy link

@dawnmist makes sense, thanks for the detailed explanation! 👍 sorry for the mistake 😅

@JellyL
Copy link

JellyL commented Jan 4, 2022

I think --exclude 'nothing' should be the default setting

@perrin4869
Copy link

I think the biggest case for --exclude 'nothing' is that one common requirement is to modify the exports field of a package.json file - due to many of them lacking exports for esm modules yet

@karlhorky
Copy link

karlhorky commented Mar 29, 2022

To really exclude everything without choosing a filename that doesn't exist (which could lead to weird unexpected edge cases), use a regular expression pattern containing an empty string to exclude everything:

$ yarn patch-package react  --exclude '^$'

@devinrhode2
Copy link

devinrhode2 commented Apr 22, 2022

I don't think anyone mentioned this idea yet
But as typically we have 1000's of npm packages, this means most individual npm packages are not that huge.

If we tweak our gitignore to ignore all node_module sub-folders like so:

node_nodules/*

We can then INCLUDE a certain node_module sub-folder in our git repo:

!node_modules/rc-slider

I think this may altogether be a better approach than patch-package, unless the package you are touching is huge. By simply checking the node module into git directly, there's a lot of nice simple benefits

siderakis added a commit to siderakis/Amplitude-TypeScript that referenced this issue Jun 17, 2023
Currently there is no way to avoid downloading async storage. Even when we supply our own alternative storage provider. This is causing errors.

ds300/patch-package#49
@pkit
Copy link

pkit commented Aug 21, 2023

For people who want to actually change dependencies: use yarn "resolutions" although it's not perfect (cannot install a new package that didn't exist before), it covers a lot of cases.

@pkit
Copy link

pkit commented Aug 21, 2023

By simply checking the node module into git directly, there's a lot of nice simple benefits

Dunno, looks like that approach gives zero new features compared to patch-package, but pollutes the repo with a bunch of garbage.
Any examples of the benefits?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests