Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to "patch" a node_modules module?

Tags:

node.js

npm

patch

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:

  • I cannot update prompt-sync anymore or I might lose the changes I made (losing !== just breaking my patched changes)
  • I cannot basically run any package commands, such as npm audit fix etc, as those might also overwrite my changes
  • This doesn't work at all, if I want to have my project in a git repository, because I will obviously add node_modules to .gitignore and if anyone were to pull my repository and run npm install, it would install prompt-sync without my changes

I 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?

like image 238
Swiffy Avatar asked Dec 12 '25 02:12

Swiffy


2 Answers

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.

Install patch-package:

npm i patch-package

In package.json add the postinstall hook:

"scripts": {
  "postinstall": "patch-package"
}

Edit the prompt-sync package using your editor of choice:

vim node_modules/prompt-sync/index.js

Generate a patch file using patch-package:

npx patch-package prompt-sync

Commit package.json changes and the generated .patch file.

Now when a coworker pulls your changes and runs npm i the patch will be applied to prompt-sync.

Read the awesome patch-package docs for more details.

like image 192
Andrei Avatar answered Dec 14 '25 14:12

Andrei


Patch a "node_modules" (Node.js) module

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.

Process

Fix a bug in one of your dependencies

MODEL

nano "node_modules/<PACKAGE_NAME>/some_file.js"

Run patch-package to create a "*.patch" (in "patches" folder) file

MODEL

npx patch-package "<PACKAGE_NAME>"

Required settings/resources in your "package.json"

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):

  • https://stackoverflow.com/a/72826192/3223785
  • https://www.npmjs.com/package/patch-package

Thanks! 😘

like image 30
Eduardo Lucio Avatar answered Dec 14 '25 15:12

Eduardo Lucio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!