Простая настройка для работы Angular 4 с Electron Webpack, с загрузкой шаблона и дополнительной библиотекой CSS (Bulma). Я использую Yarn, но вы, вероятно, можете использовать npm. Зависимость Electron Builder рекомендует Yarn.

1. Базовая настройка

Сначала начните с пустого каталога и инициализируйте зависимости Angular:

yarn add @angular/common @angular/compiler @angular/core \
  @angular/forms @angular/http @angular/platform-browser \
  @angular/platform-browser-dynamic @angular/router \
  core-js rxjs source-map-support zone.js

Затем добавьте --dev зависимости для Electron Webpack (также включая Typescript и надстройку Electron Webpack Typescript):

yarn add --dev electron-webpack electron-webpack-ts electron \
  webpack typescript @types/node

Чтобы использовать Electron Webpack, вам необходимо создать две точки входа. Основной поток и поток средства визуализации. В качестве основной точки входа я преобразовал пример из начального проекта Electron Webpack для использования Typescript. Создайте этот файл как src/main/index.ts

import { app, BrowserWindow } from 'electron'

const isDevelopment = process.env.NODE_ENV !== 'production';

let mainWindow : BrowserWindow;

function createMainWindow() {
    const window = new BrowserWindow();

    // Set url for `win`
    // points to `webpack-dev-server` in development
    // points to `index.html` in production
    const url = isDevelopment
        ? `http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`
        : `file://${__dirname}/index.html`;

    if (isDevelopment) {
        window.webContents.openDevTools();
    }

    window.loadURL(url);

    window.on('closed', () => {
        mainWindow = null;
    });

    window.webContents.on('devtools-opened', () => {
        window.focus();
        setImmediate(() => {
            window.focus();
        })
    });

    return window;
}

app.on('window-all-closed', () => {
    // On macOS it is common for applications to stay open
    // until the user explicitly quits
    if (process.platform !== 'darwin') app.quit()
});

app.on('activate', () => {
    // On macOS it is common to re-create a window
    // even after all windows have been closed
    if (mainWindow === null) mainWindow = createMainWindow();
});

// Create main BrowserWindow when electron is ready
app.on('ready', () => {
    mainWindow = createMainWindow();
});

Для рендерера я объединил polyfill.ts, vendor.ts и main.ts Angular, чтобы создать src/renderer/index.ts

// Polyfills
import "core-js/es7/reflect";
require("zone.js/dist/zone");

// Vendor
import "@angular/platform-browser";
import "@angular/platform-browser-dynamic";
import "@angular/core";
import "@angular/common";
import "@angular/http";
import "@angular/router";
import "rxjs";

// main

import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { enableProdMode } from "@angular/core";
import { AppModule } from "./app/app.module";

if(process.env.NODE_ENV === "production") {
    enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule);

Electron Webpack создает индекс HTML. Он включает элемент с идентификатором #app, который используется в качестве селектора в главном src/renderer/app/app.component.ts

import {Component, ViewEncapsulation} from "@angular/core";
@Component({
    selector: '#app',
    template: '<h1>App works!</h1>',
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {}

AppModule, который загружает Angular и загружает AppComponent, определен в src/renderer/app/app.module.ts с помощью:

import {NgModule} from "@angular/core";
import {BrowserModule} from "@angular/platform-browser";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import {AppComponent} from "./app.component";

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule
    ],
    declarations: [
        AppComponent
    ],
    bootstrap: [
        AppComponent
    ]
})
export class AppModule {}

В корневом каталоге проекта создайте tsconfig.json для настройки Typescript для компиляции Angular:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "typeRoots": [
      "./node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  },
  "include": [
    "./**/*"
  ]
}

Добавьте раздел scripts в свой package.json с командой для запуска Electron Webpack в режиме разработки:

"scripts": {
    "dev": "electron-webpack dev"
 }

Теперь вы готовы запустить минимальное приложение, используя следующую команду:

yarn dev

2. Добавление поддержки шаблонов Angular

В приведенном выше минимальном примере используются встроенные шаблоны Angular. Чтобы файлы шаблонов Angular работали, вам необходимо добавить правильный загрузчик веб-пакетов и настроить конфигурацию веб-пакетов.

Сначала добавьте в проект необходимые зависимости:

yarn add --dev angular2-template-loader

Создайте настраиваемый файл конфигурации веб-пакета с именем webpack-renderer-additions.js со следующим содержимым:

module.exports = {
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: "ts-loader"
                    },
                    {
                        loader: "angular2-template-loader"
                    }
                ]
            }
        ]
    }
};

И скажите Electron Webpack загрузить эту конфигурацию, добавив следующее в package.json проекта

"electronWebpack": {
  "renderer": {
    "webpackConfig": "webpack.renderer.additions.js"
  }
}

Теперь вы можете добавить шаблон для компонента приложения, создать src/renderer/app/app.component.html со следующим содержимым:

<h1 class="title">App Works!</h1>

И обновите src/renderer/app/app.component.ts, чтобы удалить встроенный шаблон и сослаться на этот файл шаблона:

import {Component, ViewEncapsulation} from "@angular/core";

@Component({
    selector: '#app',
    templateUrl: './app.component.html',
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {}

3. Использование библиотеки CSS (Bulma)

Я добавляю Bulma, чтобы ускорить прототипирование разметки внешнего интерфейса за счет наличия минимальной библиотеки CSS, которую легко настраивать с помощью SASS. Чтобы это заработало, добавьте библиотеку в проект:

yarn add bulma

и --dev зависимости для работы с SASS в Electron Webpack:

yarn add --dev sass-loader node-sass

Создайте в src/renderer/app/styles.scss файл базовых стилей, который ссылается на Bulma, например:

// optionally configure variables to customise Bulma
// before importing...
@import "~bulma";
// optionally add extra SASS after importing Bulma

Импортируйте SASS в свое приложение, обновив src/renderer/app/app.component.ts до:

import {Component, ViewEncapsulation} from "@angular/core";

import "./styles.scss";

@Component({
    selector: '#app',
    templateUrl: './app.component.html',
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {}

Повторно запустите Electron Webpack с сервером разработки, выполнив команду:

yarn dev

Вот и все! Простой, минималистичный пример использования Angular 4 с Electron Webpack. Пример кода доступен на GitHub.

Бонус:

Если вы хотите использовать Angular Router, вам необходимо вставить тег <base /> в index.html, созданный Electron Webpack. Вы можете сделать это, добавив следующий код в src/renderer/index.ts непосредственно перед строкой bootstrapModule(AppModule):

const base = document.createElement('base');
base.href = './';
document.head.appendChild(base);