MidoriPhotArt.
Windowsデスクトップアプリケーションの作成。Javascriptの言語を利用したWindowsのアプリを作成する。Electronを利用。最小構成のWEBアプリ「HalloWorld」を作成します。

Electronを使用したWindows デスクトップアプリ解説

サンプルアプリケーション: midori280\hello-world-app 1.0.0.exe

ここで作成したサンプルの「HelloWorld」コードです。インストール不要の形式になっています。ダウンロードして、実行すれば、表示されます。このサンプルを通じて、Electronアプリケーションの基本的な構造と動作を確認できます。

メインプロセス Node.js 環境 アプリケーションのライフサイクル管理 OS機能へのアクセス レンダラープロセス Chromium 環境 HTML/CSS/JavaScript ユーザーインターフェース IPC (プロセス間通信) メインプロセスとレンダラープロセス間のデータ交換

1. プロジェクトの概要

このプロジェクトはElectronを使用してWindows Storeで配布可能な最小構成のデスクトップアプリケーションを構築します。Electronは、HTML、CSS、JavaScriptを使用してクロスプラットフォームのデスクトップアプリケーションを作成するためのフレームワークです。

2. ファイル構成

最小構成で必要なファイルは以下の通りです:

  • package.json - プロジェクトの依存関係と設定を定義
  • main.js - アプリケーションのメインプロセス(Electronのエントリーポイント)
  • index.html - ユーザーインターフェース(レンダラープロセスの内容)
📁 hello-world-app/ 📄 package.json - プロジェクト設定と依存関係 📄 main.js - メインプロセス (Node.js) 📄 index.html - レンダラープロセス (UI) 📁 node_modules/ - 依存パッケージ

package.json

{
  "name": "hello-world-app",
  "version": "1.0.0",
  "description": "Hello World Windows デスクトップアプリ",
  "main": "main.js",  // メインプロセスのエントリーポイント
  "scripts": {
    "start": "electron .",  // 開発モードで実行
    "build": "electron-builder"  // ビルド用コマンド
  },
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "electron": "^25.0.0",  // Electronフレームワーク
    "electron-builder": "^24.4.0"  // ビルドツール
  },
  "build": {
    "appId": "com.example.helloworld",
    "win": {
      "target": "appx"  // Windows Store配布用フォーマット
    }
  }
}

package.jsonには、アプリケーションの情報、依存関係、スクリプトが含まれています。特に重要な点:

  • main: アプリケーションのエントリーポイントを指定
  • scripts: 開発とビルドのためのコマンド
  • devDependencies: 開発に必要なパッケージ
  • build: Windows Storeパッケージング用の設定

main.js

// Electronモジュールの読み込み
const { app, BrowserWindow } = require('electron')
const path = require('path')

// ウィンドウを作成する関数
function createWindow() {
  // メインウィンドウの設定
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,  // Node.js機能の統合
      contextIsolation: false // コンテキスト分離を無効化
    }
  })

  // index.htmlをロード
  mainWindow.loadFile('index.html')
  
  // 開発ツールを開く場合(開発時のみ)
  // mainWindow.webContents.openDevTools()
}

// Electron初期化完了時のイベント
app.whenReady().then(() => {
  createWindow()
  
  // macOSでの処理:ドックアイコンクリック時の動作
  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// すべてのウィンドウが閉じられたときの処理
app.on('window-all-closed', function () {
  // macOS以外ではアプリを終了
  if (process.platform !== 'darwin') app.quit()
})

main.jsは、アプリケーションのメインプロセスを制御します:

  • BrowserWindowのインスタンスを作成してアプリウィンドウを定義
  • HTML、CSS、JavaScriptを使ったUIをウィンドウに読み込み
  • アプリケーションのライフサイクルイベントを管理
アプリ起動 app.whenReady createWindow ウィンドウ表示 window-all-closed イベント アプリ終了

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Hello World</title>
  <style>
    /* ----------------
     * スタイル定義
     * ---------------- */
    body {
      font-family: 'Segoe UI', sans-serif;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
      background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
      color: #fff;
      overflow: hidden;
    }
    
    .container {
      text-align: center;
      padding: 2rem;
      border-radius: 12px;
      background: rgba(255, 255, 255, 0.1);
      backdrop-filter: blur(10px);
      box-shadow: 0 15px 25px rgba(0, 0, 0, 0.2);
      animation: fadeIn 1s ease-out;
    }
    
    h1 {
      font-size: 4rem;
      font-weight: 700;
      margin-bottom: 1rem;
      background: linear-gradient(45deg, #ff6b6b, #ffb347, #2ecc71);
      -webkit-background-clip: text;
      background-clip: text;
      color: transparent;
    }
    
    /* アニメーション定義 */
    @keyframes fadeIn {
      from { opacity: 0; transform: translateY(-20px); }
      to { opacity: 1; transform: translateY(0); }
    }
  </style>
</head>
<body>
  <!-- メインコンテンツ -->
  <div class="container">
    <h1>Hello World</h1>
    <p>モダンなElectronアプリへようこそ</p>
    <button class="btn">はじめる</button>
    <button class="btn">詳細</button>
  </div>

  <script>
    // ボタンクリック時の処理
    document.querySelectorAll('.btn').forEach(button => {
      button.addEventListener('click', function() {
        alert('ボタンがクリックされました!');
      });
    });
  </script>
</body>
</html>

index.htmlは、レンダラープロセスで表示されるユーザーインターフェースを定義します:

  • HTML要素を使用してUI構造を構築
  • CSSを使用してスタイリング
  • JavaScriptを使用して動的な機能を追加

3. 技術スタックの解説

Electronとは?

Electronは、GitHubが開発したオープンソースフレームワークで、JavaScriptやHTML、CSSなどのウェブ技術を使ってクロスプラットフォームのデスクトップアプリケーションを開発できます。内部的には:

  • Chromium: Googleのオープンソースブラウザエンジンを使用してUIをレンダリング
  • Node.js: JavaScriptをデスクトップ環境で実行し、OSレベルの機能にアクセス

重要: ElectronアプリケーションはWeb技術で作られていますが、ブラウザの制限を受けずにファイルシステムやOSの機能にアクセスできます。これがElectronの最大の強みです。

// Electronの主要コンポーネント概要
// -------------------------------------
// 1. メインプロセス (Node.js環境)
//    - アプリケーションの起動と終了を管理
//    - OSとの連携機能を提供
//    - レンダラープロセスを作成・管理

// 2. レンダラープロセス (Chromium環境)
//    - UIをレンダリング
//    - ユーザーインタラクションを処理
//    - ウェブ技術(HTML/CSS/JS)を使用

// 3. プロセス間通信(IPC)
//    - メインプロセスとレンダラープロセス間のデータやり取り
const { ipcMain } = require('electron');
ipcMain.on('非同期メッセージ', (event, arg) => {
  console.log(arg); // "ping"などのメッセージ
  event.reply('非同期レスポンス', 'レンダラーへの返信');
});

5. デスクトップアプリの配布形式

Electronアプリケーションは様々な形式で配布できます。配布形式によって、インストール方法やユーザー体験が異なります。

Windows向け配布形式

  • NSIS (.exe): 従来のWindowsインストーラー
    • メリット: ほとんどのユーザーに馴染みがある、カスタマイズ性が高い
    • デメリット: 管理者権限が必要な場合がある
    • 設定例: "win": {"target": "nsis"}
  • Portable (.exe): インストール不要の実行ファイル
    • メリット: インストール不要、USBメモリなどで持ち運び可能
    • デメリット: 設定が保存されにくい、関連付けができない
    • 設定例: "win": {"target": "portable"}
  • AppX/MSIX (.appx/.msix): Windows Store用パッケージ
    • メリット: Windows Storeでの配布、自動更新、サンドボックス化
    • デメリット: Microsoft開発者アカウントが必要、審査プロセスがある
    • 設定例: "win": {"target": "appx"}
  • Squirrel (.exe): 自動更新機能付きインストーラー
    • メリット: 自動更新機能が組み込まれている
    • デメリット: 設定が複雑
    • 設定例: "win": {"target": "squirrel"}

Windows Store (AppX/MSIX) 配布の詳細

Windows Storeでの配布は以下の手順が必要です:

  1. 開発者登録: Microsoft Partner Centerに登録(個人:$19、企業:$99)
  2. アプリ証明書の取得: Windows開発者アカウントから証明書を取得
  3. アプリのパッケージング: electron-builderでAppX/MSIXパッケージを作成
  4. アプリの提出: Partner Centerからアプリを提出し審査を受ける

注意点: Windows Storeアプリは、通常のElectronアプリよりも制限が多いです。ファイルシステムへのアクセスやシステム機能の利用に制限があります。

複数の配布形式を同時に作成

"build": {
  "appId": "com.example.helloworld",
  "win": {
    "target": [
      {
        "target": "nsis",
        "arch": ["x64", "ia32"]
      },
      {
        "target": "portable",
        "arch": ["x64"]
      },
      {
        "target": "appx",
        "arch": ["x64"]
      }
    ]
  }
}

6. ターミナルコマンド詳細ガイド

Electronアプリの開発には様々なコマンドを使用します。ここでは、プロジェクト初期化から実行、ビルドまでの詳細なコマンド解説を提供します。

npmとnpxの基本概念

npm (Node Package Manager): Node.jsのパッケージ管理ツールで、以下の機能を提供します:

  • パッケージのインストールと管理
  • 依存関係の解決
  • スクリプトの実行(package.jsonのscriptsセクションで定義)

npx: npm 5.2.0以降に同梱されているツールで、以下の特徴があります:

  • インストールせずにパッケージを一時的に実行できる
  • ローカルにインストールされたパッケージをパスを気にせず実行できる
  • 特定バージョンのパッケージを指定して実行できる

npm vs npx の使い分け:

  • npm: パッケージのインストール、アンインストール、スクリプト実行に使用
  • npx: インストールされたパッケージのコマンドライン実行や、一時的なパッケージ実行に使用

プロジェクト初期化

# 新しいディレクトリを作成
mkdir midori280\win_desktop_app
cd midori280\win_desktop_app

# プロジェクトを初期化(対話形式でpackage.jsonを作成)
npm init

# 全ての質問にデフォルト値を使用する場合
npm init -y

npm initを実行すると、対話形式でプロジェクト名、バージョン、説明などを入力できます。-yフラグを付けるとデフォルト値で自動作成されます。このコマンドは、プロジェクトのルートディレクトリにpackage.jsonファイルを生成します。

依存関係のインストール

# Electronをインストール(開発依存として)
npm install electron --save-dev

# ビルドツールをインストール
npm install electron-builder --save-dev

# 特定バージョンを指定する場合
npm install electron@25.0.0 --save-dev

# 全ての依存関係を一度にインストール(package.jsonに基づく)
npm install

依存関係はpackage.jsonファイルに保存されます。--save-devフラグは開発時のみ必要なパッケージを指定します。

フラグの詳細説明:

  • --save または -S: 通常の依存関係として追加(本番環境でも必要)
  • --save-dev または -D: 開発依存関係として追加(開発時のみ必要)
  • --global または -g: グローバルにインストール(全プロジェクトで使用可能)
  • --exact または -E: 正確なバージョンを指定(^や~を使わない)

開発中のアプリ実行

# package.jsonのscriptsで定義された"start"コマンドを実行
npm start

# または直接Electronを実行
npx electron .

# 開発者ツールを自動的に開く場合
npx electron . --dev

# ホットリロードで開発(electron-reloaderが必要)
npm install electron-reloader --save-dev
# そして以下をmain.jsに追加:
# try { require('electron-reloader')(module); } catch {}

npm startpackage.jsonscriptsセクションで定義された"start"コマンドを実行します。npxコマンドは、ローカルにインストールされたパッケージを直接実行するためのものです。

コマンドの詳細説明:

  • npm start: package.jsonのscriptsセクションで定義された"start"コマンドを実行します。通常は"electron ."が設定されています。
  • npx electron .: カレントディレクトリをElectronアプリとして実行します。.はカレントディレクトリを指します。
  • --devフラグ: 開発者向けの設定を有効にします。多くの場合、開発者ツールが自動的に開きます。

electron-reloader: このパッケージを使用すると、ソースコードの変更を検出して自動的にアプリを再起動します。開発効率が大幅に向上します。

アプリのビルド

# package.jsonのscriptsで定義された"build"コマンドを実行
npm run build

# または直接electron-builderを実行
npx electron-builder

# 特定のプラットフォーム向けにビルド
npx electron-builder --windows
npx electron-builder --mac
npx electron-builder --linux

# 特定のターゲット形式を指定
npx electron-builder --win --x64 --ia32
npx electron-builder --win nsis:ia32 portable:ia32

ビルドコマンドは、配布可能なパッケージ(.exe、.dmg、.appxなど)を作成します。ビルド設定はpackage.jsonbuildセクションで構成できます。

electron-builderのオプション詳細:

  • --windows/--win: Windows向けビルドを実行
  • --mac: macOS向けビルドを実行
  • --linux: Linux向けビルドを実行
  • --x64: 64ビットアーキテクチャ向けにビルド
  • --ia32: 32ビットアーキテクチャ向けにビルド
  • --arm64: ARM64アーキテクチャ向けにビルド
  • --dir: パッケージングせずにビルド結果をディレクトリに出力
  • --publish: ビルド後に自動公開(例: --publish always

ビルドターゲットの詳細:

  • nsis: Windows用インストーラー(.exe)
  • portable: ポータブル版(インストール不要の.exe)
  • appx: Windows Store用パッケージ(.appx)
  • msi: Microsoft Installer形式(.msi)
  • dmg: macOS用ディスクイメージ(.dmg)
  • deb: Debian/Ubuntu用パッケージ(.deb)

その他の便利なコマンド

# パッケージの更新
npm update

# 脆弱性のチェック
npm audit

# パッケージの脆弱性を修正
npm audit fix

# 未使用の依存関係を検出
npm prune

# package.jsonの依存関係のリスト表示
npm ls --depth=0

# グローバルにインストールされたパッケージのリスト
npm list -g --depth=0

パッケージングのトラブルシューティング

# ビルドキャッシュをクリア
npx electron-builder cache clear

# 詳細なログ出力を表示
npx electron-builder --win --x64 --ia32 --debug

# node_modulesを再インストール(問題解決のため)
rm -rf node_modules
rm package-lock.json
npm install

注意: Windows環境では rm -rf ではなく rmdir /s /q node_modulesdel package-lock.json を使用してください。

7. 開発ステップバイステップ

  1. 環境セットアップ: Node.jsとnpmをインストール
  2. プロジェクト作成: プロジェクトフォルダを作成し、必要なファイルを作成
  3. 依存関係のインストール: npm installを実行して必要なパッケージをインストール
  4. 開発とテスト: npm startでアプリケーションを実行してテスト
  5. ビルド: npm run buildでWindowsパッケージを生成
  6. デプロイ: 生成されたパッケージを配布
# プロジェクト作成からビルドまでの完全なコマンド例
# -------------------------------------

# 1. プロジェクトディレクトリの作成
mkdir midori280\win_desktop_app
cd midori280\win_desktop_app

# 2. プロジェクトの初期化
npm init -y

# 3. package.jsonを編集(スクリプトとビルド設定を追加)
# エディタでpackage.jsonを開き編集

# 4. 必要な依存関係をインストール
npm install electron electron-builder --save-dev

# 5. main.jsとindex.htmlを作成
# エディタでファイルを作成

# 6. 開発中のアプリを実行(テスト)
npm start

# 7. Windowsアプリとしてビルド
npm run build

# 8. 生成されたアプリを確認
# dist/win-unpacked/hello-world-app.exeを実行
# または、dist/*.exeインストーラーを実行

8. 発展的なトピック

アプリの機能拡張

  • 複数ウィンドウの管理
  • Inter-Process Communication (IPC)を使用したプロセス間通信
  • ネイティブメニューやトレイアイコンの実装
  • 自動アップデートの仕組み

パフォーマンス最適化

  • アプリケーションのバンドルサイズの最適化
  • メモリ使用量の管理
  • 起動時間の短縮テクニック
// 発展的な機能の例:トレイアイコンの実装
// ------------------------------
const { app, Tray, Menu } = require('electron');
const path = require('path');

let tray = null;

app.whenReady().then(() => {
  // トレイアイコンを作成
  tray = new Tray(path.join(__dirname, 'icon.png'));
  
  // トレイのコンテキストメニューを設定
  const contextMenu = Menu.buildFromTemplate([
    { label: 'アプリを表示', click: () => { /* ウィンドウを表示 */ } },
    { type: 'separator' },
    { label: '設定', click: () => { /* 設定画面を開く */ } },
    { type: 'separator' },
    { label: '終了', click: () => { app.quit(); } }
  ]);
  
  tray.setToolTip('Hello World App');
  tray.setContextMenu(contextMenu);
});

まとめ

Electronを使用することで、Web開発のスキルを活かしながらデスクトップアプリケーションを開発できます。このチュートリアルで紹介した最小構成は、多様なデスクトップアプリケーションの開発の出発点となります。適切な配布形式を選択し、環境を正しく構築することで、効率的な開発が可能になります。