Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building great CLIs with Node.js

Building great CLIs with Node.js

Presentation given at Valencia.js ( https://www.meetup.com/ValenciaJS/events/258572974/ )
Version without animations (PDF doesn't like animated GIFs 😔)

Wojtek Siudzinski

February 28, 2019
Tweet

More Decks by Wojtek Siudzinski

Other Decks in Programming

Transcript

  1. Valencia.js 28 Feb 2019 2 $ whoami Wojtek `suda` Siudzinski

    Senior Software Engineer @ Particle Founder @ Appsome! Maintained Particle’s dev tools Developed that-guy https://www.particle.io/developer-tools https://github.com/suda/that-guy
  2. Valencia.js 28 Feb 2019 3 12 Factor CLI Apps 1

    2 3 A methodology proposed by Jeff Dickey from Heroku. It derives from their 12 Factor App methodology for server-side apps aiming to make them easy to maintain and for the CLI apps it strives to provide your users with a great CLI UX. https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46
  3. Valencia.js 28 Feb 2019 4 Provide good help documentation Both

    online and in-CLI help are essential. Ideally the user should be able to learn how use the app without leaving the terminal. Many frameworks will generate help automatically.
  4. Valencia.js 28 Feb 2019 6 vorpal .command('backfill <exchange> <fsym> <tsym>')

    .description('Gets history data from the exchange for the specified pair') .option( '-d, --days <days>', 'Number of days to back fill. Default: 6' )
  5. Valencia.js 28 Feb 2019 8 ! heroku help create creates

    a new app USAGE $ heroku create [APP] ARGUMENTS APP name of app to create OPTIONS -b, --buildpack=buildpack buildpack url to use -n, --no-remote do not create a git -r, --remote=remote the git remote to -s, --stack=stack the stack to create -t, --team=team team to use --addons=addons comma-delimited list
  6. Valencia.js 28 Feb 2019 9 Use stdout and stderr accordingly

    stdout is for output stderr is for messaging
  7. Valencia.js 28 Feb 2019 12 Prompt where possible Apps who’s

    primary audience are humans (as contrary to other apps) should allow input to provide additional or missing information. You shouldn’t require it though and it should be possible to input the information via arguments.
  8. Valencia.js 28 Feb 2019 13 input = await cli.prompt('your name

    (normal)') input = await cli.prompt('your name (mask)', { type: 'mask' }) input = await cli.prompt('your name (hide)', { type: 'hide' }) input = await cli.prompt('your name (default)’, { default: 'somedefault' })
  9. Valencia.js 28 Feb 2019 15 Be fancy " Use colors,

    emojis, spinners and progress bars to make the UX more clear, highlighting important informations and actions. Not all terminals may support this, therefore respect TERM=dumb and NO_COLOR env variables.
  10. Valencia.js 28 Feb 2019 17 // oclif spinner cli.action.start('running') cli.action.stop()

    // chalk cli.log(`${chalk.red('!')} # Error`) // progress let bar = new ProgressBar('[:bar]', { total: 10 }) bar.tick()
  11. Valencia.js 28 Feb 2019 19 Speed * <100ms: very fast

    * 100ms-500ms: fast enough * 500ms-2s: usable * >2s: sluggish and annoying
  12. Valencia.js 28 Feb 2019 20 ! node --require time-require src/cli.js

    Start time: (2019-02-26 13:13:52 UTC) [treshold=1%] # module time % 1 chalk (node_modules/time-..._modules/chalk/index.js) 10ms ▇ 1% 2 http (http) 8ms ▇ 1% 3 https (https) 16ms ▇▇ 2% 4 ./lib/body (node_modules/node-fetch/lib/body.js) 9ms ▇ 1% 5 node-fetch (node_modules/node-fetch/index.js) 38ms ▇▇▇ 5% 6 ./_enum-keys (node_module...s/modules/_enum-keys.js) 8ms ▇ 1% 7 ./modules/es6.symbol (nod...s/modules/es6.symbol.js) 19ms ▇▇ 3% 8 ./modules/es6.promise (no.../modules/es6.promise.js) 9ms ▇ 1% 9 ./_typed-array (node_modu...modules/_typed-array.js) 11ms ▇ 1% 10 ./modules/es6.typed.int8-...es6.typed.int8-array.js) 12ms ▇ 2% 11 core-js/shim (node_modules/core-js/shim.js) 211ms ▇▇▇▇▇▇▇ 28% 12 babel-polyfill (node_modu...l-polyfill/lib/index.js) 216ms ▇▇▇▇▇▇▇ 29% 13 lodash (node_modules/lodash/lodash.js) 36ms ▇▇▇ 5% 14 ./objects/separator (node...ib/objects/separator.js) 9ms ▇ 1% 15 lodash (node_modules/inqu...modules/lodash/index.js) 20ms ▇▇ 3% 16 ./baseUI (node_modules/inquirer/lib/ui/baseUI.js) 27ms ▇▇ 4% (…) Total require(): 2094ms Total time: 743ms
  13. Valencia.js 28 Feb 2019 23 Configuration Follow XDG-spec when comes

    to storing config. ~/.config/myapp for configs ~/.local/share/myapp for data Also respect the XDG_CONFIG_HOME env variable.
  14. Valencia.js 28 Feb 2019 25 Versioning and updating Allow your

    users to see the version of the CLI with a single command. This becomes very useful when debugging. Check for updates and encourage users to upgrade.
  15. Valencia.js 28 Feb 2019 27 ! node update-notifier.js ╭─────────────────────────────────────╮ │

    │ │ Update available 0.9.2 → 3.0.0 │ │ Run npm i public-ip to update │ │ │ ╰─────────────────────────────────────╯
  16. Valencia.js 28 Feb 2019 29 Platformlessness There are different: *

    operating systems * Node.js versions installed * architectures