DEV Community

Ramu Narasinga
Ramu Narasinga

Posted on • Edited on • Originally published at thinkthroo.com

cac — Command And Conquer, a JavaScript library for building CLI apps.

In this article, we will review cac — command and conquer, a JavaScript library for building cli apps.

  1. What is cac package?

  2. cac usage in Tsup.

What is cac package?

Command and conquer is a JavaScript library for building cli apps.

Features

  • Super light-weight: No dependency, just a single file.

  • Easy to learn. There’re only 4 APIs you need to learn for building simple CLIs: cli.option cli.version cli.help cli.parse.

  • Yet so powerful. Enable features like default command, git-like subcommands, validation for required arguments and options, variadic arguments, dot-nested options, automated help message generation and so on.

  • Developer friendly. Written in TypeScript.

learn more about cac package in the documentation.

Usage

Simple Parsing

Use CAC as simple argument parser:

// examples/basic-usage.js
const cli = require('cac')()

cli.option('--type <type>', 'Choose a project type', {
  default: 'node',
})

const parsed = cli.parse()

console.log(JSON.stringify(parsed, null, 2))
Enter fullscreen mode Exit fullscreen mode

This example is picked from documentation.

cac usage in Tsup

  1. In a file named cli-main.ts in Tsup source code, cac is imported as shown below:
import { cac } from 'cac'
Enter fullscreen mode Exit fullscreen mode

2. At line 12 in cli-main.ts, cac is initialised as shown below:

 const cli = cac('tsup')
Enter fullscreen mode Exit fullscreen mode

3. From line 18 to 102 options are configured. As you can see, there are lot of options available in this Tsup library.

 .option('--entry.* <file>', 'Use a key-value pair as entry files')
    .option('-d, --out-dir <dir>', 'Output directory', { default: 'dist' })
    .option('--format <format>', 'Bundle format, "cjs", "iife", "esm"', {
      default: 'cjs',
    })
    .option('--minify [terser]', 'Minify bundle')
    .option('--minify-whitespace', 'Minify whitespace')
    .option('--minify-identifiers', 'Minify identifiers')
    .option('--minify-syntax', 'Minify syntax')
    .option(
      '--keep-names',
      'Keep original function and class names in minified code',
    )
Enter fullscreen mode Exit fullscreen mode

4. Below is the command configuration:

  .command('[...files]', 'Bundle files', {
      ignoreOptionDefaultValue: true,
    })
Enter fullscreen mode Exit fullscreen mode

5. In the actions, all the arguments that you have passed are accessible via flags variable. options is updated with these flags as shown below

  .action(async (files: string[], flags) => {
      const { build } = await import('.')
      Object.assign(options, {
        ...flags,
      })
Enter fullscreen mode Exit fullscreen mode

Most importantly, build function is called as shown below at line 154.

      }
      await build(options)
    })
Enter fullscreen mode Exit fullscreen mode

About me

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

Build Shadcn CLI from scratch.

References:

  1. https://github.com/egoist/tsup/blob/main/src/cli-main.ts#L1

  2. https://www.npmjs.com/package/cac

  3. https://github.com/egoist/tsup/blob/main/src/cli-main.ts#L12

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.