fh-npm

FeedHenry NPM

Usage no npm install needed!

<script type="module">
  import fhNpm from 'https://cdn.skypack.dev/fh-npm';
</script>

README

fh-npm

fh-npm speeds up npm installs by symlinking to already installed modules in the fh-npm cache if available, allowing node modules to be shared among multiple applications. fh-npm can be used instead of 'npm install', e.g.

<your-node-app-dir> $ fh-npm

If the packages referenced in your package.json have previously been installed by fh-npm, these will be symlinked to in your node_modules directory. Any packages not in the fh-npm cache will be installed via npm into the cache, and then symlinked to your local node_modules directory.

Usage

$ fh-npm --help
    
--help                               help
--version                            version information
--level=<level>                      logging level: fatal, error, warn, info, debug, trace. Default is fatal. Log output goes to stderr.
--cache=<cache-dir>                  The cache dir for fh-npm to use, defaults to $(HOME)/.fh-npm
--npm=<path-to-npm>                  The specific npm binary to use, helpful when working with multiple versions of node
--install=<npm-install-command>      The npm 'install' command to use, defaults to 'install --production'
--clean                              Remove the node_modules dir before install
--copy                               Copy the files from the fh-npm cache into the users node_modules directory (instead of doing a symlink)

How it works internally

This is roughly how fh-npm works, see ./lib/install.js for specifics:

  • read the users package.json, then for each dependency:

  • check if the package is already in the cache: uses semver to compare the users requested package version with what's already in the cache. If there's a semver hit, the cached pacakge is used.

  • if the package is not in the cache, go an install it in the cache. This uses npm to do a normal install of the package@version in the fh-npm cache directory. It then moves the installed package to <fh-npm-cache>/<packge-name>/<version>/.

  • Once the required package is in the cache ok, the symlink is made to it from the users node_modules directory.

Handling of '*'

According to semver * means 'any version whatsoever'. So for example, if a users package.json contains "request": "*", this will match any version of the 'request' package that's already in the fh-npm cache. It is generally recommended that you don't use * in your package.json.

Handling of URL & file references

NPM allows you to specify a URL or file reference for a package dependency instead of a specific version number, e.g.

"foo": "git://github.com/bar/foobar.git#master"

In this case, fh-npm will always 'npm install' the package into the fh-npm cache (fresh each time its called) and symlink to the exact version from there. In order to make best use of fh-npm, it is recommended that you try avoid using URLs or file references for your NPM packages.

Handling of npm shrinkwrap

If a npm-shrinkwrap.json file exists in the users directory, we simply run npm itself, i.e. fh-npm effectively isn't used and a normal npm install occurs.

TODO - future feature requests, etc

Purging the fh-npm cache

Would be nice to be able to safely purge the fh-npm cache. This would involve removing any packages in the cache which have no symlinks pointing to their installation directories. This is not so trivial however, as explained in this SO article: http://stackoverflow.com/questions/4532241/linux-find-all-symlinks-of-a-given-original-file-reverse-readlink.

Better support for shrinkwrap

As explained above, fh-npm is effectively bypassed if shrinkwrap is used.