|
| 1 | +--- |
| 2 | +layout: blog |
| 3 | +title: yargs 16 Released |
| 4 | +excerpt: yargs 16 released |
| 5 | +--- |
| 6 | + |
| 7 | +{::options parse_block_html="true" /} |
| 8 | +<div class="page-content align-items"> |
| 9 | +<div class="page-box-full left"> |
| 10 | +# yargs 16 Released |
| 11 | + |
| 12 | +About 5 months ago, [Mael Le Guen](https://github.com/mleguen) proposed converting the yargs codebase to TypeScript. I was a bit skeptical at first... |
| 13 | + |
| 14 | +I saw benefits TypeScript could offer the project: |
| 15 | + |
| 16 | +* yargs has a large API surface with many implicit contracts, e.g., how calling a method like `.option()` eventually feeds into [yargs-parser](https://github.com/yargs/yargs-parser). |
| 17 | +* some parts of the codebase are quite messy, and type safety would give additional confidence to future refactors. |
| 18 | + |
| 19 | +A few concerns were motivating my skepticism: |
| 20 | + |
| 21 | +* I knew this would be a large project, and was worried we'd deliver something that was only _halfway there._ |
| 22 | +* The existing [@types/yargs](https://www.npmjs.com/package/@types/yargs) TypeScript definitions have **>12,000,000** downloads/week, I didn't want to disrupt this community. |
| 23 | +* I didn't want to significantly bloat the size of yargs. |
| 24 | + |
| 25 | +Thanks to the hard work of Mael, who lead the conversion project (_with help from others like [QmarkC](https://github.com/QmarkC)_), and thanks to a few compromises, I'm happy to say that the TypeScript conversion project was successful. |
| 26 | + |
| 27 | +Beyond the benefits I expected (_ease of refactoring, and explicit interfaces_), TypeScript made two additional improvements to yargs easier, which I'm excited to announce in **v16**: |
| 28 | + |
| 29 | +* yargs now supports both ESM and CommonJS (_you can even use [yargs directly in the browser](https://jsfiddle.net/bencoe/m9fv2oet/), without bundling_). |
| 30 | +* yargs now has experimental support for Deno. |
| 31 | + |
| 32 | +## yargs is now written in TypeScript, but... |
| 33 | + |
| 34 | +As the TypeScript project approached completion, it became clear that it would be significant amount of work to match the type definitions exposed in **@types/yargs**... |
| 35 | + |
| 36 | +We've made the decision to not ship yargs with [Type declaration files](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html). As a TypeScript user of yargs, usage [instructions](https://github.com/yargs/yargs/blob/master/docs/typescript.md) shouldn't change, and you will still `npm i @types/yargs --save-dev`. |
| 37 | + |
| 38 | +Developers working on the yargs project now benefit from type safety, and the project benefits from the build steps we've introduced (_more on this in a moment_), but the existing TypeScript community should be able to upgrade with minimal disruption. |
| 39 | + |
| 40 | +## ESM and CJS support |
| 41 | + |
| 42 | +**yargs@v16** is **~26%** larger than past version of yargs. This is because, using Node.js' [conditional exports](https://nodejs.org/api/esm.html#esm_conditional_exports), yargs now provides an interface for both CommonJS and ESM: |
| 43 | + |
| 44 | +**CommonJS example:** |
| 45 | + |
| 46 | +```js |
| 47 | +const {argv} = require('yargs') |
| 48 | + |
| 49 | +if (argv.ships > 3 && argv.distance < 53.5) { |
| 50 | + console.log('Plunder more riffiwobbles!') |
| 51 | +} else { |
| 52 | + console.log('Retreat from the xupptumblers!') |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +**ESM example:** |
| 57 | + |
| 58 | +```js |
| 59 | +import yargs from 'yargs' |
| 60 | +import { hideBin } from 'yargs/helpers' |
| 61 | + |
| 62 | +yargs(hideBin(process.argv)) |
| 63 | + .command('curl <url>', 'fetch the contents of the URL', () => {}, (argv) => { |
| 64 | + console.info(argv) |
| 65 | + }) |
| 66 | + .demandCommand(1) |
| 67 | + .argv |
| 68 | +``` |
| 69 | + |
| 70 | +To facilitate this, we target ESM with the TypeScript compilation step, then have an additional compile step with [Rollup](https://github.com/rollup/rollup) which creates a CommonJS bundle of the library. |
| 71 | + |
| 72 | +It's my hope that taking this approach of shipping a dual mode library will help smooth the process for folks experimenting with ESM (_and that the additional bloat in the library will be forgiven 😊_) |
| 73 | + |
| 74 | +## Deno Support |
| 75 | + |
| 76 | +> Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust. |
| 77 | +
|
| 78 | +Taking on the work to make yargs and its dependencies fully support ESM, combined with converting the codebase to TypeScript, made it a short addition step towards supporting the Deno runtime. |
| 79 | + |
| 80 | +**Deno example:** |
| 81 | + |
| 82 | +```typescript |
| 83 | +import yargs from 'https://deno.land/x/yargs/deno.ts' |
| 84 | +import { Arguments, YargsType } from 'https://deno.land/x/yargs/types.ts' |
| 85 | + |
| 86 | +yargs() |
| 87 | + .command('download <files...>', 'download a list of files', (yargs: YargsType) => { |
| 88 | + return yargs.positional('files', { |
| 89 | + describe: 'a list of files to do something with' |
| 90 | + }) |
| 91 | + }, (argv: Arguments) => { |
| 92 | + console.info(argv) |
| 93 | + }) |
| 94 | + .strictCommands() |
| 95 | + .demandCommand(1) |
| 96 | + .parse(Deno.args) |
| 97 | +``` |
| 98 | + |
| 99 | +I am a Deno novice, and would characterize yargs' support of the platform as _experimental_. However, I'm excited to see folks adopt the functionality, and will happily fix bugs for the platform as they arise. |
| 100 | + |
| 101 | +## Significant Breaking Changes |
| 102 | + |
| 103 | +* the use of Conditional exports makes yargs' exported files explicit. Folks who were requiring deep files, e.g., `lib/utils/obj-filter.js`, will not be able to do so. The helpers yargs exposes have been [defined explicitly](https://github.com/yargs/yargs/pull/1733). |
| 104 | +* the `rebase` helper method has been removed from yargs (this was just wrapping `path.relative`). |
| 105 | +* Node 8 support has been dropped. |
| 106 | + |
| 107 | +_Other changes are listed in the [CHANGELOG](https://github.com/yargs/yargs/blob/master/CHANGELOG.md)_. |
| 108 | + |
| 109 | +-- [Ben](https://github.com/bcoe). |
| 110 | + |
| 111 | +Related: |
| 112 | + |
| 113 | +* ["Maintainers Should Consider Following Node.js’ Release Schedule"](https://medium.com/the-node-js-collection/maintainers-should-consider-following-node-js-release-schedule-ab08ed4de71a). |
| 114 | +* ["How my team releases libraries"](https://dev.to/bcoe/how-my-team-releases-libraries-23el). |
| 115 | +</div> |
| 116 | +</div> |
0 commit comments