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
andafter
fields
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
- 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 daizongNow 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.
package.json
:
{
"scripts": {
"dev": "tsc -b src -w"
}
}
daizong:
export default {
dev: 'tsc -b src -w',
};
package.json
:
{
"scripts": {
"dev": "touch a.md && touch b.md"
}
}
daizong:
export default {
dev: ['touch a.md', 'touch b.md'],
};
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. */ }, };
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,
},
};
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',
};
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']
.
- Examples:
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',
},
],
},
};
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
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'],
},
};
Smaller numbers indicate higher precedence.
Task.env
Task.envGroups
(last group overwrites preceding groups likeObject.assign
)_.defaultEnv
ignoreError
available on all tasks, defaults tofalse
. Iftrue
, 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 tofalse
.
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,
},
};
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
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
|
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
.
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.
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.config.mjs
instead of daizong.config.js
.