# command

A command in `nr` encapsulates a reference to an external executable (CLI, script, etc), the arguments to pass to it, and configuration related to how to handle its output. Commands may then be invoked by [scripts](/nr/configuration-reference/script.md).

To create a command, use the function at the `command` property of the context object passed to your configuration function:

{% code title="nr.config.js" %}

```typescript
export default ({ command }) => {
    
};
```

{% endcode %}

## `command`

This function accepts the following parameters:

### `name: string`

Human friendly name for the command. This will be used for error-reporting and can be used to reference the command in scripts.

### `args:` [`CommandArguments`](https://github.com/darkobits/nr/blob/master/src/etc/types/CommandArguments.ts)

Array containing the executable/file to run and any arguments to pass to it. This array may take one of four forms, described below.

* `[executable]` of type `[string]`
* `[executable, positionals]` of type `[string, Array<string>]`
* `[executable, flags]` of type `[string, Record<string, any>]`
* `[executable, positionals, flags]` of type `[string, Array<string>, Record<string, any>]`

**Example:**

{% code title="nr.config.js" %}

```typescript
export default ({ command }) => {
  // [executable] form:
  command('unit-test', ['jest']);
  
  // [executable, positionals] form:
  command('lint', ['eslint', ['src']]);
  
  // [executable, flags] form:
  command('type-check', ['tsc', { noEmit: true }], {
    // See "Argument Casing" below.
    preserveArgumentCasing: true
  });
  
  // [executable, positionals, flags] form:
  command('compile', ['babel', ['src'], { outDir: 'dist' }]);
};
```

{% endcode %}

This approach may seem verbose at first, but compared to a single, raw string it separates the parts of a command invocation into discreet values that enable re-use:

{% code title="nr.config.js" %}

```typescript
export default ({ command }) => {
  // This list may be used to configure other commands as well.
  const extensions = ['.ts', '.tsx', '.js', '.jsx'];

  const commonBabelFlags = {
    extensions: extensions.join(','),
    outDir: 'dist',
    copyFiles: true,
    sourceMaps: true
    deleteDirOnStart: true
  };
  
  command('compile', ['babel', ['src'], commonBabelFlags]);
  
  command('compile-watch', ['babel', ['src'], {
    ...commonBabelFlags,
    watch: true
  }]);
};
```

{% endcode %}

{% hint style="warning" %}
Commands are **not** executed in a shell environment where you can use constructs like `&&`, `||`, or`$?`. Rather, a command should be shell-agnostic and point to a single executable file that will be invoked **without an interpreter** like `cmd.exe` or `/bin/bash`.
{% endhint %}

### `options?:` [`CommandOptions`](https://github.com/darkobits/nr/blob/master/src/etc/types/CommandOptions.ts)

Commands may be further configured by passing an optional options object as the third parameter to `command`. Its properties are detailed below.

#### `prefix?: (chalk: Chalk) => string`

Function that will be passed a `chalk` instance and should return a string. This string will be used to prefix each line of output from the command.

This feature can be useful in cases where scripts run multiple commands in parallel or when a CLIs output may not make it obvious what program the output is coming from.

**Example:**

In this example, let's add a prefix to our Babel command.

{% code title="nr.config.js" %}

```typescript
export default ({ command }) => {
  command('compile', ['babel', ['src'], { outDir: 'dist' }], {
    prefix: chalk => chalk.bgYellow.black('Babel')
  })
};
```

{% endcode %}

#### `execaOptions?:` [`execa.Options`](https://github.com/sindresorhus/execa/blob/main/index.d.ts#L249-L254)

`nr` executes commands using `execa`. Here, you may provide any option accepted by `execa` to further fine-tune how the command is executed.

**Example:**

{% code title="nr.config.js" %}

```typescript
export default ({ command }) => {
  command('compile', ['babel', ['src'], { outDir: 'dist' }], {
    execaOptions: {
      // Commands will inherit process.env, but additional variables can
      // be set here as well.
      env: {
        RAINBOWS: true,
        UNICORNS: true
      }
    }
  })
};
```

{% endcode %}

#### **`preserveArgumentCasing?: boolean`**

**Default:** `false`

Idiomatic JavaScript uses camel-case for object keys while the vast majority of CLIs accept named arguments in kebab-case. For this reason, `nr` automatically converts named arguments to kebab-case for you.

However, some CLIs (TypeScript, for example) expect named arguments to be in camel-case. To account for this, this option may be set to `true` to bypass automatic conversion of named arguments to kebab-case.

**Example:**

{% code title="nr.config.js" %}

```typescript
export default ({ command }) => {
  command('tsc', ['tsc', { noEmit: true }], {
    preserveArgumentCasing: true
  })
};
```

{% endcode %}

<table><thead><tr><th width="179">Return Type</th><th>Description</th></tr></thead><tbody><tr><td><a href="https://github.com/darkobits/nr/blob/master/src/etc/types/CommandThunk.ts"><code>CommandThunk</code></a></td><td>Value that may be provided to <code>script</code> to run the command.</td></tr></tbody></table>

When `command` is called, it creates a `CommandThunk`, a function that can be invoked to run the command. This function is added to a registry using the command's `name`, and then it is returned. There are two ways to reference a command in a script:

1. Use the `CommandThunk` directly in a script definition.
2. Use a string in the form `cmd:name` to instruct `nr` to look-up the command in the registry.

## `command.node`

This variant of `command` is useful for commands where the executable is the `node` binary itself.

It has the same signature as `command`. It can be used to execute a Node script (regardless of whether the executable flag has been set on it) using the current version of Node. This variant uses [`execaNode`](https://github.com/sindresorhus/execa#execanodescriptpath-arguments-options) to execute the script.

**Example:**

{% code title="nr.config.js" %}

```typescript
export default ({ command }) => {
  // Equivalent to "node ./server.js" with some additional quality of
  // life enhancements provided by execaNode.
  command.node('server', ['./server.js'])
};
```

{% endcode %}

## `command.babel`

This variant of `command` is useful for executing commands with `babel-node`.

It has the same signature as `command`. It can be used to execute a Node script (regardless of whether the executable flag has been set on it) using the `babel-node` CLI. This variant also uses [`execaNode`](https://github.com/sindresorhus/execa#execanodescriptpath-arguments-options) to execute the script.

**Example:**

{% code title="nr.config.js" %}

```typescript
export default ({ command }) => {
  // Equivalent to "babel-node --extensions=.ts,.tsx,.js,.jsx ./server.js"
  // with some additional quality of life enhancements provided by execaNode.
  command.babel('server', ['./server.js'])
};
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://darkobits.gitbook.io/nr/configuration-reference/command.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
