3

I have a npm dependency (e.g. ngx-infinite-scroll) that I'm currently trying to fork (for bug fixes) and include my forked version as a dependency in my application. Below an example of the include in my package.json:

  "dependencies": {
    "ngx-infinite-scroll": "github:jcroll/ngx-infinite-scroll#bugfixes",
  },

In the above I've forked the repo at github and created a new branch called bugfixes.

My problem is that the maintainer runs a build process that creates an artifact in a ./dist directory and then publishes this flat directory to npm using $ npm run publish ./dist. However, when I install my new forked repo via $ npm i ngx-infinite-scroll the entire repo is downloaded and not the dist dir.

Now I know this should be expected. One thing I was hoping to do was at least get the dist dir to be created on install by adding to the scripts of the library's package.json:

  "scripts": {
    ...
    "prepare": "npm run build"
  },

However I still do not see the dist directory on install. Even then I would still have to alter the package.json to point the module key to this new nested directory entry point.

What I would like instead is when I install this library from github is to have it publish its flattened dist directory as the top level directory of the library just like how the original library installs by the maintainer building the library and running $ npm rub publish ./dist. Is there any way to do this?

Edit: I am also aware via this answer that I could build the dist and commit the code to this new branch but I'd like a more elegant way, hence the question.

jcroll
  • 6,875
  • 9
  • 52
  • 66

2 Answers2

5

There are two things you can do

Changes to your package

You have a event prepare, postinstall or install and use the below in the same

"postinstall": "cd node_modules/ngx-infinite-scroll && npm i && npm run build"

Then if you really want to use dist, you could do something like below

"postinstall": "cd node_modules/ngx-infinite-scroll && npm i && npm run build && mv dist ../ngx-infinite-scroll-dist && cd .. && rm -rf ngx-infinite-scroll && mv ngx-infinite-scroll-dist ngx-infinite-scroll && cd ngx-infinite-scroll && npm i",

Build in fork

Another option is to change the fork and update the postinstall of the package.json to do the npm run build and create the dist folder when the forked package is installed

Edit: 20-Mar-2018

You were right, if we use postinstall then it will create infinite loop. You can do that in a prepack event.

"prepack": "node build.js",

Below is a sample github project you can actual test

https://github.com/tarunlalwani/ngx-infinite-scroll/tree/so49242809

Test it using

npm add tarunlalwani/ngx-infinite-scroll#so49242809

And it will have the dist folder once installed

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • Hi Tarun, thank you for your answer. Unfortunately I'm not sure the `postinstall` script works. Firstly (as an aside) it appears the `cd node_modules/ngx-infinite-scroll` is not needed. More importantly, however, it seems to create a recursive loop: the dependencies for the package install and because `npm i` was run it begins installing the packages again, and again, ad infinitum – jcroll Mar 19 '18 at 16:12
  • Regarding the `cd node_modules/ngx-infinite-scroll` not being needed I see now you are talking about altering the postinstall script of the parent package. I was trying to alter the postinstall script of the installable package (which is originally what I am after here). I see you attempted this under the "Build in fork" part but again, I'm not sure that works how you've designed. – jcroll Mar 19 '18 at 16:20
  • Additionally Tarun I have now tried altering the `postinstall` of the parent package but the build script of the child package breaks during the installation process because (I believe) paths defined in the script are no longer valid in the because of the nested directory structure. – jcroll Mar 19 '18 at 20:58
  • This appears to work Tarun. My final script (tho ugly) does actually build and flatten the dependency as requested: `"prepack": "npm i && npm run build && find * -type f -not -name 'dist' -not -name 'package.json' -not -path '*dist/*' -exec rm -rv {} + && rm -rf src example node_modules scripts tests dist/package.json && ls -l && mv -v dist/* ."` Nice work finding that hook Tarun. – jcroll Mar 20 '18 at 16:32
  • You may not need the `npm i` there as I could see the `node_modules` existed when the `prepack` was executed – Tarun Lalwani Mar 20 '18 at 16:51
0

There is this simpler way: patch-package

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.

Patches created by patch-package are automatically and gracefully applied when you use npm(>=5) or yarn.

No more waiting around for pull requests to be merged and published. No more forking repos just to fix that one tiny thing preventing your app from working.

rodurico
  • 751
  • 7
  • 17