Reputation: 4693
Say I have a Node.js app, lets call it patched-app
. This app is a simple app that uses prompt-sync to ask for user input and then does something with it.
So we create a folder patched-app
and initialize it with npm init
. We then run npm i prompt-sync
and create a new file called index.js
where my code would be. To make things a little bit more interesting, I will also create a git repository here and this is the result:
+---patched-app
| | .gitattributes
| | .gitattributes
| | .gitignore
| | index.js
| | package-lock.json
| | package.json
| |
| +---node_modules
| | | .package-lock.json
| | |
| | +---ansi-regex
| | | index.js
| | | license
| | | package.json
| | | readme.md
| | |
| | +---prompt-sync
| | | index.js
| | | LICENSE
| | | package.json
| | | README.md
| | | test.js
| | |
| | \---strip-ansi
| | index.d.ts
| | index.js
| | license
| | package.json
| | readme.md
| \---.git
| <<git stuff>>
Now the issue here is that I don't like something with this prompt-sync
package and so I want to edit node_modules/prompt-sync/index.js
and change it to my liking. I don't necessarily want to create a whole new module such as prompt-sync-swiffy
(or do I?), as my changes are small enough so I don't have to download any new packages for prompt-sync
, so I'm good with the existing dependencies of ansi-regex
and strip-ansi
.
I could just open up node_modules/prompt-sync/index.js
, edit it and be done - and that's what I have pretty much been doing thus far because I don't know any better. I have recognized at least three major issues with this though:
prompt-sync
anymore or I might lose the changes I made (losing !== just breaking my patched changes)npm audit fix
etc, as those might also overwrite my changesnode_modules
to .gitignore
and if anyone were to pull my repository and run npm install
, it would install prompt-sync
without my changesI also don't necessarily want to fork prompt-sync
and / or create a new "official" NPM package. What I want is a method that allows me or anyone else to run npm install
normally, while somehow keeping my patches to modules local e.g. have a module_patches
folder which isn't ignored by the repository.
It is OK if a newer version of prompt-sync
breaks my patch. That would be on me to update the patch or use a locked in version of prompt-sync
.
So what are my options?
Upvotes: 14
Views: 23399
Reputation: 13255
Assuming you've made the changes to node_modules/some-package
already and have a working app.
rm -rf android/build
# run patch-package to create a .patch file
npx patch-package some-package
# commit the patch file to share the fix with your team
git add patches/some-package+3.14.15.patch
git commit -m "fix brokenFile.js in some-package"
Patches created by patch-package are automatically and gracefully applied when you use npm(>=5) or yarn.
Setup
In package.json:
"scripts": {
+ "postinstall": "patch-package"
}
And run:
npm i patch-package
Upvotes: 1
Reputation: 2477
Patch-package lets app authors instantly make and keep fixes to npm dependencies. It's a vital band-aid for those of us living on the bleeding edge.
MODEL
nano "node_modules/<PACKAGE_NAME>/some_file.js"
MODEL
npx patch-package "<PACKAGE_NAME>"
For patches to be applied during installation, these settings/resources are necessary in your "package.json".
[...]
"dependencies": {
[...]
"patch-package": "X.X.X",
"postinstall-postinstall": "X.X.X",
[...]
},
[...]
"scripts": {
[...]
"postinstall": "patch-package"
},
[...]
Ref(s):
Thanks! 😘
Upvotes: 10
Reputation: 4617
A nice way to patch NPM packages is using patch-package. It will automatically create patch files of your changes and apply them in postinstall hook.
Upvotes: 23