すでに Angular プロジェクトが作成されているものとする
参考サイト
環境
Angular バージョン
ng version
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 12.2.10
Node: 14.15.1
Package Manager: npm 8.1.0
OS: darwin x64
Angular: 12.2.10
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, localize, material, platform-browser
... platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1200.5
@angular-devkit/build-angular 12.2.10
@angular-devkit/core 12.0.5
@angular-devkit/schematics 12.2.10
@angular/fire 6.1.5
@schematics/angular 12.2.10
rxjs 6.6.7
typescript 4.3.5
モジュールの追加
@types/node
を新しいバージョンに上げておく
"@types/node": "^14.15.5",
Angular12 で electron を実装するのに必要なモジュールを追加する
package.json
"dependencies" or "devDependencies": {
...
"ngx-electron": "^2.2.0",
"ts-loader": "^9.2.5",
"concurrently": "^6.2.1",
"electron": "^13.2.0",
"electron-log": "4.4.1",
"electron-packager": "^15.3.0",
"webpack-cli": "^4.8.0",
"webpack-node-externals": "^3.0.0"
}
webpack.**.config.js の追加
webpack.electron.config.js
const path = require('path');
const { ProgressPlugin } = require('webpack');
const src = path.join(process.cwd(), 'src', 'electron');
module.exports = {
resolve: {
extensions: [
'.ts',
'.js'
]
},
entry: {
main: path.join(src, 'main.ts')
},
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader',
options: {
configFile: path.join(src, 'tsconfig.json')
}
}
]
},
plugins: [
new ProgressPlugin()
],
// indicates that transpilation code is to be run in the main process
target: 'electron-main'
};
webpack.electron.dev.config.js
const path = require('path');
const baseConfig = require('./webpack.electron.config');
module.exports = {
...baseConfig,
mode: 'development',
devtool: 'source-map',
output: {
path: path.join(process.cwd(), 'dist'),
// avoid conflicts with the `main.js` file generated from the Angular CLI
filename: 'shell.js'
}
};
webpack.electron.prod.config.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const baseConfig = require('./webpack.electron.config');
module.exports = {
...baseConfig,
mode: 'production',
output: {
path: path.join(process.cwd(), 'dist'),
filename: 'main.js'
},
plugins: [
// the electron-packager requires a valid `package.json` file along with the Electron code
new CopyWebpackPlugin({
patterns: [
{
context: path.join(process.cwd(), 'src', 'electron'),
from: 'package.json'
}
]
})
],
// Indicate that we do not want to bundle modules from 3rd party libraries automatically, as part of ES6 imports.
// Instead we must define them in the `dependencies` property of the `package.json` file and will be installed
// using the `package` npm script
externals: [nodeExternals()]
};
npm run の スクリプトを追加
package.json
"scripts": {
...
"build:dev": "concurrently \"ng build --delete-output-path=false --watch\" \"webpack --config webpack.electron.dev.config.js --watch\"",
"start:dev": "electron dist/shell.js",
"build:prod": "ng build --optimization --outputHashing=all --sourceMap=false --namedChunks=false --extract-licenses --vendorChunk=false --build-optimizer && webpack --config webpack.electron.prod.config.js",
"start:prod": "electron dist/main.js"
}
テストする時は
For the desktop version run:
npm run build:dev
npm run start:dev
electron 起動用の main.ts を用意する
src/electron/main.ts
import { app, BrowserWindow, ipcMain, dialog } from 'electron';
import * as fs from 'fs';
import log from 'electron-log';
log.info(`${app.name} ${app.getVersion()}`);
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
mainWindow.maximize();
mainWindow.webContents.openDevTools();
mainWindow.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow();
});
// Angular -> Electron
ipcMain.on('selectPirate', async (event: Electron.IpcMainEvent, name: string) => {
await dialog.showMessageBox({ message: 'You selected: ' + name });
event.returnValue = true;
});
src/electron/package.json
{
"name": "angular-electron-sample",
"description": "Angular Electron Sample",
"version": "0.0.0",
"author": {
"name": "Aristeidis Bampakos"
},
"main": "main.js",
"dependencies": {
"electron-log": "4.3.1"
}
}
src/electron/tsconfig.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"importHelpers": false
},
"include": [
"**/*.ts"
]
}
テスト
ビルドしてみる
build:dev
最後フリーズした状態になるけど気にせず ctrl+c で強制終了する
起動してみる
start:dev
Electron用の動作 を Angule アプリに追加する
app.module に追加
src/app/app.module.ts
import { ElectronService, NgxElectronModule } from "ngx-electron";
...
@NgModule({
imports: [
NgxElectronModule
],
providers: [
ElectronService
]
electron を使うコンポーネントに追加
**.component.ts
import { ElectronService } from 'ngx-electron';
constructor(
public electronService: ElectronService
) {}
// electron を使う関数
public use_electron(): void{
if(this.electronService.isElectronApp) {
this.electronService.ipcRenderer.sendSync('selectPirate', 'hogehoge');
}
}
おわりに
Angular 12 では なかなか情報がみつからなかったので書きました