4

I'm looking for a pattern to avoid the need of global packages when working with node, I'd like to install everything I need with npm install and then just running every command with npm run xxx, without any global package installed.

For example, I have jest configured to run my tests.

These are the dependencies in my package.json:

[...]
},
"author": "",
"license": "ISC",
"dependencies": {
  "@types/express": "^4.16.1",
  "@types/node": "^11.10.5",
  "express": "^4.16.4",
  "ts-node-dev": "^1.0.0-pre.32",
  "typescript": "^3.3.3333"
},
"devDependencies": {
  "@types/jest": "^24.0.9",
  "@types/supertest": "^2.0.7",
  "jest": "^24.3.1",
  "nodemon": "^1.18.10",
  "supertest": "^4.0.0",
  "ts-jest": "^24.0.0"
}
[...]

and these are some scripts I have configured:

[...]
"scripts": {
  "test": "jest --coverage",
  "tsc": "tsc",
  "watch": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/server.ts"
},
[...]

But when I issue npm run test I get this error:

$ npm run test
> ci-test@0.0.1 test /home/sas/devel/apps/vue/ci-test
> jest --coverage
sh: 1: jest: not found
npm ERR! file sh
[...]

If I install jest globally with npm install -g jest everything runs fine, but that's precisely what I'm trying to avoid.

A few assumptions I made that might be wrong:

  • when running scripts node first looks for commands in node_modules/.bin (in order to use locally installed packages)

  • when I issue npm install every command line command is installed to node_modules/.bin

This last one is not working, because even though I have jest in my devDependencies there's no node_modules/.bin/jest file in my project

$ ls node_modules/.bin/
acorn  cdl        esgenerate  esvalidate            is-ci  json5    loose-envify  mime    nodetouch  parser  semver      sshpk-sign    strip-indent  watch
atob   escodegen  esparse     import-local-fixture  jsesc  js-yaml  marked        mkdirp  nopt       rc      sshpk-conv  sshpk-verify  uglifyjs

On the other hand, as a workaround, the following seems to work:

"scripts": {
  "test": "npx jest --coverage",

But it takes more than 10 seconds for npx to install jest everytime I run npm run test

So, what would be the correct way to achieve it? O how can I tell npm to install jest to node_modules/.bin and use it whe I reference it in my scripts?

opensas
  • 60,462
  • 79
  • 252
  • 386
  • 1
    Check again your `NODE_ENV` environment variable, if it is `production`, then `npm install` command only downloads dependencies package. Finally, make sure `NODE_ENV !== production`, then run `npm install` command again (my expect: `jest` and `nodemon` will appear in your `node_modules/.bin/`) – hoangdv Mar 11 '19 at 08:10
  • NODE_ENV is empty, but I could tell npm to install devDepencies with the --only=dev option – opensas Mar 11 '19 at 08:12
  • 1
    strange thing, now I did several tests setting NODE_ENV to development, and the unsetting it, and now `npm install` installs devDependecies, like you said it should – opensas Mar 11 '19 at 08:21

1 Answers1

4

It seems like it was easier than expected, I just had to issue:

npm install --only=dev

seems like by default npm won't install dev dependencies


I did a couple more tests, playing with the NODE_ENV var, and after unsetting it npm install seems to install also devDependencies, along with jest in node_modules/.bin/jest. It seems like somehow it was assuming I was in production mode.


Another trick I learned to avoid installing global dependencies is to install it with --save-dev, and then adding a script to run it with npm run. For example, to avoid installing jest globally but still be able to use it from the command line you should:

npm install jest --save-dev

Then add the following to your package.json

scripts: {
  "jest": "jest"
}

And then you can run it from the command line with npm run jest. To pass params from the command line you have to add a '--' before the params, like this: npm run jest -- --coverage. Or you could just issue npx jest --coverage, if installed, npx will use jest from node_modules/.bin. (check this for more info)

BTW, this answer to a similar question might be useful

opensas
  • 60,462
  • 79
  • 252
  • 386