Skip to content
82 changes: 82 additions & 0 deletions docs/1 - Getting Started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Getting Started

Vite is designed to work out of the box with zero configuration. Simply run `vite run <script>` to execute any script defined in your `package.json` file.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need some intro to explain what it is, what problem it solves, and what it is similar to.


For example, if you have the following script defined in your `package.json`:

```jsonc
// package.json
{
"scripts": {
"lint": "vite lint"
}
}
```

The first time you run `vite run lint`, Vite Task will execute it just like `npm run lint`:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a info box:

What's the difference between vite run lint and vite lint?

  • vite run lint is invoking the Vite task runner. It runs the lint script defined under scripts in package.json.
  • vite lint is invoking Vite's lint command that performs the actual linting.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Built-in commands like cargo lint or cargo fmt are written without run, so I don’t think they’re a good example for vite run.

More abstractly, how about using an example like vite run hello with "hello": "echo hello" instead?

```
$ vite run lint

> vite lint

Found 0 warnings and 0 errors.
✓ Finished in 103ms on 3192 files with 88 rules using 10 threads.
```

If you run it again immediately, Vite Task will detect that nothing has changed and replay the cached output instantly without re-running the script:

```
$ vite run lint

> vite lint (cache hit, replaying)

Found 0 warnings and 0 errors.
✓ Finished in 103ms on 3192 files with 88 rules using 10 threads.
```

If you modify a source file and run it again, Vite Task will tell you why the cache was missed and re-execute the script:

```
$ echo "debugger;" > src/index.js && vite run lint

> vite lint (cache miss, because the content of src/index.js changed)

⚠ eslint(no-debugger): `debugger` statement is not allowed
╭─[src/index.js:1:1]
1 │ debugger;
· ─────────
╰────
help: Remove the debugger statement

Found 1 warning and 0 errors.
✓ Finished in 114ms on 3192 files with 88 rules using 10 threads.
```

## Running Tasks

### Single Package

Run a task in the current package:

```bash
vite run <task_name>
```

This executes the task defined in `vite-task.json` or `package.json` in the current directory.

### Monorepo

Target a specific package:

```bash
vite run <package_name>#<task_name>
```

Run a task across all packages:

```bash
vite run -r <task_name>
```

The `-r` (recursive) flag executes the task in all packages in topological order based on dependencies. This means if package A depends on package B, the task in B will run before the task in A.
93 changes: 93 additions & 0 deletions docs/2 - Defining Tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Defining Tasks

There are two ways to define tasks in Vite Task:

- `scripts` in `package.json`: Any script you define there can be run with `vite run <script-name>`, just like `npm run <script-name>`.
- `vite-task.json`: You can also define tasks in a dedicated `vite-task.json` file.

## `vite-task.json`

The `vite-task.json` file lets you define tasks with more options than `package.json` scripts. It should be placed in the root of any package alongside `package.json` to define tasks for that package.

Here is an example of a `vite-task.json` file:

```jsonc
{
"tasks": {
"build": {
"command": "webpack",
"envs": ["NODE_ENV"]
},
"test": {
"command": "vite lint",
"cwd": "./src"
}
}
}
```

Configurable fields for each task:

- `command` (string): The command to execute for the task.
- `cwd` (string, optional): The working directory to run the command in. Defaults to the directory containing the `vite-task.json` file.
- `dependsOn` (array of strings, optional): A list of other tasks that this task depends on. See [Task Orchestration](3%20-%20Task%20Orchestration.md) for details.
- `cache`, `envs`, `passthroughEnvs`, `inputs`, `outputs`: see [Configuring Cache](4%20-%20Configuring%20Cache.md) for details.

## Configuration Merging

### Merging with `package.json` Scripts

If you want to keep your existing `package.json` scripts but also need custom configurations for them, you can define a task with the same name in `vite-task.json`. **Vite Task will use the configuration from `vite-task.json` and the command from `package.json`**.

For example, the following combination of `package.json` and `vite-task.json`:

```jsonc
// package.json
{
"scripts": {
"build": "webpack",
}
}
// vite-task.json
{
"tasks": {
"build": {
"envs": ["NODE_ENV"]
}
}
}
```

is equivalent to:

```jsonc
// vite-task.json
{
"tasks": {
"build": {
"command": "webpack",
"envs": ["NODE_ENV"]
}
}
}
```

> If a script in `package.json` and a `command` in `vite-task.json` have the same name, Vite Task will report the conflict and abort.

### Merging with `defaults` in `vite-task.json`

You can provide default configurations by defining `defaults` in `vite-task.json` at the root of the workspace. **Each configuration defined in `defaults` will be applied to all tasks in the workspace with the same name**, unless a task explicitly overrides it.

```jsonc
// vite-task.json
{
"defaults": {
"build": {
// Disable caching for all tasks named "build"
"cache": false
}
}
}
```

> The `defaults` field is only allowed in the root `vite-task.json` file. Vite Task will report an error and abort if it finds one elsewhere.
178 changes: 178 additions & 0 deletions docs/3 - Task Orchestration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Task Orchestration

## Composing Tasks Inside Scripts

Vite Task lets you compose tasks with bash-like syntax inside your scripts defined in `package.json` or `vite-task.json`.

### Multi-step Tasks

You may already use `&&` in your scripts to run multiple commands in sequence. Vite Task recognizes this pattern and caches each step individually.

For example:

```jsonc
// package.json
{
"name": "app",
"scripts": {
"build": "vite build && vite preview"
}
}
```

Vite Task will show `vite build` and `vite preview` as individual commands with their own cache status under the `build` task.

<table>
<tbody>
<tr valign="top" align="left">
<td>
<ul>
<li><code>app#build</code>
<ul>
<li><code>vite build</code></li>
<li><code>vite preview</code></li>
<ul>
</li>
</ul>
</td>
<td>
<pre>
$ vite build

<small>(cache hit, replaying)</small><br />
VITE+ v1.0.0 building for production
transforming...
✓ 32 modules transformed...
rendering chunks...
computing gzip size...
dist/index.html 0.46 kB | gzip: 0.30 kB
dist/assets/react-CHdo91hT.svg 4.13 kB | gzip: 2.05 kB
dist/assets/index-D8b4DHJx.css 1.39 kB | gzip: 0.71 kB
dist/assets/index-CAl1KfkQ.js188.06 kB | gzip: 59.21 kB
✓ built in 308ms
</pre>

</td>
</tr>

</tbody>
</table>

### Nested Tasks

Vite Task recursively expands `vite run ...` in scripts to run nested tasks directly instead of spawning a new subprocess. This gives you a cleaner overview of all executions and avoids unnecessary overhead.

```jsonc
// package.json
{
"name": "monorepoRoot",
"scripts": {
"ready": "vite run format && vite run -r build",
"format": "dprint fmt && vite fmt"
}
}
```

Vite Task will show:

<table>
<tbody>
<tr valign="top" align="left">
<td>
<ul>
<li><code>monorepoRoot#ready</code>
<ul>
<li><code>vite run format</code>
<ul>
<li><code>dprint fmt</code></li>
<li><code>vite fmt</code></li>
</ul>
</li>
<li><code>vite run -r build</code>
<ul>
<li><code>pkg1#build</code></li>
<li><code>pkg2#build</code></li>
<li><code>pkg3#build</code></li>
</li>
</ul>
</td>
<td>
<pre>
$ dprint fmt

<small>(cache hit, replaying)</small><br />
Formatted 3 files.
</pre>

</td>
</tr>

</tbody>
</table>

### Supported Syntaxes

For multi-step and nested tasks to be recognized correctly, Vite Task supports a subset of bash syntax:

- Simple commands: `program arg1 arg2 ...`
- Commands prefixed with environment variables: `VAR=value program arg1 arg2`
- Referencing variables with `$`: `program $FOO a${BAR}b ${BAZ:42}`
- Sequential commands: `program1 && VAR=value program2 $FOO && ...`

If a script contains syntax beyond these, Vite Task falls back to normal script execution with system shells. For example, the following script will not be split into multiple steps because of the `if` statement:

```jsonc
{
"scripts": {
"complex": "if [ -f file.txt ]; then vite lint && vite build ; fi"
}
}
```

Even if a script is not expanded, Vite Task can still **cache the entire script execution as a single unit**.

If you put a `vite run ...` command inside a script with unsupported syntax, like the example below, the **inner `vite run ...` will fail** at execution time, because caching both `build` tasks and `complex` as a single unit is not currently supported.

```bash
{
"scripts": {
"complex": "if [ -f file.txt ]; then vite run -r build; fi"
}
}
```

To make it work, you can disable caching for the outer task by adding `"cache": false` in `vite-task.json`:

```jsonc
/// vite-task.json
{
"tasks": {
"complex": {
"cache": false,
"command": "if [ -f file.txt ]; then vite run -r build; fi"
}
}
}
```

## Task Dependencies

Task dependencies can be defined in `vite-task.json` file. You can specify which tasks need to be executed before a particular task runs:

```jsonc
{
"tasks": {
"build": {
"command": "vite build",
"dependsOn": ["lint", "ui#test", "^build"]
},
"lint": {
"command": "vite lint"
}
}
}
```

- `lint` refers to the `lint` task in the same package.
- `ui#test` refers to the `test` task in the `ui` package.
- `^build` refers to all the tasks named `build` in the dependencies of the current package.
Loading