Is it possible to install npm package only if it has not been already installed?

Is it possible to install npm package only if it has not been already installed?

I need this to speed up test on CircleCI, but when I run npm install [email protected] etc. it always downloads things and installs them from scracth, however, node_modules folder with all modules is already present at the moment of running commands (cached from previous build) and protractor --version etc. shows the needed version of the package.

Its perfect to have some one-line command like this:

protractor --version || npm install -g [email protected]

but the one that will also check version of the package.


Solution 1:

You could try npm list protractor || npm install [email protected]

Where npm list protractor is used to find protractor package.

If the package is not found, it will return npm ERR! code 1 and do npm install [email protected] for installation

Solution 2:

with bash you can do

[ $(node -p "require('protractor/package.json').version") != "2.1.0" ] && npm install [email protected]

Solution 3:

Function version of the excellent answer by @JeromeWAGNER:

function install_package_if_needed() {
    local p=${1:-Package required}
    local v=${2:-Version required}
    shift 2
    local i=$(node -p "require('$p/package.json').version" 2>/dev/null)
    [ "$i" == "$v" ] || npm "$@" install "$p@$v"
}

Use like:

$ install_package_if_needed protractor 2.1.0

To pass additional options to npm, specify them after the version, like so:

$ install_package_if_needed protractor 2.1.0 -g

Solution 4:

[ $(node -p "try{require('protractor/package.json').version}catch(e){}") != "2.1.0" ]  && npm install grunt