npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

precise-watcher

v2.1.0

Published

Automate tasks on file change, run them in parallel, and forget about tool-specific plugins.

Downloads

12

Readme

Contents

  1. Status
  2. Installation
  3. Usage
    1. Posibilities
    2. Watch files using NPM scripts
      1. Setting options in a configuration file
    3. Watch files using your console
      1. Supported options
    4. Watch files using js
  4. Examples
    1. Run eslint --fix on 1 single file, when it changes
    2. Copy /static content to /public. On development, serve /public; on production, exit
  5. Supported options
  6. Credits
  7. License

Status

Linux & MacOS CI NPM version

Installation

Run npm i precise-watcher or yarn add precise-watcher.

Usage

Using precise-watcher is as simple as adding the following to your package.json and running npm run watch:

{
  "precise-watcher": {
    "src": [{
      "pattern": ["**/*"],
      "on": "change",
      "run": [{
        "cmd": "echo",
        "args": ["<file> changed."]
      }]
    }]
  },
  "scripts": {
    "watch": "precise-watcher"
  },
  "devDependency": {
    "precise-watcher": "^1.0.0"
  }
}

To run it, just modify any file not included in your .gitignore file...

Posibilities

This tool allows you to:

  • Run commands on 1 single file when it changes (by using "<file>" in src.run.args).
  • Call as many commands in parallel or serial as you want.
  • Watch not only for changes but errors, removals, addings, ...
  • Watch multiple sources and run multiple scoped commands.
  • Write complex solutions easily.
  • [From v2.0]: Run all your commands and exit. Useful for production!

Once you see what it does and why you need it, you can use it in any of the following ways:

  1. NPM scripts
  2. CLI
  3. Javascript

Watch files using NPM scripts

Add precise-watcher to your package.json file in the following way:

{
  "precise-watcher": {
    // Your options go here.
  },
  "scripts": {
    // Replace "watch" with whatever you want.
    "watch": "precise-watcher"
  }
}

Then, run the NPM script (npm run watch in this case) and press ctrl + c, as normal, to stop watching files.

Addittionaly, you can remove the options from your package.json file and use a config. file to set your options:

Setting options in a configuration file

Create a config. file called precise-watcher.config.js (for example), and reference it using the --config option in the command you added before.

// precise-watcher.config.js
module.exports = {
  // Your options go here.
}
{
  "scripts": {
    "watch": "precise-watcher --config precise-watcher.config.js"
  }
}

As you can see, you no longer need the precise-watcher property anymore.

Watch files using your console

To start watching file changes:

  1. Create a config file called precise-watcher.config.js, for example.
  2. Run ./node_modules/.bin/precise-watcher --config precise-watcher.config.js.

To stop watching file changes:

  • Press ctrl + c.

Supported options

Below are a list of options that you can use with precise-watcher:

Option | Defaults | Description :------- | :------------ | :---------- --cwd | process.cwd() | Directory for chokidar, config file, and child_process.spawn(). --config | package.json | Path to your config. file, relative to cwd.

Watch files using js

Should be as easy as:

const { start, stop, shutdown } = require('precise-watcher')

// Resolves to an array of chokidar.watch() instances:
start().then(async (watchers) => {
  // To remove some watchers:
  // Resolves to an array of each watcher.close() result.
  const closedWatchers = await stop(watchers)
  // To remove all watchers:
  const allClosedWatchers = await stop()

  // To exit:
  shutdow() // Calls stop() internally.
}) // ...

With async/await:

const { start, stop, shutdown } = require('precise-watcher')

(async () => {
  try {
    const watchers = await start()
    const closedWatchers = await stop(watchers)
    const allClosedWatchers = await stop()

    shutdown()
  } catch (error) {
    // Log error...
  }
})()

Examples

If you need more inspiration, you can check out these examples:

Run eslint --fix on 1 single file, when it changes

  1. Run npm install eslint --save-dev.
  2. Add the following to your package.json:
{
  "precise-watcher": {
    "src": [{
      "pattern": ["**/*.js"],
      "on": "change",
      "run": [{
        "cmd": "echo",
        "args": [
          "Running eslint <file> --fix"
        ],
        "callNext": "parallel"
      }, {
        "cmd": "eslint",
        "args": [
          "<file>",
          "--fix"
        ],
        "callNext": "serial"
      }, {
        "cmd": "echo",
        "args": ["Done"]
      }]
    }]
  },
  "scripts": {
    "watch": "precise-watcher"
  }
}
  1. Run npm run watch.
  2. Modify any .js file.

Copy /static content to /public. On development, serve /public; on production, exit.

  1. Install requirements: Run npm install live-server precise-watcher@^2.0 cpy-cli --save-dev.
  2. Create some files: /static/index.html and /static/img/favicon.svg, for example.
  3. Add the following to precise-watcher.config.js:
const {NODE_ENV} = process.env;
const isProduction = NODE_ENV === 'production';
const isDevelopment = !isProduction;

module.exports = {
    "src": [].concat(isDevelopment ? {
        "pattern": "public",
        "on": "ready",
        "run": [{
            // Start development server.
            "cmd": "live-server",
            "args": ["public"]
        }]
    } : {
        "pattern": "dist",
        // Empty the /dist dir.
        "run": [{
            "cmd": "rm",
            "args": ["dist -R"]
        }, {
            "cmd": "mkdir",
            "args": ["dist"]
        }]
    }).concat({
        "pattern": ["static/**/*.{jpg,jpeg,png,ico,svg,html}"],
        "baseDir": "static",
        "on": (isProduction
            ? null // Run as soon as possible.
            : ["ready", "change"] // Run when chokidar is ready and when it detects a change.
        )
        "run": {
            // Copy your static content (images and HTMLs), one by one.
            "cmd": "cpy",
            "args": `<file> ../${isDevelopment ? "public" : "dist"} --cwd=static --parents`.split(" ")
        }
    })
};
  1. Update your npm scripts (update your package.json):
"scripts": {
    "start": "precise-watcher --config precise-watcher.config.js",
    "dev": "NODE_ENV=development npm run start",
    "prod": "NODE_ENV=production npm run start"
}
  1. Run npm run dev and wait for your browser to start. Then, modify any file (e.g, static/index.html) and your changes should be visible right away.

  2. When you're done, hit ctrl + c and run npm run prod. Your /dist folder will now contain all your final files.

Supported options

{
  /** @type {?object} (Optional) chokidar options that will apply to all sources. Defaults to the following, as of [email protected]: */
  "chokidar": {
    "persistent": true,
    // Concatenated with src.ignoreFrom sources.
    "ignored": [],
    "ignoreInitial": false,
    "followSymlinks": false,
    // Defaults to value passed via --cwd, "cwd" param in src/start.js' main function, or process.cwd()
    "cwd": "",
    "disableGlobbing": false,
    "usePolling": false,
    "useFsEvents": true,
    "alwaysStat": false,
    "depth": undefined,
    "awaitWriteFinish": false,
    "ignorePermissionErrors": false,
    "atomic": true
  },
  /** @type {object|object[]} Source(s) to watch. */
  "src": [{
    /** @type {string|RegExp|string[]|RegExp[]} Pattern(s) to watch. */
    "pattern": [],
    /** @type {?string} (Optional) Set "<file>" replacement relative to this value. Basically: path.relative(baseDir, watchedFile). Useful to convert /some/path/file to /file, for example */
    "baseDir": "",
    /** @type {?string} A path to a .gitignore-like file to ignore sources matched by src.pattern. Relative to cwd. */
    "ignoreFrom": ".gitignore",
    /** @type {object|object[]} An array of commands. */
    "run": [{
      /** @type {?string} The command to run. */
      "cmd": "",
      /**
       * @type {?string[]} List of arguments for cmd.
       *
       * Use "<file>" to replace it with the changed filepath if the event
       * supports it, or set each src.pattern value as default (and call
       * this command in parallel multiple times with each given pattern).
       */
      "args": [],
      /** @type {?string} Any of "serial" or "parallel". Defaults to "serial". */
      "callNext": "serial",
      /**
       * @type {?function} A function triggered before running the command.
       * @return {?boolean} If false is returned, the command won't run.
       */
      beforeRun (cmdInfo, eventInfo) {
        const {
          callNext,
          patterns,
          baseDir,
          commands
        } = this;
        const {
          cmd,
          args: cmdArgs,
          options: cmdOptions
        } = cmdInfo;
        const {
          name: eventName,
          args: eventArgs
        } = eventInfo;
        let keepRunning = true;

        return keepRunning;
      }
    }],
    /** @see https://github.com/paulmillr/chokidar */
    /** @type {?string[]|?string} One or many chokidar events: "add", "unlink", "addDir", "unlinkDir", "error", "ready", "raw". */
    "on": [],
    /** @see https://github.com/paulmillr/chokidar */
    /** @type {?object} Chokidar options that will apply to these sources only. Merged with global "chokidar" options. */
    "chokidar": {}
  }]
}

Credits

Thanks to Chokidar's author and contributors and this project's contributors.

License

This project is MIT Licensed.