3

Inside package.json, is it possible to test if node_modules directory exists? My goal is to print a message if node_module does not exists, something like:

node_module not existent: use npm run dist

where dist is a script inside scripts of my package.json. Thank you.

caneta
  • 1,612
  • 2
  • 20
  • 34

4 Answers4

5

I thought I would post what I've done for cross-platform one-liner conditional NPM scripts.

"scripts": {
    "start":"(node -e \"if (! require('fs').existsSync('./node_modules'))
{process.exit(1)} \" || echo 
'node_module dir missing: use npm run dist') && node start-app.js",
}
joshhemphill
  • 492
  • 6
  • 20
  • 1
    Clever, not quite right for the OP, but up-voted irrespectively as it adds value. – Arthur Weborg Dec 15 '21 at 22:10
  • 1
    That is, consider changing the hard-coded values `./bin/helpers` as well as `setup-helpers` and `npm run final-build-step` to match the original question at hand. – Arthur Weborg Dec 15 '21 at 22:15
3

As suggested by B M in comments, I've created the following script named checkForNodeModules.js:

const fs = require('fs');
if (!fs.existsSync('./node_modules'))
  throw new Error(
    'Error: node_modules directory missing'
  );

And inside my package.json:

"scripts": {
  "node-modules-check": "checkForNodeModules.js",
  "start": "npm run node-modules-check && node start-app.js",
}

Thanks!

caneta
  • 1,612
  • 2
  • 20
  • 34
2

Yes it is, via npm scripts. Which npm script to use is your choice. If your application starts via npm start (good practice) use the start script to add your check:

"scripts": { "start" : "./test.sh" }

The actual test for the directory can be implemented via a shell script or a NodeJs script, consider using npx as discussed in Difference between npx and npm?.

B M
  • 3,893
  • 3
  • 33
  • 47
  • I see two issues: on Unix like systems `test.sh` will run but on Windows systems will not; npx executes npm binaries, but at time 0, I have no node_modules directory, so what executable to run, a global one? What if a colleague with brand new node installation has no global executables? – caneta Oct 04 '19 at 10:32
  • If you need a platform independent solution `npx` will be the better choice. It will install packages guessing them by the name of the command to run. – B M Oct 04 '19 at 13:22
  • Sorry but I need a snippet to better understand this. So what to write inside `"scripts"` section? Something like `"test": "npx what?` – caneta Oct 04 '19 at 13:28
  • The probably simplest solution, no `npx` needed: `"scripts": { "start" : "node test.js && node start-app.js" }` while in `test.js`: `if (! fs.existsSync('./node_modules')) throw new Error('node_modules not found...');`. Personally I think that running an `npm install` should be solved elsewhere, e. g. in a CI/CD pipeline, but technically this should work. – B M Oct 04 '19 at 16:51
  • Thank you B M, that is exactly what I was searching for! – caneta Oct 07 '19 at 07:56
0

With this script I have run yarn install in subfolder app of my project dir (if node_modules not exist)

const fs = require('fs');
const path = require('path');
const spawn = require('cross-spawn');

if (!fs.existsSync(path.resolve(__dirname, '../app/node_modules'))) {
  
  const result = spawn.sync(
    'yarn',
    ['--cwd', path.resolve(__dirname, '../app'), 'install'],
    {
      stdio: 'inherit'
    }
  );
  console.log(result);
}
sytolk
  • 7,223
  • 3
  • 25
  • 38