minimistjs / minimist

parse argument options
MIT License
515 stars 30 forks source link

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

Closed tfish-oh closed 9 months ago

tfish-oh commented 9 months ago

image

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

ljharb commented 9 months ago

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.

tfish-oh commented 9 months ago

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

ljharb commented 9 months ago

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

tfish-oh commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

image It seems like it's still not working

ljharb commented 9 months ago

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

shadowspawn commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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

tfish-oh commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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.

https://github.com/minimistjs/minimist/blob/9080fa79ccfedb02eac91b91a477a0bc223ee8b2/index.js#L243

shadowspawn commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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