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

Why can't I get this parameter argv. template | | argv. t #51

Closed
tfish-oh opened this issue Oct 23, 2023 · 18 comments
Closed

Why can't I get this parameter argv. template | | argv. t #51

tfish-oh opened this issue Oct 23, 2023 · 18 comments

Comments

@tfish-oh
Copy link

image

Why can't I get this parameter argv. template | | argv. t? Did I pass the values incorrectly
"@types/minimist": "^1.2.2" 这个是我使用的版本

@ljharb
Copy link
Member

ljharb commented Oct 23, 2023

You specified the generic types for minimist, but you didn't actually pass a runtime value with that config to the function, so it doesn't know about any of them.

Types don't matter since they're all erased before runtime; the actual JS is what matters.

@ljharb ljharb closed this as not planned Won't fix, can't repro, duplicate, stale Oct 23, 2023
@tfish-oh
Copy link
Author

image
I passed in the parameter t during runtime, but what I got was undefined?

@ljharb
Copy link
Member

ljharb commented Oct 23, 2023

I don't mean on the command line - I mean as an option in the object passed to minimist().

@tfish-oh
Copy link
Author

const argv = minimist(process.argv.slice(2))
Is there a problem with this writing method?

I'm sorry to bother you, I can run the script locally using node, but pushing it to NPM is not enough

@ljharb
Copy link
Member

ljharb commented Oct 23, 2023

If you want the arguments t and template to be recognized, then the object you're currently passing in as { string: ['_'] } needs to be either omitted, or, to include "t" and "template" in the "string" array.

@tfish-oh
Copy link
Author

image
It seems like it's still not working

@ljharb
Copy link
Member

ljharb commented Oct 23, 2023

Remove '_', i'm not sure why that's there at all.

@shadowspawn
Copy link
Collaborator

npm consumes options from the command-line before the program can see them. You can check this by logging process.argv.

The work-around is to use -- to stop the option processing by npm. This is a feature commonly supported by command-line parsers included Minimist itself. It is included in the "usage" description for npm run-script since it is a common source of confusion.

Try putting -- after the script name, like:

npm create -- jl-cli my-vue-app -t p

@tfish-oh
Copy link
Author

Remove '_', i'm not sure why that's there at all.

The same error will be reported if the ‘_’ in minimist is removed.

@tfish-oh
Copy link
Author

npm consumes options from the command-line before the program can see them. You can check this by logging process.argv.

The work-around is to use -- to stop the option processing by npm. This is a feature commonly supported by command-line parsers included Minimist itself. It is included in the "usage" description for npm run-script since it is a common source of confusion.

Try putting -- after the script name, like:

npm create -- jl-cli my-vue-app -t p

image

I don’t know why the -t parameter can be recognized by removing the directory parameter.

@shadowspawn
Copy link
Collaborator

I don’t know why the -t parameter can be recognized by removing the directory parameter.

Are you referring to the _ key?

That is a special key used by Minimist in the results. It should not be included in the configuration opts being passed into Minimist.

You showed:

{
   string: ['_', 't'],
   alias: { t: 'template' }
}

but I would expect just:

{
   string: ['t'],
   alias: { t: 'template' }
}

@shadowspawn
Copy link
Collaborator

To explain a little more, Minimist does not need or support predefining what non-option arguments are expected.

@tfish-oh
Copy link
Author

I don’t know why the -t parameter can be recognized by removing the directory parameter.

Are you referring to the _ key?

That is a special key used by Minimist in the results. It should not be included in the configuration opts being passed into Minimist.

You showed:

{
   string: ['_', 't'],
   alias: { t: 'template' }
}

but I would expect just:

{
   string: ['t'],
   alias: { t: 'template' }
}

image
I mean, use the command in the picture above to remove the folder parameter ‘my-vue-app’ on the command line to identify the -t parameter. The folder parameter and the -t parameter cannot appear at the same time.

@tfish-oh
Copy link
Author

To explain a little more, Minimist does not need or support predefining what non-option arguments are expected.

image
image

I see that when create-vite and create-vue use minimum, they use string: ['_'] like this.

@shadowspawn
Copy link
Collaborator

shadowspawn commented Oct 24, 2023

I see that when create-vite and create-vue use minimum, they use string: ['_'] like this.

Oh! Looking at the Minimist code, I can see that works to prevent a conversion to number. I had not previously been aware that was possible. Thanks for the references.

argv._.push(flags.strings._ || !isNumber(arg) ? arg : Number(arg));

@shadowspawn
Copy link
Collaborator

shadowspawn commented Oct 24, 2023

I don’t know why the -t parameter can be recognized by removing the directory parameter.

I mean, use the command in the picture above to remove the folder parameter ‘my-vue-app’ on the command line to identify the -t parameter. The folder parameter and the -t parameter cannot appear at the same time.

Do you want to display an error if both are supplied? If so, you will need to check for that yourself.

Or does the full program not allow both at once? I can specify both in a test program.

const minimist = require('minimist');
const commandLineArgs = process.argv.slice(2);

// The { string: ['_'] } is to prevent positional arguments from being parsed as numbers.
const argv = minimist(commandLineArgs, { string : ['_'] });

console.log('Parse: %o', commandLineArgs);
const argTargetDir = argv._[0];
const argTemplate = argv.template || argv.t;
console.log({ argTargetDir, argTemplate });
% node index.js 1234            
Parse: [ '1234', [length]: 1 ]
{ argTargetDir: '1234', argTemplate: undefined }
% node index.js my-vue-app
Parse: [ 'my-vue-app', [length]: 1 ]
{ argTargetDir: 'my-vue-app', argTemplate: undefined }
% node index.js -t TEMPLATE
Parse: [ '-t', 'TEMPLATE', [length]: 2 ]
{ argTargetDir: undefined, argTemplate: 'TEMPLATE' }
% node index.js --template TEMPLATE
Parse: [ '--template', 'TEMPLATE', [length]: 2 ]
{ argTargetDir: undefined, argTemplate: 'TEMPLATE' }
% node index.js my-vue-app -t TEMPLATE
Parse: [ 'my-vue-app', '-t', 'TEMPLATE', [length]: 3 ]
{ argTargetDir: 'my-vue-app', argTemplate: 'TEMPLATE' }
% node index.js -t TEMPLATE my-vue-app
Parse: [ '-t', 'TEMPLATE', 'my-vue-app', [length]: 3 ]
{ argTargetDir: 'my-vue-app', argTemplate: 'TEMPLATE' }

@tfish-oh
Copy link
Author

I don’t know why the -t parameter can be recognized by removing the directory parameter.

I mean, use the command in the picture above to remove the folder parameter ‘my-vue-app’ on the command line to identify the -t parameter. The folder parameter and the -t parameter cannot appear at the same time.

Do you want to display an error if both are supplied? If so, you will need to check for that yourself.

Or does the full program not allow both at once? I can specify both in a test program.

const minimist = require('minimist');
const commandLineArgs = process.argv.slice(2);

// The { string: ['_'] } is to prevent positional arguments from being parsed as numbers.
const argv = minimist(commandLineArgs, { string : ['_'] });

console.log('Parse: %o', commandLineArgs);
const argTargetDir = argv._[0];
const argTemplate = argv.template || argv.t;
console.log({ argTargetDir, argTemplate });
% node index.js 1234            
Parse: [ '1234', [length]: 1 ]
{ argTargetDir: '1234', argTemplate: undefined }
% node index.js my-vue-app
Parse: [ 'my-vue-app', [length]: 1 ]
{ argTargetDir: 'my-vue-app', argTemplate: undefined }
% node index.js -t TEMPLATE
Parse: [ '-t', 'TEMPLATE', [length]: 2 ]
{ argTargetDir: undefined, argTemplate: 'TEMPLATE' }
% node index.js --template TEMPLATE
Parse: [ '--template', 'TEMPLATE', [length]: 2 ]
{ argTargetDir: undefined, argTemplate: 'TEMPLATE' }
% node index.js my-vue-app -t TEMPLATE
Parse: [ 'my-vue-app', '-t', 'TEMPLATE', [length]: 3 ]
{ argTargetDir: 'my-vue-app', argTemplate: 'TEMPLATE' }
% node index.js -t TEMPLATE my-vue-app
Parse: [ '-t', 'TEMPLATE', 'my-vue-app', [length]: 3 ]
{ argTargetDir: 'my-vue-app', argTemplate: 'TEMPLATE' }

I can do it locally, but it won’t work if I put it on npm and use scaffolding.

@shadowspawn
Copy link
Collaborator

I can do it locally, but it won’t work if I put it on npm and use scaffolding.

I have not written a package initializer, but it looks like the main trick is using the --. To be safe, I would use it straight after the registry option like in the example below. (npm init and npm create do the same thing.)

The documentation for npm-init shows:

Any additional options will be passed directly to the command, so npm init foo -- --hello will map to npm exec -- create-foo --hello.

To better illustrate how options are forwarded, here's a more evolved example showing options passed to both the npm cli and a create package, both following commands are equivalent:

npm init foo -y --registry=<url> -- --hello -a
npm exec -y --registry=<url> -- create-foo --hello -a

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

No branches or pull requests

3 participants