NPM Dependencies Dilemma

Miko Gao
3 min readNov 29, 2016

--

NPM has been by far the most common tool to use everyday. And for now our project is served online statically, so there are no NPM dependency problems. But we did meet some several times in the development process. You know, some guys new to the project clone it and run `npm install`, then ‘It does not work on my computer.’ ‘Really? It does work on mine.’ happened.

Later we knew it was because of the `^` or `~` in those dependency versions. When some dependency has incompatible updates (which occurs every second), or someone forgets saving the dependencies they use to the package.json, there will be such errors.

Put all into the repo

It reminds me that when I worked in another team, we put node_modules into the repo. It did work in different environment, except the big repo size and the long fresh clone time.

Adding new dependencies or updating existing ones can generates commits hard to diff and review.

Clearly, this is not a good enough solution.

‘lock’ version with `-E`

Okay then, now that we know there should be no range syntax in dependency version, we should not forget to add dependencies to package.json. How about using [`npm install -SE`](https://docs.npmjs.com/cli/install) ? To avoid using these parameters all the time, they could be saved to .npmrc.

```
save=true
save-exact=true
```

Seems good, right ? But because we actually cannot grantee that the dependency version of dependencies we use has no range syntax, there will be no identical dependency tree in all the environments.

So sad.

npm shrinkwrap

Then I found the shrinkwrap.

This command locks down the versions of a package’s dependencies so that you can control exactly which versions of each dependency will be used when your package is installed.

The shrinkwrap command has locked down the dependencies based on what’s currently installed in node_modules.

Wow, really impressed. Sounds like they realized the problem and offered this best solution.

Some package requires some dependencies, but for some reasons we don’t use these packages but choose to link them directly instead.

Need much more labor to follow the dependency updates (for there are frequent bug fixes and new features)

And you have to do it according to the ‘best practices ’ to avoid fails of shrinkwrap .

1. Run npm install — save-dev left-pad
2. Run npm prune to de-dupe the dependency graph incase one of your existing modules made use of left-pad somewhere otherwise npm shrinkwrap will fail
3. Run npm shrinkwrap — dev to update the shrinkwrap file
4. Raise a pull request, note that the npm-shrinkwrap.json file has a tone of unreadable and unexpected changes — enjoy the fact that github refuses to render the diff on the shrinkwrap file…

Even though,

If you wish to lock down the specific bytes included in a package, for example to have 100% confidence in being able to reproduce a deployment or build, then you ought to check your dependencies into source control, or pursue some other mechanism that can verify contents rather than versions.

Then, there is Yarn. Although I don’t agree with the reason they make it, only if it resolves all these problems without causing new trouble, it’s a better solution.

--

--