Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the way we import yargs (lag of documentation) #2045

Open
soroushm opened this issue Oct 12, 2021 · 9 comments
Open

the way we import yargs (lag of documentation) #2045

soroushm opened this issue Oct 12, 2021 · 9 comments
Labels

Comments

@soroushm
Copy link

soroushm commented Oct 12, 2021

I running Yargs in cli, the advanced documentation have two different ways to use yargs,
I will glade somebody explain to me why we need to use yargs as a function?
and do we need it for simple usage like below?

import yargs from 'yargs/yargs`

yargs(process.argv.slice(2)).commandDir()

instead of using like this

import yargs from 'yargs`
yargs.commandDir()
@soroushm soroushm changed the title lag of documentatin the way we import yargs (lag of documentation) Oct 12, 2021
@bcoe bcoe added the question label Oct 13, 2021
@bcoe
Copy link
Member

bcoe commented Oct 13, 2021

@soroushm thank you for the question, I will make an effort to update the documentation with a better explanation.

The preferred approach to use is yargs() which returns a new instance of yargs, whereas using yargs.parse(), yargs.commandDir(), etc., uses a singleton pattern -- there may be state that leaks.

Newer ESM syntax only supports yargs() syntax.

@soroushm
Copy link
Author

soroushm commented Oct 14, 2021

@bcoe is that any difference between the two import?

import yargs from 'yargs/yargs'
import yargs from 'yargs'

@bcoe
Copy link
Member

bcoe commented Nov 19, 2021

If you're writing TypeScript, and using the CJS version of the library,

import yargs from 'yargs' <-- would give you the singleton version of the library.
import yargs from 'yargs/yargs' <-- non-singleton version with some helpers attached to it (like an instance of yargs-parser).

If you're using the ESM version of the library:

import yargs from 'yargs' <-- gives you non-singleton version of library.
import yargs from 'yargs/yargs' <-- I belivee is currently slightly broken, see #2067

@shadowspawn
Copy link
Member

shadowspawn commented Feb 26, 2023

This looks a good issue for potential improvements to basic recommended patterns, CommonJS vs ESM, and singleton vs factory.

The TypeScript instructions could cover esModuleInterop more explicitly, as failure modes are currently mysterious if using CommonJS with it false: #2010

@shadowspawn
Copy link
Member

shadowspawn commented Feb 26, 2023

A musing rather than a recommendation at this point. The magic yargs.argv mystified me, until I found it is a getter. I wonder if we would be better to promote .parse() in examples as clearer what is happening?

Reference: #2068 (comment)

There could be a small section on the appealing concise but magic singleton invocation: const argv = require('yargs').argv.

Edit: found another reference that .argv is legacy and .parse() preferred:

// Legacy yargs.argv interface, it's recommended that you use .parse().

@shadowspawn
Copy link
Member

shadowspawn commented Jul 15, 2023

I found importing from yargs/yargs works well from TypeScript if use module: Node16 (or NodeNext) for the ESM build. I updated the table of import and setting permutations: #2010 (comment)

So I think yargs/yargs could be the default pattern we use everywhere except talking about the legacy singleton, which requires esModuleInterop turned on or broken for CommonJS. (#2010)

Hopefully #2067 has been fixed by addition of separate ESM entry point.

(Edit: yargs/yargs is used in most places in docs already. I was working through some of the trade-offs myself, as also confused by the yargs and yargs/yargs.)

@shadowspawn
Copy link
Member

shadowspawn commented Oct 16, 2023

I keep seeing issues with some TypeScript combinations due to the differences in default exports. I wonder whether adding a named export for the yargs factory function would be much simpler to use from TypeScript?!

@bcoe
Copy link
Member

bcoe commented Nov 21, 2023

Hey @shadowspawn, I'm hoping to start dabbling in OSS a bit again, so digging through some old issues. Thanks for your work on yargs.

yargs/yargs is used in most places in docs already. I was working through some of the trade-offs myself, as also confused by the yargs and yargs/yargs

I wonder if we should consider deprecating the old singleton behaviour. I think it would be less confusing if yargs and yargs/yargs were equivalent (ideally for both CJS, ESM, and TypeScript).

The downside of this, is that a lot of folks in the world are using the singleton approach and would need help upgrading.

@shadowspawn
Copy link
Member

shadowspawn commented Nov 22, 2023

Am I correct in thinking that the main benefit (currently) of yargs/yargs is to get away from the singleton for new users of yargs?

The downside of this, is that a lot of folks in the world are using the singleton approach and would need help upgrading.

Yup, going to break lots of people upgrading. However, people will also be hitting this going from CJS to ESM without causing too many complaints.

A related change I would like to investigate is making it easy to use the factory method and implicitly obtain the arguments from process.argv, like the singleton does. (I don't think that currently happens?)
Update: opened #2399

For interest, in Commander I have likewise been preparing for dropping the default export of a singleton for years. One decision I made early on was to add a named export of a singleton so it was still available for explicit use, but (eventually) not as the default export. That provides another route for people transitioning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants