【问题标题】:Require nodejs "child_process" with TypeScript, SystemJS and Electron需要带有 TypeScript、SystemJS 和 Electron 的 nodejs “child_process”
【发布时间】:2016-08-01 12:09:54
【问题描述】:

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

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”来执行它。 在从 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(或任何其他声明的节点模块,这些节点模块不是我可以在“:”运算符之后声明的公共接口)有什么想法吗?

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

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

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

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

我真的很想提供一个不改变模块系统的解决方案,或者更深入地解释正在发生的事情以及存在哪些解决此类模块加载问题的方法

【问题讨论】:

    标签: node.js typescript require electron systemjs


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      好的,经过一番研究#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 child = require('child_process'); 而不是var child = require('child_process');?你有和var一样的结果吗?
      • 是的,完全一样(注意我没有按照你的建议将模块更改为commonjs,原因在我上面的更新中注明)
      • 再次感谢您的新建议。恐怕它没有用。我复制了您的上一个版本的 System.config 并更改了我的代码以使用 import 语句,如您在 andwer 的第一个版本中建议的那样,但仍然出现相同的 xhr 错误。我也试过: import * as child from "child_process";这也没有同样的错误。我还尝试使用 node.d.ts 顶部的 /// 引用来做到这一点,但正如我所料,它没有改变任何东西
      • 很高兴它有帮助,实际上我不熟悉 SystemJS,只熟悉 TypeScript 和 Electron,但我认为问题是 SystemJS 正在加载 nodejs 模块作为常规浏览器依赖项。所以起初我建议以某种方式将它映射到 CommonJS 模块名称模式。当没有帮助时,我只是查看了源代码以了解映射的实际工作方式,并看到它是这个 @node 前缀所必需的。是的,它应该被记录在案,但您可以随时查看源代码,以便了解该库是如何“设计”的)。干杯
      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2016-07-29
        • 1970-01-01
        • 2017-02-19
        • 2021-07-20
        • 2020-08-31
        • 2017-10-17
        • 1970-01-01
        • 1970-01-01
        • 2015-11-20
        相关资源
        最近更新 更多