invoke a child process via fork() when using ts-node
Asked Answered
C

3

8

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!

Conventionalism answered 29/9, 2018 at 14:40 Comment(3)
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. :-)Tekla
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?Blowtorch
Yeah, right, I might have chosen bad examples. So yeah, let's say I'm using annotations, which I am. :-)Conventionalism
B
12

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.

Blowtorch answered 29/9, 2018 at 15:3 Comment(2)
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!Conventionalism
Glad you resolved this quickly. Depending on how you test this, you could possibly assert execArgv.Blowtorch
D
4

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.

Dolorous answered 18/4, 2020 at 11:37 Comment(0)
T
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.

Tekla answered 29/9, 2018 at 14:48 Comment(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!Conventionalism

© 2022 - 2024 — McMap. All rights reserved.