Как интегрировать Electron ipcRenderer в приложение Angular 2 на основе TypeScript?

Я хочу использовать ipcMain/ipcRenderer для моего проекта для связи от Angular to Electron и обратно.

Электронная сторона довольно понятна:

const
  electron = require('electron'),
  ipcMain = electron.ipcMain,
;

ipcMain.on('asynchronous-message', function(event, arg) {
  console.debug('ipc.async', arg);
  event.sender.send('asynchronous-reply', 'async-pong');
});

ipcMain.on('synchronous-message', function(event, arg) {
  console.debug('ipc.sync', arg);
  event.returnValue = 'sync-pong';
});

Но я не знаю, как интегрировать этот модуль Electron в мое приложение Angular 2. Я использую SystemJS в качестве загрузчика модулей, но я новичок с ним.

Любая помощь оценивается. Благодарю.

--- Марио

Ответ 1

Существует конфликт, потому что Electron использует решение commonjs, но ваш код уже скомпилирован с помощью правил systemjs.

Два решения:

Надежный путь. Объект Register require вернуть:

<script>
    System.set('electron', System.newModule(require('electron')));
</script>

Это лучше всего, потому renderer/init.js сценарий renderer/init.js загружает этот модуль при запуске. SystemJS должен принимать это только, а не нагрузки.

Альтернативный способ. Используйте грязный трюк с объявлением.

Получить экземпляр электрона внутри index.html:

<script>
    var electron = require('electron');
</script>

Объявите его внутри вашего файла typescript файла следующим образом:

declare var electron: any;

Используйте его со свободой)

electron.ipcRenderer.send(...)

Ответ 2

Недавний пакет под названием ngx-electron делает это легко. Ссылка на репо и ссылка на статью

SRC/приложение /app.module.ts

import { NgxElectronModule } from 'ngx-electron';
// other imports 
@NgModule({
  imports: [NgxElectronModule],
  ...
})

SRC/приложение /your.component.ts

import { Component, NgZone } from '@angular/core';
import { ElectronService } from 'ngx-electron';

@Component({
  selector: 'app-your',
  templateUrl: 'your.component.html'
})
export class YourComponent {
    message: string;        

    constructor(private _electronService: ElectronService, private _ngZone: NgZone) { 
        this._electronService.ipcRenderer.on('asynchronous-reply', (event, arg) => {
            this._ngZone.run(() => {
                let reply = 'Asynchronous message reply: ${arg}';
                this.message = reply;
            });
        }
    }

    playPingPong() {
        this._electronService.ipcRenderer.send('asynchronous-message', 'ping');
    }
}

Примечание: NgZone используется, потому что this.message обновляется асинхронно вне зоны Angulars. статья

Ответ 3

Но я понятия не имею, как интегрировать этот модуль Electron в мое приложение Angular 2

У вас было бы angular размещение в процессе отображения пользовательского интерфейса в электронном формате. ipcMain используется для связи с дочерними процессами без рендеринга.

Ответ 4

Это должно быть просто требованием модуля ipcRenderer в вашем главном файле html (электрон предоставит вам это):

<script>
  var ipc = require('electron').ipcRenderer;
  var response = ipc.sendSync('getSomething');
  console.log(response); // prints 'something'
</script>

а затем настроить обработчик в вашем основном файле js:

const ipcMain = require('electron').ipcMain;
ipcMain.on('getSomething', function(event, arg) {
  event.returnValue = 'something';
});

Это должно быть все.

Ответ 5

Мое решение:

настроить baseUrl в tsconfig.json

в корне каталога, на который указывает baseUrl, создайте каталог "электрон". Внутри этого каталога файл index.ts:

const electron = (<any>window).require('electron');

export const {BrowserWindowProxy} = electron;
export const {desktopCapturer} = electron;
export const {ipcRenderer} = electron;
export const {remote} = electron;
export const {webFrame} = electron;

(в идеале экспорт по умолчанию [...] требует ("электрон"), но это не является статически анализируемым...)

теперь я могу иметь в моем процессе визуализации:

import {remote} from 'electron';
console.log(remote);

Надеюсь, это имеет смысл...

с включенными типом:

///<reference path="../../typings/globals/electron/index.d.ts"/>
const electron = (<any>window).require('electron');

export const BrowserWindowProxy = <Electron.BrowserWindowProxy>electron.BrowserWindowProxy;
export const desktopCapturer = <Electron.DesktopCapturer>electron.desktopCapturer;
export const ipcRenderer = <Electron.IpcRenderer>electron.ipcRenderer;
export const remote = <Electron.Remote>electron.remote;
export const webFrame = <Electron.WebFrame>electron.webFrame;

NB: Типичные данные, которые я получил:

{
  "globalDependencies": {
    "electron": "registry:dt/electron#1.4.8+20161220141501"
  }
}