Ts-node: child_process.fork a ts file with import statement and args && execArgv !== undefined

Created on 27 Jun 2018  路  8Comments  路  Source: TypeStrong/ts-node

index.ts

import { fork } from 'child_process';

const proc = fork('test.ts', [], { execArgv: [] })
proc.on('message', message => console.log(message))

test.ts

import * as test from 'fs';

console.log('File loaded')

Note: You need ts-node, typescript, and @types/node
I was using node version 10.4.1

It will work if you:
Remove test.ts's import statement,
Change either empty array to undefined in index.ts,
Or use vanilla js/compiled typescript

PS C:\Users\ShayB\Desktop> node -r ts-node/register index.ts
C:\Users\ShayB\Desktop\test.ts:1
(function (exports, require, module, __filename, __dirname) { import * as test from 'fs';
                                                                     ^

SyntaxError: Unexpected token *
    at new Script (vm.js:74:7)
    at createScript (vm.js:246:10)
    at Object.runInThisContext (vm.js:298:10)
    at Module._compile (internal/modules/cjs/loader.js:670:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10)
    at Module.load (internal/modules/cjs/loader.js:612:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
    at Function.Module._load (internal/modules/cjs/loader.js:543:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:744:10)
    at startup (internal/bootstrap/node.js:238:19)
PS C:\Users\ShayB\Desktop> node -r ts-node/register index.ts

Note: the error is not the * it will be at the same spot no matter what you import.

I actually ran into this in a real project too, incredible.

invalid

Most helpful comment

This is what worked for me.

fork(
  'child-process.ts'
  , []
  , {
    execArgv: ['-r', 'ts-node/register']
  }
)

All 8 comments

You're overriding execArgv which means this isn't even running through TypeScript.

Please read the documentation for functions you're trying to use: https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options.

execArgv process.execArgv

child_process.fork() will spawn new Node.js instances using the process.execPath of the parent process.

I think the real issue here is child_process.fork() forks a new Node.js instance, but it is unaware of ts-node.

I have the same problem and the title containing things like args and execArgv is really leading in the wrong direction.

I'm also running my code via ts-node. In it I need to create a child proc 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 my-typescript-module.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?

@jrhite This should work:

const childProcess = fork(join(__dirname, 'child-process.ts'), ['-r', 'ts-node/register']);`

This is what worked for me.

fork(
  'child-process.ts'
  , []
  , {
    execArgv: ['-r', 'ts-node/register']
  }
)

I know this is old, but hopefully it helps someone.

@RichAyotte's response worked for me. In my case I needed to specify the relative path to the file:
const childProcess = fork("./src/controllers/child-process.ts", [], { execArgv: ["-r", "ts-node/register"] });

Heads up: This should never have been an issue. If you are encountering an issue please let me know by creating a new issue.

I did additional work in January to ensure args from the ts-node executable also forward correctly to children: https://github.com/TypeStrong/ts-node/pull/760.

Edit: The original issue is still valid though, if you override execArgv it won't be able to use the default behavior of re-using ts-node.

You can also omit the extension, once compiled the resulting JavaScript will be used. Ex.

ParentProcess.ts

  import * as child_process from 'child_process';
  import * as path from 'path';

  let ChlidProcessPath = path.resolve(__dirname + "/ChildProcess")
  child_process.fork(ChlidProcessPath, [], { stdio: ['inherit', 'inherit', 'inherit', 'ipc'] });

ChlidProcess.ts

class ChildProcessClass {
    constructor() {
        console.log("forked!"); 
    }
}
new ChildProcessClass();

How can I use ts-node-dev instead of ts-node?

Was this page helpful?
0 / 5 - 0 ratings