How can I switch between a linked npm dependency (in development) and an installed dependency (in staging/prod)?
Asked Answered
A

1

7

I have a custom npm module that I am working on, and it has a GitHub repo. I'm also working on a project that uses the custom module. When working on the larger project, it is nice to use npm link so I can make changes to the module and see them right away in the main project.

To deploy to staging or production, I use shrinkwrap and shrinkpack so I can do an npm install after every deploy (some of the dependencies need binaries, and dev systems aren't the same as production systems, so they do need to be installed and not just kept in source control). Edit: I'm crossing this out as the answer below technically solves my issue, even though it doesn't solve for this particular point, but that wasn't as important as the rest of it.

Of course, since the module is linked to my main project and not listed in package.json, a deploy and install misses it entirely. I can go ahead and list it in package.json and have it point to the appropriate GitHub repo, but then every time I need to test a change in the main project I would have to commit and push those changes, then update the main project, kill and restart the app...that would get tiresome pretty quickly.

I guess I need something like the opposite of "devDependencies"; something where I can have it not install the module on dev, but do install it from GitHub when doing npm install on staging or production. Other than remembering to manually change package.json every time I need to go back and forth, is there a better way to do this?

Amusement answered 16/3, 2016 at 17:58 Comment(1)
It seems like as of NPM5 the chosen answer no longer works- when i npm link and then npm install the linked folder is removed and replaced with the published-package. I even tried incrementing the locally linked version and then trying install but it still removed/replaced the npm link which was effectively [email protected] (linked, in dev) with [email protected] (published) with package.json having a semver string of lib: "^0.0.1". This is a real problem for me any pointers would be very much appreciated.Ambidextrous
C
9

you can specify a github repository as your package to install, in your package.json file:

{
  dependencies: {
    "my-library": "githubusername/my-library"
  }
}

this will work in your production environment.

in your development environment, use "npm link".

from within the "my-library" folder, run npm link directly. that will tell npm on your local box that "my-library" is avaialable as a link.

now, in your project that uses "my-library", run npm link my-library. this will create a symlink to your local development version of "my-library", allowing you to change code in that repository and have it work in your other project that needs it.

once you are ready to push to production, push "my-library" to your github repository, and then you can npm install on your servers, like normal.

Custommade answered 16/3, 2016 at 18:3 Comment(5)
This makes sense...but what happens if I do npm install (or update or whatever) in dev? Won't it try to install my library? Or is install smart enough to know to ignore installing a dependency if there is a link present? (I should try this out in a separate folder, I was just hesitant to test this theory before since I didn't want to create a huge mess in my main project)Amusement
npm is smart enough to know that you have a local linked library, and it won't overwrite it. i do exactly this, on a very regular basis. it's the best way to develop locally and deploy from wherever (github or npm global repo)Custommade
Seems to work...except I can't shrinkwrap. Tons of "invalid" packages (dependencies of the lib I'm working on), probably because shrinkwrap doesn't like linked dependencies.Amusement
yeah, sorry - i have zero experience with shrinkwrap. i hear nothing but horror stories about it, so i don't even bother.Custommade
That's OK, your basic answer works fine. The main reason we were using shrinkwrap is to use shrinkpack (linked in my question) which keeps tarballs of the modules so you don't have to have super chatty installs, rely on 100% npm uptime, and you have a guaranteed repeatable deploy. But that part I was just playing with, so I'll just stop using shrinkwrap for now. I'll accept your answer. Thanks!Amusement

© 2022 - 2024 — McMap. All rights reserved.