Требовать nodejs child_process с TypeScript, SystemJS и Electron

Я работаю над простым проектом nodejs electron (ранее известный как атомная оболочка). Я пишу это с помощью angular 2, используя проект с той же настройкой проекта, которую они рекомендуют в документации для машинописного текста:

тск:

{
  "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. Я нашел интерфейс «child_process» в файле node.d.ts, который мне подходит, вот как он выглядит в файле 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 * 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

Я был бы очень признателен за решение, которое не меняет систему модулей, или, может быть, более подробное объяснение того, что происходит и какие существуют подходы к таким проблемам с загрузкой модулей.


person Ziv Glazer    schedule 11.04.2016    source источник


Ответы (3)


Хорошо, после небольшого исследования #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'
  }
});

Вот оно!

person tenbits    schedule 11.04.2016
comment
Большое спасибо за ваш комментарий! Я пробовал, посмотрите мое обновление вопроса относительно вашего ответа :) - person Ziv Glazer; 11.04.2016
comment
Я не совсем понял: вы пробовали import child = require('child_process'); вместо var child = require('child_process');? У вас такой же результат, как с var? - person tenbits; 11.04.2016
comment
Да, точно так же (обратите внимание, что я не менял модуль на commonjs, как вы предложили, причина этого указана в моем обновлении выше) - person Ziv Glazer; 12.04.2016
comment
Еще раз спасибо за ваше новое предложение. Боюсь, это не сработало. Я скопировал вашу последнюю версию System.config и изменил свой код, чтобы использовать оператор импорта с требованием, как вы предложили в первой версии вашего andwer, и все равно получил ту же ошибку xhr. Я также пробовал: импортировать * как дочерний элемент из child_process; Это тоже не сработало с той же ошибкой. Я также пытался сделать это с /// ссылкой вверху на node.d.ts, но, как я и ожидал, это ничего не изменило. - person Ziv Glazer; 14.04.2016
comment
Возможно, также переименуйте заголовок вопроса в Require nodejs «child_process» с typescript, systemjs и electronic. - person tenbits; 14.04.2016
comment
@ user1245668, вы проверили это решение? - person tenbits; 15.04.2016
comment
Еще нет, я проверю и отредактирую вопрос первым делом завтра :) - person Ziv Glazer; 16.04.2016
comment
Это сработало ! Большое спасибо за помощь, это очень ценно :) Я посмотрел на исходный код systemjs, который вы связали, и понял, как это работает, но я все еще чувствую, как будто вы нашли его случайно, и мне интересно, как такого рода вещи, касающиеся systemjs, нигде не задокументировано - person Ziv Glazer; 17.04.2016
comment
Рад, что это было полезно, на самом деле я не был знаком с SystemJS, только с TypeScript и Electron, но я предположил, что проблема была в том, что SystemJS загружал модуль nodejs как обычную зависимость браузера. Поэтому сначала я предложил как-то сопоставить его с шаблоном имени модуля CommonJS. Когда это не помогло, я просто заглянул в исходный код, чтобы понять, как на самом деле работает сопоставление, и увидел, что требуется этот префикс @node. Да, это должно быть задокументировано, но вы всегда можете заглянуть в исходные коды, чтобы понять, как была спроектирована библиотека). Ваше здоровье - person tenbits; 18.04.2016
comment
Как добиться этого с помощью модуля commonJs? - person AishApp; 28.04.2016
comment
@Aish123, с @node/ вы можете загружать только модули основного узла, см. ">line и обратите внимание на массив nodeCoreModules. Что определенно работает: import * as baz from 'node_modules/foo/x.js'; А для TypeScript вам нужно создать пустое определение модуля, чтобы его скомпилировать. - person tenbits; 28.04.2016
comment
@tenbits, извините, я не могу понять, что вы имеете в виду под пустым определением модуля. У меня есть файл библиотеки .d.ts, который вызывает child_process. Я получаю сообщение об ошибке, так как не могу найти модуль «child_process». Не могли бы вы уточнить, что вы имеете в виду, чтобы я мог попробовать. - person AishApp; 28.04.2016
comment
@ Aish123, ах, вы получаете ошибку Typescript во время компиляции. Вам необходимо установить Node Typings node.d.ts. Вы делаете это с tsd. Сначала установите его: npm install tsd -g. Затем в каталоге вашего проекта выполните команду tsd install node. Это установит node.d.ts в каталог typings. И создаст tsconfig.json. - person tenbits; 28.04.2016
comment
ну я тоже так сделал. Включил ссылку и добавил импорт {exec} из 'child_process';. Все еще получаю сообщение об ошибке Не удается разрешить модуль «child_process» - person AishApp; 28.04.2016
comment
@Aish123, сделай так, чтобы в tsconfig.json у тебя было свойство "moduleResolution": "node",. Возможно, также попробуйте установить типы узлов с сохранением falg tds install node --save. Пожалуйста, дайте также обратную связь) - person tenbits; 28.04.2016
comment
извините за задержку ответа. я все еще получаю сообщение об ошибке, и причина в модуле child_process проверяется в папке node_modules, а не в ссылочном файле node.d.ts. Я не уверен, как импортировать его в свой файл - person AishApp; 29.04.2016
comment
Хм, на самом деле child_process — это основной модуль nodejs. Как это может быть в папке node_modules? И нет сторонних модулей child_process: может быть, вам следует начать новый вопрос и объяснить свой проблема в деталях, чтобы мы перенесли обсуждение туда? - person tenbits; 29.04.2016
comment
я изменил свой запрос в ссылке stackoverflow.com/questions/36913677/ - person AishApp; 29.04.2016
comment
у меня нет system.config.js, можете ли вы помочь мне решить эту проблему? - person Shreenil Patel; 28.12.2017

Если сообщение об ошибке "Не удается найти модуль "child_process" или его соответствующие объявления типа", ответ будет "npm install @types/watch".

person Gustavo Hernán Crucianelli    schedule 04.10.2020

Для меня это работало с обратным вызовом для отображения результатов.

import * as child from 'child_process';

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

Я не добавлял никаких сопоставлений в SystemJS, поскольку у меня нет такой конфигурации в приложении узла.

person rinoy    schedule 22.09.2017