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

child_process.fork a ts file with import statement and args && execArgv !== undefined #619

Closed
ShayBox opened this issue Jun 27, 2018 · 8 comments
Labels

Comments

@ShayBox
Copy link

ShayBox commented Jun 27, 2018

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.

@ShayBox ShayBox changed the title child_process.fork a ts file with import statement and arg !== undefined child_process.fork a ts file with import statement and args && execArgv !== undefined Jun 27, 2018
@blakeembrey
Copy link
Member

blakeembrey commented Jun 29, 2018

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 <string[]> List of string arguments passed to the executable. Default: process.execArgv

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

@jrhite
Copy link

jrhite commented Sep 29, 2018

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?

@RobinBuschmann
Copy link

@jrhite This should work:

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

@RichAyotte
Copy link

This is what worked for me.

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

@Perry5
Copy link

Perry5 commented Sep 15, 2019

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"] });

@blakeembrey
Copy link
Member

blakeembrey commented Sep 15, 2019

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: #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.

@carlosalaniz
Copy link

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();

@Alexzanderk
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants