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

daizong

v0.28.1

Published

`package.json` script runner for ES Modules

Downloads

417

Readme

daizong 🏃‍♂️

Build Status npm version Node.js Version

package.json script runner for ES Modules. daizong supports the following features out of the box:

  • Run tasks sequentially or in parallel
  • Built-in commands (create directories, delete files and directories)
  • Environment variables
    • Set environment variables for a specific task
    • Set default environment variables for all tasks
    • Define groups of environment variables to be inherited by tasks
  • Define tasks in groups
  • Private tasks
  • Allow continue-on-error
  • before and after fields

Breaking changes

0.20.0+

To avoid ambiguity between task names and arguments passed to tasks. Starting from 0.20.0, a task path has to be separated by - instead of a space:

# Prior to 0.20.0
daizong build windows --args # Don't use, deprecated.

# 0.20.0+
daizong build-windows --args

Usage

  • Install daizong as a dev dependency npm i -D daizong (you can skip this if you want daizong to be installed globally).
  • Create a daizong.config.js to define tasks (see examples below).
  • Use npx daizong <task> --arg1 --arg2 to run a specific task.

If you'd like to run daizong scripts in a shorter way, install daizong globally:

npm i -g daizong

Now instead of npx daizong <task>, you can do:

dz <task>

Note that the global dz command works regardless of whether daizong is installed locally or not.

Examples (daizong vs npm scripts)

package.json:

{
  "scripts": {
    "dev": "tsc -b src -w"
  }
}

daizong:

export default {
  dev: 'tsc -b src -w',
};

Run tasks sequentially

package.json:

{
  "scripts": {
    "dev": "touch a.md && touch b.md"
  }
}

daizong:

export default {
  dev: ['touch a.md', 'touch b.md'],
};

Shorthand and full task definitions

Most tasks you see above are defined as a command string or an array of command strings:

export default {
  dev: ['touch a.md', 'touch b.md'],
};

This is a shorthand task definition. As we're moving to more daizong features, the shorthand task definition is no longer suited and we can switch to its full definition:

export default {
  // Shorthand task definition is either a string or an array of strings.
  task1: 'echo hi',

  // The `task1` above can be rewritten in its full form.
  task1: {
    run: 'echo hi',
    /* More task settings can be used here. */
  },
};

Run tasks in parallel

We'll need 3rd-party libraries like(concurrently) to achieve this in package.json:

{
  "scripts": {
    "dev": "concurrently \"touch a.md\" \"touch b.md\""
  }
}

daizong supports it out of the box:

export default {
  dev: {
    run: ['touch a.md', 'touch b.md'],
    parallel: true,
  },
};

Reuse a task

package.json:

{
  "scripts": {
    "dev": "concurrently \"npm run touch1\" \"npm run touch2\"",
    "touch1": "touch a.md",
    "touch2": "touch b.md"
  }
}

daizong:

export default {
  dev: {
    // Use `#<task_name>` to call an existing task.
    run: ['#touch1', '#touch2'],
    parallel: true,
  },
  touch1: 'touch a.md',
  touch2: 'touch b.md',
};

Built-in commands

run also accepts an object. In that case, you are running daizong's built-in commands:

  • mkdir: string creates a directory and its parents if needed.
  • del: string | string[] deletes files or directories based on the given paths or globs. See del for details.
    • Examples: del: 'dist/*.js.map', del: ['a.txt', 'b.txt'].
  • mkdirDel: string = del <dir> + mkdir <dir>.

Example:

export default {
  prepare: {
    run: {
      mkdir: 'dist',
      del: 'cache',
    },
  },
  dev: {
    run: ['#prepare', 'echo dev'],
  },
  build: {
    run: ['#prepare', 'echo build'],
  },
};

Parallel mode is also supported in built-in commands:

export default {
  prepare: {
    run: {
      mkdir: 'dist',
      del: 'cache',
      parallel: true,
    },
  },
  dev: {
    run: ['#prepare', 'echo dev'],
  },
  build: {
    run: ['#prepare', 'echo build'],
  },
};

Note that when parallel is false (which is the default value), built-in commands are executed sequentially in declaring order:

export default {
  prepare: {
    run: {
      // `del dist` runs first!
      del: 'dist',
      mkdir: 'dist',
    },
  },
};

The above example is equivalent to:

export default {
  prepare: {
    run: {
      // `mkdirDel` deletes and then creates the specified directory.
      mkdirDel: 'dist',
    },
  },
};

You can mix built-in commands and command strings in run:

export default {
  prepare: {
    run: [
      // 1. Run a built-in command.
      {
        mkdir: 'dist',
      },
      // 2. Run a command.
      'echo working...',
      // 3. Run another task.
      '#build',
      // 4. Run another built-in command.
      {
        del: 'tmp',
      },
    ],
  },
};

Groups

Tasks can be grouped to improve readability.

export default {
  build: {
    win: {
      run: 'echo Windows build started',
    },
    linux: {
      run: 'echo Linux build started',
    },
    all: {
      run: '#build-win', '#build-linux',
      parallel: true,
    }
  },
};

To run a specified task in a group, separate its parent groups with -:

dz build-linux
dz build-all

Environment variables

To support all major operating systems, you need to use 3rd-party libraries like(cross-env) to achieve this in package.json scripts.

package.json:

{
  "scripts": {
    "build": "cross-env NODE_ENV=production tsc -b src",
    "dev": "cross-env NODE_ENV=development tsc -b src -w"
  }
}

daizong supports it out of the box:

export default {
  build: {
    run: 'tsc -b src',
    // Use `env` to specify environment variables.
    env: {
      NODE_ENV: 'production',
    },
  },
  dev: {
    run: 'tsc -b src -w',
    env: {
      NODE_ENV: 'development',
    },
  },
};

Default environment variables are also supported. Once configured, they will be automatically applied to all tasks:

export default {
  // "_" is a preserved field for configuration.
  _: {
    defaultEnv: {
      NODE_ENV: 'development',
    },
  },
  dev: {
    // NODE_ENV is 'development'
    run: 'tsc -b src -w',
  },
  build: {
    // NODE_ENV is 'production'
    run: 'tsc -b src',
    env: {
      NODE_ENV: 'production',
    },
  },
};

You can also define groups of environment variables to be inherited by tasks:

export default {
  // "_" is a preserved field for configuration.
  _: {
    defaultEnv: {
      NODE_ENV: 'development',
    },
    // Use `envGroups` to define multiple groups of environment variables.
    envGroups: {
      production: {
        NODE_ENV: 'production',
        compression_level: 'max',
      },
    },
  },
  dev: {
    // NODE_ENV is 'development'
    run: 'tsc -b src -w',
  },
  build-windows: {
    run: 'build',
    env: {
      platform: 'windows'
    },
    // This task has all environment variables defined in "production" group.
    envGroups: ['production'],
  },
  build-macos: {
    run: 'build',
    env: {
      platform: 'macos'
    },
    // This task has all environment variables defined in "production" group.
    envGroups: ['production'],
  },
};

There are predefined env groups:

  • node:dev: NODE_ENV = development
  • node:prod: NODE_ENV = production

Example:

export default {
  build: {
    run: 'tsc -b src',
    envGroups: ['node:dev'],
  },
};

Environment variable definitions precedence

Smaller numbers indicate higher precedence.

  1. Task.env
  2. Task.envGroups (last group overwrites preceding groups like Object.assign)
  3. _.defaultEnv

Continue on error

  • ignoreError available on all tasks, defaults to false. If true, task errors are ignored.
  • continueOnChildError only available on tasks with multiple subtasks. It controls if pending subtasks continue to run when one subtask fails. Defaults to false.

Example:

export default {
  build: {
    run: [
      '#clean',
      // The `tsc` command will always run regardless of the result of clean command.
      'tsc',
    ],
  },
  clean: {
    run: 'echo cleaning...',
    ignoreError: true,
  },
};

Private tasks

Tasks that are not intended to be called from CLI, and can only be called by other tasks.

// You cannot call the "clean" task via `daizong clean`.
// It can only be called by other tasks.
export default {
  // "_" is a preserved field for configuration.
  _: {
    privateTasks: {
      clean: {
        run: 'echo cleaning...',
      },
    },
  },
  build: {
    run: ['#clean', 'tsc'],
  },
};

Before / After

before and after allow you to specify what to run before or after a certain task.

export default {
  build: {
    run: 'echo hi',
    before: ['echo prepare step 1', 'echo prepare step 1'],
    after: '#clean',
  },
  clean: 'rm -rf out',
};

before and after come handy when you need to mix sequential and parallel commands:

export default {
  build: {
    before: '#prepare',
    after: '#clean',
    run: ['cmd1', 'cmd2', '#task1', '#task2'],
    parallel: true,
  },
  prepare: 'echo preparing',
  clean: 'rm -rf out',
};

It runs as:

prepare
  |
cmd1 | cmd2 | #task1 | #task2  <-- parallel
  |
clean
  |

Aliases

Note: To keep things simple, aliases are only allowed in top-level public tasks.

You can set an alias for a public task:

export default {
  build: {
    run: ['#build-windows', '#build-macos', '#build-linux'],
    parallel: true,
    alias: 'b',
  },
};

Now you can start the task by using either dz build or its alias dz b.

Pass arguments to a task

Append the arguments to task path:

export default {
  hello: {
    run: 'echo hello',
  },
};
dz hello i am zzz --arg1 --arg2

Which runs:

echo hello i am zzz --arg1 --arg2

NOTE: Arguments specified before task name are considered daizong arguments, not task arguments. Example:

dz --config <val> build-clean --config <val>

The first --config argument applies to the daizong CLI, while the second --config argument gets passed to the task.

CLI Usage

  Usage
    $ daizong [options] <task-path> [task arguments]

  Options
    --config       Explicitly specify the config file, `--config config.js`
    --verbose      Print verbose information during execution
    --private      Allow private tasks to be called from CLI
    --version, -v  Print version information

  Examples
    $ daizong --verbose test-browser --script-arg1 --script-arg2

Use daizong in a CommonJS module

Use daizong.config.mjs instead of daizong.config.js.