Should node support subcommands?
What is the problem this feature will solve?
currently, node's cli interface is pretty simple and lean, it mainly accepts flags that start with two dashes, or sometimes a single dash for some aliases. additionally, many flags depend on each other or imply using another flag.
now that more and more flags are added to node, (and each new flag is heavily considered before adding to avoid options bloat), I propose we support a more complex cli interface with sub-commands.
this issue has come up before when adding node --run, and to avoid blocking that - the discussion was postponed, so I went ahead and opened this issue.
If I recall, the main concern was node run or node test is a breaking change since it today runs node run.js or node test.js accordingly - that can be addressed with releasing this gradually as semver-major with a deprecation warning for a few versions prior to the actual change
some groups/clusters of commands that might fit using sub commands:
-
node --run -
node --watch,--watch-path -
node --test -
node --build-snapshot
What is the feature you are proposing to solve the problem?
N/A
What alternatives have you considered?
No response
I've voiced concerns about this various times in the past, perhaps most recently in this comment. Don't get me wrong, subcommands are great, and if we were to redesign Node.js from scratch we likely should use them. However, ...
I have reason to believe that a significant number of users rely on the fact that node test runs either test.js or test/index.js, and the same is likely true for node run. So while semver-major releases technically allow us to break things, I think this would cause significant breakage. There's probably many semi-maintained npm modules that use node test (or variations thereof) as their npm test script.
More generally, accepting either a positional argument or a subcommand in the same location is an anti-pattern in my mind. We unfortunately already have node inspect, so Node.js is already following something that I'd consider an anti-pattern, but that shouldn't be a loophole for us to further commit to that anti-pattern.
The only semi-reasonable way I see is to fully deprecate node xyz, where xyz would usually cause the execution of whatever xyz resolves to. Of course, this would be a huge breaking change and would likely take years, but anything less than this will introduce more and more inconsistencies, and each new subcommand would cause new breakage and deprecation cycles.
The only semi-reasonable way I see is to fully deprecate node xyz, where xyz would usually cause the execution of whatever xyz resolves to. Of course, this would be a huge breaking change and would likely take years, but anything less than this will introduce more and more inconsistencies, and each new subcommand would cause new breakage and deprecation cycles.
why would that take years?
We can doc-only deprecate the current behavior right now, and releasing that would take days to weeks. But actually moving node xyz to end-of-life seems like a huge breaking change to me. (Then again, some project members are more open to rapidly breaking things than myself, so maybe it would just take two semver-majors or so.)
We could take some pragmatic, not very elegant steps to avoid reaching end-of-life status, e.g., by still allowing node xyz whenever xyz looks like a path (e.g., contains a file extension or a directory separator). But in any case, we'll break the very basics of how people run JavaScript files with Node.js.
But in any case, we'll break the very basics of how people run JavaScript files with Node.js.
I think, for example, that preventing node xyz from running xyz would stop Node.js shell scripts (i.e. those that begin
#!/usr/bin/env node
...
) from working.
I'm +1 on the addition of subcommands.
Additionally, the project could have multiple help pages per sub command category, which might have a better UX when it comes to the help page.
For files with the same name as commands, the project could adopt what many CLIs do, which is if a value is within quotes, don't treat as a CLI flag (IE "--hello" is a file, while --hello is a CLI argument) (I don't remember whether Node.js does this already)
For files with the same name as commands, the project could adopt what many CLIs do, which is if a value is within quotes, don't treat as a CLI flag (IE
"--hello"is a file, while--hellois a CLI argument)
I'm not aware of anything else that does this, but IMO this would be terribly confusing to users -- in many cases the quotes would be processed by the shell and wouldn't be seen by the program being run (i.e. node).
I'm not aware of anything else that does this, but IMO this would be terribly confusing to users -- in many cases the quotes would be processed by the shell and wouldn't be seen by the program being run (i.e.
node).
I think the shell does this by itself, I'm no expert on how CLIs even work, but I think the shell will denote quotes as not a CLI flag regardless. I worded my example very poorly, ignore it.
I meant to say that IIUC arguments within quotes aren't treated as CLI flags, but that's not so relevant, and I may have misunderstood.
I don't know enough about CLIs
I think, for example, that preventing node xyz from running xyz would stop Node.js shell scripts
why would adding subcommands break hashbang? I am not following
I think, for example, that preventing node xyz from running xyz would stop Node.js shell scripts
why would adding subcommands break hashbang? I am not following
Because if you have a file called xyz that begins:
#!/usr/bin/env node
...
that has execute permissions and you run it, e.g.
xyz
it will end up running the equivalent of
node xyz
I'm +1 on making this breaking change. I think the UX for cli flags are really bad that even I have some trouble understanding if feature X is working with feature Y.
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the https://github.com/nodejs/node/labels/never-stale label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document.
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the https://github.com/nodejs/node/labels/never-stale label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document.