bkennedy
bkennedy

Reputation: 403

Executing a file too many times?

EDIT: I still have a bug where if I use the command watchit by itself without filtering in an argument I get an endless loop of processes opening without being killed. I think this could be because of the way I set up the binary for watchit to run index.js while also inside of the the watch() I set the file name to index.js by default if none is provided

So I was trying to create a program similar to nodemon where it can continuously watch your the program for changes and additions/deletions of files.

I am using 2 libraries I installed via npm, chokidar for the actual watching of the program, then I used caporal to create a CLI. I am also using lodash.debounce as well as chalk. Chalk is simply just to change the color of the output to make it look a little cleaner

Inside the folder I have index.js, package.json, package-lock.json, node modules folder, then a test.js which I used to just test the program with a simple console.log();

inside package.json I have the bin set as:

"bin": {
    "watchit": "index.js"
  }

index.js

#!/usr/bin/env node
const debounce = require('lodash.debounce');
const chokidar = require('chokidar');
const prog = require('caporal');
const chalk = require('chalk');
const fs = require('fs');
const { spawn } = require('child_process');

prog
  .version('0.0.1')
  .argument('[filename]', 'Name of a file to execute')
  .action(async ({ filename }) => {
    const name = filename || 'index.js';

    try {
      await fs.promises.access(name);
    } catch (err) {
      throw new Error(`Could not find the file: ${name}`);
    }
    let pid;
    const start = debounce(() => {
      if (pid) {
        console.log(chalk.red('------- Ending Process -------'));
        pid.kill();
      }
      console.log(chalk.green('------- Starting Process -------'));
      pid = spawn('node', [name], { stdio: 'inherit' });
    }, 100);

    chokidar
      .watch('.')
      .on('add', start)
      .on('change', start)
      .on('unlink', start);
  });

prog.parse(process.argv);

test.js

console.log('how many times do i run this');

from terminal

$ watchit test.js
------- Starting Process -------
how many times do i run this
------- Ending Process -------
------- Starting Process -------
how many times do i run this
------- Ending Process -------
------- Starting Process -------
how many times do i run this

I am clearly creating a new process and running the program more than I should be since there are no tracked changes when the previous output was shown. That was from a single execution of test.js without ever editing it.

Also when I simply run the command watchit from the directory I have this project on my computer, I get some of the above output then a large error about an unhandled promise rejection warning: "UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 27)"

Can anyone share some insight on WHY it's being ran too many times. Is the debounce timer just too low or is it something bigger than that?

---edit--- after adding event into the start function and console.log(event) after I console.log(-----start process-----) I receive

------- Starting Process -------
.git/packed-refs
how many times do i run this
------- Ending Process -------
------- Starting Process -------
node_modules/winston/package.json
how many times do i run this
------- Ending Process -------
------- Starting Process -------
node_modules/winston/node_modules/colors/lib/system/supports-colors.js
how many times do i run this

after ignoring .git and node_modules To ignore the files/folders I changed passed in the options obj:

chokidar
      .watch('.', {
        ignored: '*.git',
        ignored: 'node_modules'
      })
      .on('add', start)
      .on('change', start)
      .on('unlink', start);
  });

$ watchit test.js
------- Starting Process -------
.git/logs/HEAD
how many times do i run this
------- Ending Process -------
------- Starting Process -------
.git/logs/refs/remotes/origin/HEAD
how many times do i run this

Upvotes: 2

Views: 679

Answers (2)

Pedro Mutter
Pedro Mutter

Reputation: 1224

The ignored option on the watch function is wrong:

chokidar
      .watch('.', {
        ignored: '*.git',
        ignored: 'node_modules'
      })

You can't repeat a property in a Javascript object. As I saw on chokidar docs, you need to pass a regex to the ignored property. Try to change your code to something like this:

chokidar
      .watch('.', {
        ignored: /\.git.|node_modules/,
      })

Eventually, you will need to ignore more files, but you can offer an option on your library to the user to pass the files or directory that he wants to ignore.

Upvotes: 3

Zeal
Zeal

Reputation: 464

By using the asterisk(*) you are ignoring files that end in .git, you want to ignore files in the folder called .git, so remove the asterisk.

Upvotes: 1

Related Questions