# Running Scripts

The primary way you will likely interact with tooling is via package scripts using `nr`. `ts` provides a robust set of default package scripts for most common tasks like building, testing, and releasing, and you are able to add your own (or even overwrite the defaults) in your `nr.config.ts` file.

For a list of all scripts provided by `ts`, make sure you have created an `nr.config.js` file in your project root, then run:

```sh
npx nr --scripts
```

This will print a list of all defined scripts and a brief description of what each script does.

If you prefer to run scripts using `npm run script-name`, you can alias any `nr` script in `package.json` thusly:

{% code title="package.json" %}

```json
{
  "scripts": {
    "script-name": "nr script.name"
  }
}
```

{% endcode %}

The `npx` prefix is not required here because NPM will automatically look for the `nr` executable in your local `node_modules` folder.

This rest of this section will go over the most common scripts used to manage a project. It assumes the user has not installed `nr` globally (not recommended) nor added [`./node_modules/.bin` to their `$PATH`](https://darkobits.gitbook.io/ts/advanced#adding-local-node_modulesbin-to-path), so each example will use the long form notation with `npx`.

## Building <a href="#building" id="building"></a>

The `build` script will lint your project using ESLint and compile it using TypeScript to type-check and emit type declaration files. These two processes are run in parallel.

To execute this script, run:

```
npx nr build
```

To continuously build and type-check the project in watch mode, run:

```
npx nr build.watch
```

## Development <a href="#pre-build-amp-post-build-scripts" id="pre-build-amp-post-build-scripts"></a>

In addition to the `build.watch` script, `ts` also includes a `start` script that will run `vite build --watch` and start `nodemon`. The entry point that `nodemon` uses will be the `main` file declared in `package.json`.

#### Example

Given the following `package.json`, `nodemon` will run `dist/server.js` and restart the process whenever files in the `dist` folder are changed. Meanwhile, Vite will incrementally rebuild the project when source files are changed.

{% code title="package.json" %}

```json
{
  "main": "dist/server.js"
}
```

{% endcode %}

## Pre-Build & Post-Build Scripts <a href="#pre-build-amp-post-build-scripts" id="pre-build-amp-post-build-scripts"></a>

If you define `prebuild` and/or `postbuild` scripts in `nr.config.ts`, `nr` will run them before and after the `build` script. These scripts are **not** run with `build.watch`.

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

```typescript
import { defineConfig } from '@darkobits/nr'
import { defaultPackageScripts } from '@darkobits/ts'

export default defineConfig([
  defaultPackageScripts,
  ({ script, command }) => {
    script('postbuild', [
      // Example: Runs del .cache --force
      command('del', {
        args: ['.cache', { force: true }]
      })
    ], {
      description: 'Runs after the "build" script.'
    })
  })
])
```

{% endcode %}

## Testing <a href="#testing" id="testing"></a>

To run unit tests for your project with Vitest:

```
npx nr test
```

To continuously run tests in watch mode:

```
npx nr test.watch
```

To run unit tests and generate a coverage report:

```
npx nr test.coverage
```

## Linting <a href="#linting" id="linting"></a>

Linting is performed automatically as part of the `build` script, but you can manually lint the project by running:

```
npx nr lint
```

To automatically fix any fixable errors in the project:

```
npx nr lint.fix
```

## Releasing in CI <a href="#releasing-semantic-release" id="releasing-semantic-release"></a>

If you prefer to release your project automatically from a CI environment, `ts` ships with [`semantic-release`](https://github.com/semantic-release/semantic-release) and a configuration preset. To use `semantic-release` with the provided configuration, simply run one of the release scripts.

To release a new verion from CI:

```
npx nr release
```

When using this method, you do not need to create a `release.config.js` file; `semantic-release` will be invoked with the configuration preset for you.

If you prefer or need to configure `semantic-release` manually but would still like to use the configuration preset, you can extend it from your configuration file:

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

```js
module.exports = {
  extends: '@darkobits/semantic-release-config'
}
```

{% endcode %}

{% hint style="warning" %}
When using your own configuration file, invoke `semantic-release` directly rather than using the release script.
{% endhint %}

#### **Publishing Releases to GitHub**

If you need to publish your project to GitHub, you will need to create a [personal access token](https://github.com/settings/tokens) with the `public_repo` scope and then configure a `GH_TOKEN` environment variable in your CI environment with this value. If `GH_TOKEN` is not present, `ts` will omit the GitHub plugin from its `semantic-release` configuration.

#### **Publishing to NPM**

If you need to publish your project to NPM, you will need to create an NPM Access Token (the "Automation" token type is recommended) and then configure an `NPM_TOKEN` environment variable in your CI environment with this value. If `NPM_TOKEN` is not present, `ts` will omit the NPM plugin from its `semantic-release` configuration.

## Releasing Locally <a href="#releasing-standard-version" id="releasing-standard-version"></a>

If you prefer to manage publishing locally, `ts` ships with [`standard-version`](https://github.com/conventional-changelog/standard-version). To generate (or update) your project's `CHANGELOG.md` and bump the project's version in `package.json`:

```
npx nr bump
```

To create a beta release:

```
npx nr bump.beta
```

For your project's [first release](https://github.com/conventional-changelog/standard-version#first-release), you may not want to bump the version at all, and only generate a change-log and release commit:

```
npx nr bump.first
```

#### **Pre-Bump & Post-Bump Scripts**

If you define `prebump` and/or `postbump` scripts in `nr.config.ts`, `nr` will run them before and after any `bump*` scripts.

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

```typescript
import { defineConfig } from '@darkobits/nr'
import { defaultPackageScripts } from '@darkobits/ts'

export default defaultPackageScripts([
  defaultPackageScripts,
  ({ script, command }) => {
    script('postbump', [
      // Runs del .cache --force
      command('del', {
        args: ['.cache', { force: true }]
      })
    ], {
      description: 'Runs after the "bump" script.'
    })
  })
])
```

{% endcode %}

## NPM Lifecycles <a href="#npm-lifecycles" id="npm-lifecycles"></a>

`ts` also provides a `prepare` script that will build and lint the project and run unit tests. The `prepare` lifecycle script is designed to ensure that when a developer clones a repository for the first time and runs `npm install`, they can be confident that the project builds and that its tests are passing. This gives the developer confidence that the project's tooling is configured correctly and that its source code is in a good, working state.

To have NPM run this script as part of the "prepare" lifecycle, you *must* create an alias in `package.json`:

{% code title="package.json" %}

```json
{
  "scripts": {
    "prepare": "nr prepare"
  }
}
```

{% endcode %}
