需要使用TypeScript,SystemJS和Electron的nodejs"child_process"

Ziv*_*zer 9 require node.js typescript systemjs electron

我正在研究一个简单的nodejs 电子(以前称为原子壳)项目.我正在使用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"
  ]
}
Run Code Online (Sandbox Code Playgroud)

我需要运行一个命令,我发现我可以使用节点"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;
}
Run Code Online (Sandbox Code Playgroud)

但我只能(据我所知)只使用导入获得此类型:

import * as child_process from 'child_process'; 
Run Code Online (Sandbox Code Playgroud)

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

GET file:///C:/angular2Samples/NGW-electron-VS%20-%20TEMP/child_process net::ERR_FILE_NOT_FOUND
Run Code Online (Sandbox Code Playgroud)

现在,我通过使用:

var child_process = require('child_process');
Run Code Online (Sandbox Code Playgroud)

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

var child_process : I_CANT_PUT_ANY_CHILD_PROCESS_TYPE_HERE = require('child_process');
Run Code Online (Sandbox Code Playgroud)

关于如何获取带有类型信息的child_process(或任何其他声明的公共接口,我可以在":"运算符之后声明的公共接口)的想法?

非常感谢您提供任何帮助和解释:)

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

由于tenbits建议我在文件的顶部添加了如下引用:///

并使用了你说的导入语句,但没有变形我的模块加载器.它仍然没有像预期的那样工作.我对改变模块系统感觉不太舒服,因为我的项目使用了角度2和他们的文档,他们的一些导游说新项目没有以前的优先考虑这个问题(我对模块加载器场景很新,我不是完全理解它是如何工作的).当我试图改变它时,我得到一些关于角度2的东西的错误,我现在没有足够的时间进入.如果不改变模块加载器,不应该有这种方法吗?通过浏览systemjs站点,它在开始时说它支持commonjs模块: Systemjs doc

我真的会想出一个不会改变模块系统的解决方案,或者可能会对正在发生的事情进行更深入的解释以及存在哪些模块加载问题的方法

ten*_*its 24

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

你可以import像以前一样使用

import * as child from 'child_process';

var foo: child.ChildProcess = child.exec('foo.sh');
console.log(typeof foo.on);
Run Code Online (Sandbox Code Playgroud)

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

System.config({
  map: {
    'child_process': '@node/child_process'
  }
});
Run Code Online (Sandbox Code Playgroud)

而已!

  • 很高兴它很有帮助,实际上我不熟悉“SystemJS”,只熟悉 TypeScript 和 Electron,但我认为问题是“SystemJS”正在加载 Nodejs 模块作为常规浏览器依赖项。所以一开始我建议以某种方式将其映射到 CommonJS 模块名称模式。当这没有帮助时,我只是查看源代码以了解映射的实际工作原理,并发现需要这个“@node”前缀。是的,它应该被记录下来,但是您始终可以查看源代码,这样您就可以了解该库是如何“设计”的)。干杯 (2认同)

Gus*_*lli 8

如果错误消息是“找不到模块‘child_process’或其相应的类型声明”,则答案是“npm install @types/watch”


rin*_*noy 5

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

import * as child from 'child_process';

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

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