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

ts-node is not running sub-command #955

Closed
myflowpl opened this issue May 6, 2019 · 7 comments
Closed

ts-node is not running sub-command #955

myflowpl opened this issue May 6, 2019 · 7 comments

Comments

@myflowpl
Copy link

myflowpl commented May 6, 2019

ts-node is running the first command correctly

but the sub-command gives empty output, nothing happens

npm run start gives the help as expected

npm run start orient gives empty results

If i change the files back to .js and run it with node it works as expected

./package.json

{
  "name": "commander-ts-node",
  "scripts": {
    "start": "ts-node sm.ts"
  },
  "dependencies": {
    "@types/node": "^12.0.0",
    "commander": "^2.20.0",
    "ts-node": "^8.1.0",
    "typescript": "^3.4.5"
  }
}

./sm.ts

#!/usr/bin/env node

const program = require('commander');

program
  .version('0.0.1')
  .command('orient', 'existing sub command')
  .command('orient2', 'not existing');

program.parse(process.argv);

if (program.args.length === 0) {
  program.help();
}

./sm-orient.ts

#!/usr/bin/env node

const program = require('commander');

console.log('SM-ORIENT.ts')

program
  .command('download', 'download new version of orientdb')
  .command('switch', 'switch to other release')
  .command('backup', 'manage orientdb backups')
  .parse(process.argv);

./tsconfig.json

{
  "compilerOptions": {
    "moduleResolution": "node",
    "target": "es5",
    "module": "commonjs",
    "lib": ["es6", "es2015", "dom"],
    "typeRoots": ["node_modules/@types"],
    "baseUrl": "."
  },
  "exclude": ["node_modules", "tmp"]
}

I'm using Ubuntu Windows Linux Subsystem on Windows 10

node version: v10.15.1

@shadowspawn
Copy link
Collaborator

shadowspawn commented May 6, 2019

Nice complete reproduction example, thanks.

Technical detail.

Checking what node sees in sm.ts when run ts-node sm.ts get (shortened output):

  • process.argv of [ 'node_modules/.bin/ts-node', 'sm.ts', 'orient' ] (ok)
  • process.execArg of [ 'node_modules/ts-node/dist/bin.js' ] (uh oh)

Commander passes on process.execArg in case there are memory options or similar, producing an incorrect subcommand call of:

[ 'node_modules/.bin/ts-node', 'node_modules/ts-node/dist/bin.js', 'sm-orient.ts' ]

I wonder if we should be spawning process.execPath instead of process.argv[0], like we do on Windows?
Edit: nope, not that easy...

@shadowspawn
Copy link
Collaborator

I think a work-around is to use node as the executable:

$ node -r ts-node/register sm.ts orient compress
SM-ORIENT.ts

The -r ts-node/register pattern is mentioned on the ts-node page, and in the Commander pull request adding .ts support:

@myflowpl
Copy link
Author

myflowpl commented May 7, 2019

Yes, it works, but the problem for me is I need to pass the location of custom tsconfig.json.

You can do it like this: ts-node --project src/tsconfig.json sm.ts.

And I can't find the way to make it with node -r ts-node/register sm.ts syntax

@shadowspawn
Copy link
Collaborator

Getting messier especially for cross-platform, but you could define TS_NODE_PROJECT?

Mentioned under:

@myflowpl
Copy link
Author

myflowpl commented May 7, 2019

So true, I just didn't read the docs carefully enough and just learned new thing :)

Now it works with this package.json script

"start": "TS_NODE_PROJECT=mytsconfig.json node -r ts-node/register sm.ts"

So now the workaround is fully functional.

But if the issue is to hard to fix, the typescript configuration, and the workaround should at least be added to the documentation.

Thanks for your help.

@shadowspawn
Copy link
Collaborator

Note to self. Still wondering if we are spawning child process correctly in complex cases...

I added execPath to debugging, and think process.foo are self-consistent. arg[0] is the logical executable, arg[1] is the running script, and using execPath and execArg can pass the running script.

console.log('process.argv: ', process.argv);
console.log('process.execPath: ', process.execPath);
console.log('process.execArgv: ', process.execArgv);
$ node_modules/.bin/ts-node index.ts 
process.argv:  [ '/Users/john/Documents/Sandpits/commander/issues/execArgv/node_modules/.bin/ts-node',
  '/Users/john/Documents/Sandpits/commander/issues/execArgv/index.ts' ]
process.execPath:  /usr/local/bin/node
process.execArgv:  [ '/Users/john/Documents/Sandpits/commander/issues/execArgv/node_modules/ts-node/dist/bin.js' ]

Can add script to execPath and execArg...

$ /usr/local/bin/node /Users/john/Documents/Sandpits/commander/issues/execArgv/node_modules/ts-node/dist/bin.js /Users/john/Documents/Sandpits/commander/issues/execArgv/index.ts
process.argv:  [ '/Users/john/Documents/Sandpits/commander/issues/execArgv/node_modules/ts-node/dist/bin.js',
  '/Users/john/Documents/Sandpits/commander/issues/execArgv/index.ts' ]
process.execPath:  /usr/local/bin/node
process.execArgv:  [ '/Users/john/Documents/Sandpits/commander/issues/execArgv/node_modules/ts-node/dist/bin.js' ]

@shadowspawn
Copy link
Collaborator

Added TypeScript tips in README. Hopefully that helps.
https://github.com/tj/commander.js#typescript

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

2 participants