7

I have a typescript project and rather than using tsc first, I'm just running via ts-node directly.

In my code I need to create a child process with fork().

If I run code like child_process.fork('ChildProcess.ts') and ChildProcess.ts contains some typescript only constructs (eg: import {}, export, ...), then the interpreter being node, not ts-node, will fail.

It may be recommended to use something like child_process.exec('node ./node_modules/.bin/ts-node ChildProcess.ts), but I really want/need the IPC communication channel that gets set up between the parent and child processes when fork() specifically is used.

Any ideas on how to achieve this?

Thanks!

lostdorje
  • 6,150
  • 9
  • 44
  • 86
  • 1
    `import` and `export` aren't TypeScript-specific. They're standard JavaScript introduced in ES2015. (Node has experimental, partial support for them now via the `--experimental-modules` runtime flag.) But of course, none of that helps you with true TypeScript-only features that are presumably in the file, like type annotations. :-) – T.J. Crowder Sep 29 '18 at 14:50
  • I'm not sure what the problem is. `fork('ChildProcess.ts')` should run it with ts-node, too. Can you provide a way to replicate the problem? – Estus Flask Sep 29 '18 at 14:52
  • Yeah, right, I might have chosen bad examples. So yeah, let's say I'm using annotations, which I am. :-) – lostdorje Sep 29 '18 at 14:52

3 Answers3

10

As the reference states, execArgv in forked process is inherited from current process:

execArgv List of string arguments passed to the executable. Default: process.execArgv.

When entry point runs as:

ts-node index.ts

execArgv defaults to ts-node binary:

[ '...\\ts-node\\dist\\_bin.js' ]

And

child_process.fork('ChildProcess.ts') 

runs with ts-node too.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Ah, you're exactly right. Thanks. I was running into problems because I wrote an initial test for this and use jest to run the tests which is invoked via `node`, not `ts-node`. I lost site of this point. I wrote a quick little driver snippet in typescript and run it via `ts-node` and you are correct. `ts-node` is invoked and the typescript in my child process runs fine. Now to figure out how to write a nice jest test for this. ;-) Thanks! – lostdorje Sep 29 '18 at 15:12
  • Glad you resolved this quickly. Depending on how you test this, you could possibly assert `execArgv`. – Estus Flask Sep 29 '18 at 15:17
3

If you omit the file extension when forking the process, it works with ts-node during developement, as well as with tsc and node in production.

In your app.ts file:

import { fork } from 'child_process';

fork('./longRunningProcess');

Then you can have TypeScript constructs in your longRunningProcess.ts file. After transpilation to app.js and longRunningProcess.js, it will still work when running with regular node.

0

If ts-node doesn't handle fork itself (which is a bit surprising, but I don't use it), and you need the IPC, I think your choices are:

  • Use tsc beforehand so you're invoking a JavaScript file, or

  • Use tsc on-demand to compile the ChildProcess.ts file to a ChildProcess.js file, and then fork the ChildProcess.js file.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Ah, not pretty, but yeah I hadn't thought of the on demand approach. Something like `tsc.compile(['ChildProcess.ts'], ['--out', 'ChildProcess.js'])` followed by `fork('ChildProcess.js')` may just be the easiest way to get what I need. Lemme think a little more on this. Thanks! – lostdorje Sep 29 '18 at 14:56