npm scripts management using nps and nps-utils
Tags: node, nps, npsutils, javascript
Published: 2020-08-16 00:13:24

- When developing with npm, the amount and content of scripts in `package.json` may increase.
- Also, it may not be multi-platform, such as using commands that are not available in some environments.
- Therefore, I will describe how to manage scripts separately using two libraries, nps and nps-utils.

## preparation
- As an example, we are going to change the following package.json scripts.

```json
{
  "scripts": {
    "dev": "NODE_ENV=development nodemon index.js",
    "test": "NODE_ENV=test jest --coverage",
    "lint": "eslint . --cache"
    "build": "NODE_ENV=production run-s build:{clean,js}",
    "build:clean": "rm -rf ./dist",
    "build:js": "esbuild src/index.js --bundle --outfile=dist/out.js"
  },
  "devDependencies": {
　　................,
    "esbuild": "^0.6.12",
    "nodemon": "^2.0.4",
    "jest": "^26.4.0",
    "eslint": "^7.7.0",
    "npm-run-all": "^4.1.5"
  }
}
```

- This package.json has the following concerns
  - The rm command and environment variable settings are limited to the execution environment.
  - There is a lot of content and volume, and it will become more complex as it increases in the future.

## setting

### install
- Install the following two libraries
  - nps : npm scripts management tool
      - By keeping the details of scripts in a separate file, management and maintenance will be easier.
      - It is highly flexible and extensible because it can be written in js and yaml instead of json.
  - nps-utils : Packaged tools to enhance nps
      - A number of multi-platform libraries are built into the system, making it complete in one.

```bash
npm install --save-dev nps nps-utils
```

### init
- Create a configuration file with the following command.
  - **※This time, we'll create it in js.**

```bash
# The default is package-scripts.js
./node_modules/.bin/nps init

# If you create with yaml.
./node_modules/.bin/nps init --type yml
```

- After creation, the structure is as follows.

```
.
├── package.json
└── package-scripts.js
└── .......
```

### Example of a configuration template
- First, make the following contents of `package-scripts.js `created in the initialization process.

```js
// Multiplatform support(Mac,Windows,Linux)
const {
  series,  // Simplification of continuous execution
  rimraf,  // rm command
  crossEnv  // Environment variable setting
} = require('nps-utils');

module.exports = {
  scripts: {
    dev: {
      default: crossEnv('NODE_ENV=development nodemon index.js')
    },
    test: {
      default: crossEnv('NODE_ENV=test jest --coverage')
    },
    lint: {
      default: 'eslint . --cache'
    },
    build: {
      default: crossEnv(
        `NODE_ENV=production ${series.nps(
          'build.clean',
          'build.js',
        )}`,
      ),
      clean: rimraf('dist'),
      js: 'esbuild src/index.ts --bundle --outfile=dist/out.js',
    }
  }
};
```

- The content of the final `package.json` is as follows.

```json
{
  "scripts": {
    "dev": "nps dev",
    "test": "nps test",
    "lint": "nps lint",
    "build": "nps build"
  },
  "devDependencies": {
　　................,
    "esbuild": "^0.6.12",
    "nodemon": "^2.0.4",
    "jest": "^26.4.0",
    "eslint": "^7.7.0",
    "npm-run-all": "^4.1.5",
    "nps": "^5.10.0",
    "nps-utils": "^1.7.0",
    ..........
  }
}
```

### run
- Each script is executed with the following command.

```bash
# npm run script name

# dev
npm run dev
# test
npm run test
```

## Link
- [nps Github](https://github.com/sezna/nps)
- [nps-utils Github](https://github.com/kentcdodds/nps-utils)