Handling Command-line Arguments in NPM Scripts
Tags: showdev, webdev, javascript, node
Published: 2020-12-09 02:00:55

---
title: Handling Command-line Arguments in NPM Scripts
published: true
description: Proper CLI arguments handling can turn your NPM scripts more succinct and powerfull
tags: #showdev #webdev #javascript #node
cover_image: https://images.unsplash.com/photo-1488590528505-98d2b5aba04b?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80
---

## Custom Arguments

Lets imagine that you have a NPM script to lint your application. Something like that:

```json
"scripts": {
  "lint": "eslint './src/**/*.{js,ts,tsx}'"
}
```

Then you decide to add a lint --fix in quiet mode because sometimes you want the linter to fix the errors quietly for you. Then you add another script:

```json
"scripts": {
  "lint": "eslint './src/**/*.{js,ts,tsx}'",
  "lint:fix": "eslint './src/**/*.{js,ts,tsx}' --quiet --fix"
}
```

Your `lint:fix` is basically your `lint` script with two new params. So, you can rewrite it to pass the params directly to the `lint` command instead, without repeat it:

```json
"scripts": {
  "lint": "eslint './src/**/*.{js,ts,tsx}'",
  "lint:fix": "npm run lint -- --quiet --fix"
}
```

This approach is more succinct and scalable. If you change your `lint` command, all the variations will inherit the modifications. Is also easier to read and quickly understand.

The `--` notation tells your script to pass the parameters to the current command invoked by NPM. From the NPM docs: "NPM will pass all the arguments after the `--` directly to your script". This feature is available on NPM >=2.0.0  | [See the Docs](https://docs.npmjs.com/cli/v6/commands/npm-run-script). You can pass parameters to any command.

## Named Parameters

From NPM docs: "Any environment variables that start with npm_config_ will be interpreted as a configuration parameter | [See the Docs](https://docs.npmjs.com/cli/v6/using-npm/config). That said, you can use the `npm_config_` variable to pass named parameters to your NPM scripts executions.

Lets imagine that you have a `serve` script that can serve your application in 4 modes: `development`, `staging`, `test` and `production` based on your NODE_ENV. So, you could have the following NPM scripts:

```json
"scripts": {
  "serve": "nodemon index.js",
  "serve:dev": "NODE_ENV=development npm run serve",
  "serve:staging": "NODE_ENV=staging npm run serve",
  "serve:test": "NODE_ENV=test npm run serve",
  "serve:prod": "NODE_ENV=production npm run serve"
}
```

Cool, mission accomplished: you can serve your application based on your `stage`, that is also very useful. But we can refactor this code to use only one script, and pass our stage as an argument using the `npm_config_` variable like that:

```json
"scripts": {
  "serve": "NODE_ENV=$npm_config_stage nodemon index.js"
}
```

Now we can pass our `stage` parameter ($npm_config_stage) to modify the NODE_ENV when calling our script like that:

```bash
npm run serve --stage=development
```

You can pass any value to the `stage` parameter, like `npm run serve stage=whatever`. 

Also you could want another name, like `myvar`. So, you would call `npm run serve --myvar=whatever` and your `npm_config_` var would be `$npm_config_myvar`.

## Conclusion

Using Custom Parameters and Named Variables allow your NPM scripts to be smaller, easy understandable and maintainable. Thats all folks :)

Cover Image by Luca Bravo @ Unsplash