需要 nodejs "child_process" 与 TypeScript、SystemJS 和 Electron

Require nodejs "child_process" with TypeScript, SystemJS and Electron

我正在开发一个简单的 nodejs electron(以前称为 atom shell)项目。 我正在使用 angular 2 编写它,使用与他们在打字稿文档中推荐的项目相同的项目设置:

tsc:

{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "exclude": [
  "node_modules",
  "typings/main",
  "typings/main.d.ts"
  ]
}

我需要 运行 一个命令,我发现我可以用节点 "child_process" 来完成。 我无法找到 "import" 或 "require" 它,同时从 node.d.ts 文件中使用它的类型。我在 node.d.ts 文件中找到了适合我需要的 "child_process" 接口, 这是它在 node.d.ts 文件中的样子:

    declare module "child_process" {
    import * as events from "events";
    import * as stream from "stream";

    export interface ChildProcess extends events.EventEmitter {
        stdin:  stream.Writable;
        stdout: stream.Readable;
        stderr: stream.Readable;
        pid: number;
        kill(signal?: string): void;
        send(message: any, sendHandle?: any): void;
        disconnect(): void;
        unref(): void;
    }

    export function spawn(command: string, args?: string[], options?: {
        cwd?: string;
        stdio?: any;
        custom?: any;
        env?: any;
        detached?: boolean;
    }): ChildProcess;
    export function exec(command: string, options: {
        cwd?: string;
        stdio?: any;
        customFds?: any;
        env?: any;
        encoding?: string;
        timeout?: number;
        maxBuffer?: number;
        killSignal?: string;
    }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess;
    export function exec(command: string, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess;
    export function execFile(file: string,
        callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess;
    export function execFile(file: string, args?: string[],
        callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess;
    export function execFile(file: string, args?: string[], options?: {
        cwd?: string;
        stdio?: any;
        customFds?: any;
        env?: any;
        encoding?: string;
        timeout?: number;
        maxBuffer?: number;
        killSignal?: string;
    }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess;
    export function fork(modulePath: string, args?: string[], options?: {
        cwd?: string;
        env?: any;
        execPath?: string;
        execArgv?: string[];
        silent?: boolean;
        uid?: number;
        gid?: number;
    }): ChildProcess;
    export function spawnSync(command: string, args?: string[], options?: {
        cwd?: string;
        input?: string | Buffer;
        stdio?: any;
        env?: any;
        uid?: number;
        gid?: number;
        timeout?: number;
        maxBuffer?: number;
        killSignal?: string;
        encoding?: string;
    }): {
        pid: number;
        output: string[];
        stdout: string | Buffer;
        stderr: string | Buffer;
        status: number;
        signal: string;
        error: Error;
    };
    export function execSync(command: string, options?: {
        cwd?: string;
        input?: string|Buffer;
        stdio?: any;
        env?: any;
        uid?: number;
        gid?: number;
        timeout?: number;
        maxBuffer?: number;
        killSignal?: string;
        encoding?: string;
    }): string | Buffer;
    export function execFileSync(command: string, args?: string[], options?: {
        cwd?: string;
        input?: string|Buffer;
        stdio?: any;
        env?: any;
        uid?: number;
        gid?: number;
        timeout?: number;
        maxBuffer?: number;
        killSignal?: string;
        encoding?: string;
    }): string | Buffer;
}

但我只能(据我所知)只能通过使用 import:

来获得这种类型
import * as child_process from 'child_process'; 

唯一的问题是当我这样做时,我的应用程序无法加载并且我在控制台中收到以下错误:

GET file:///C:/angular2Samples/NGW-electron-VS%20-%20TEMP/child_process net::ERR_FILE_NOT_FOUND

目前,我使用以下方法解决问题:

var child_process = require('child_process');

但无论如何我都找不到将类型信息添加到此 var:

var child_process : I_CANT_PUT_ANY_CHILD_PROCESS_TYPE_HERE = require('child_process');

关于如何获得带有类型信息的 child_process(或任何其他声明的节点模块,我可以在“:”运算符之后声明的 public 接口)有什么想法吗?

非常感谢您的帮助和解释:)

更新---------------------------------------- ----------------------

按照 tenbits 的建议,我在文件顶部添加了如下参考: ///

并使用了你说的导入语句,但没有改变我的模块加载器。它仍然没有像预期的那样出现相同的错误。 我对更改模块系统感到不太舒服,因为我的项目使用 angular 2 并且他们的文档和他们的一些指南说新项目对这个问题没有以前的偏好(我对模块加载器很陌生场景,我还没有完全理解它是如何工作的)。 当我尝试更改它时,我遇到了一些关于 angular 2 个内容的错误,目前我没有足够的时间来讨论这些内容。难道不应该有办法在不更改模块加载器的情况下做到这一点吗?通过浏览 systemjs 站点,它在开始时说它支持 commonjs 模块: Systemjs doc

我真的很喜欢一个不改变模块系统的解决方案,或者更深入地解释发生了什么以及存在哪些解决此类模块加载问题的方法

好的,经过一些研究#L138我找到了解决方案

您可以像以前一样使用import

import * as child from 'child_process';

var foo: child.ChildProcess = child.exec('foo.sh');
console.log(typeof foo.on);

但是您应该配置 SystemJS 以将模块映射到 NodeJS

System.config({
  map: {
    'child_process': '@node/child_process'
  }
});

就是这样!

对我来说,它与回调一起显示结果。

import * as child from 'child_process';

 var foo: child.ChildProcess = child.exec('dir', (error: string, stdout: string, stderr: string) => {
            console.log(stdout);      
        });

我没有在 SystemJS 中添加任何映射,因为我在节点应用程序中没有任何此类配置

如果错误信息是'找不到模块'child_process'或其相应的类型声明'答案是'npm install @types/watch'