Matthias
Matthias

Reputation: 15425

Why does `npm install` use the shrinkwrap's 'resolved' property

I am considering setting up a local npm mirror such as "npm_lazy" on my computer. But it seems like npm install and npm shrinkwrap don't work well with local mirrors.

Let me explain. When there is an npm-shrinkwrap.json file, the npm install command always requests packages from the URL specified in the shrinkwrap file's "resolved" property. So, even if I have a local npm mirror running at http://localhost:12345/, and even if I configure npm to use that as its registry, it will not request any package modules from my local mirror (unless a "resolved" property in the shrinkwrap file happens to point to http://localhost:12345/).

Basically, npm install ignores npm's registry configuration and follows the shrinkwrap "resolved" property.

Is there a reason why npm install uses the "resolved" property instead of constructing it dynamically with the dependency package name and version? Why does npm-shrinkwrap.json have this field at all?

So back to my issue. I want to use npm_lazy as a local npm mirror. I could rewrite all the "resolved" URLS in npm-shrinkwrap.json to point to http://localhost:12345/. But then my shrinkwrap file is less portable — my coworkers would not be able to use unless their computers have the same npm_lazy server running.

I have considered redirecting all registry.npmjs.org traffic to localhost in order to create a transparent mirror. But it would be too hard -- it needs to supoprt HTTPS, and also, how would npm_lazy access the true domain? I would have to specify it by its IP address, which may change.

Has anyone else attempted to do the same thing -- to set up a local-computer NPM cache? But, my main question is, why does npm use the "resolved" property? Thanks.

Upvotes: 4

Views: 3629

Answers (2)

aleung
aleung

Reputation: 10308

I prefer not to save resolved property into npm-package.json.

The utility shonkwrap do the trick. But it impacts everybody in the team: type shonkwrap instead of npm shrinkwrap. Or you can write similar code into your build script (e.g. gulpfile) to delete resolved property from existing npm-package.json.

Upvotes: 0

Kenney
Kenney

Reputation: 9093

Shrinkwrap locks down the dependencies, attempting to guarantee the same 'build' (or dependencies) for everyone using that shrinkwrap file. It not only locks down the versions, but also the repository URL, for the same reason: changing any of these potentially changes the content of the package, thus losing any guarantee. Of course, if shrinkwrap were aware of the concept of a repository cache or proxy, it should certainly use yours, but apparently it isn't.

Normally you'd replace the repository URL in package.json (since this is a source file) and run npm shrinkwrap again to re-generate the npm-shrinkwrap.json file (since it is a generated file), and keep that on a local dev branch. But it is a hassle to keep configuration files separated.

So you could enter cache.repository.example.com as the repository hostname, and add a CNAME to DNS pointing to npmregistry. Anyone having npm_lazy installed locally could then safely override this DNS entry in their Hosts file to point to localhost.

However, there is a simpler solution to localize your checkout. Recently I answered a question with this little script to update package.json versions with values from npm-shrinkwrap.json, which can easily be adapted to update all resolved properties in npm-package.json to use your proxy, and which I will leave as an excercise ;-)

Upvotes: 2

Related Questions