はじめに (対象読者・この記事でわかること)

この記事は、Electron ForgeとVue 3を組み合わせてデスクトップアプリケーション開発を始めたものの、「Electronアプリが起動しない」「真っ白な画面しか表示されない」といった問題に直面している開発者を主な対象としています。

この記事を読むことで、Electron ForgeとVue 3の基本的な連携方法、特にアプリ起動時の一般的なエラーの原因とその効果的な解決策を理解し、スムーズに開発を進められるようになります。Electronのメインプロセスとレンダラープロセスの連携、ビルド設定の調整といった、つまずきやすいポイントに焦点を当てて解説します。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。 * HTML/CSSの基本的な知識 * JavaScript/TypeScriptの基本的な知識 * Vue.jsの基本的な知識 (コンポーネント、ライフサイクルなど) * Node.js/npmの基本的なコマンド操作 * 基本的なターミナル操作

Electron ForgeとVue 3:セットアップの落とし穴

ElectronはJavaScript、HTML、CSSを使ってデスクトップアプリケーションを開発できる強力なフレームワークです。中でも、Electron Forgeはプロジェクトの初期化、開発、ビルド、パッケージングまでをシンプルに管理するためのツールキットとして広く利用されています。一方、Vue 3は軽量かつ高速なフロントエンドフレームワークであり、SPA (Single Page Application) 開発において非常に人気があります。この2つを組み合わせることで、リッチなUIを持つデスクトップアプリケーションを効率的に開発できるため、多くの開発者に選ばれています。

しかし、Electron ForgeとVue 3の組み合わせは、特に初めて利用する際にいくつかの「落とし穴」があります。最もよく報告される問題の一つが、「アプリが起動しない」「真っ白な画面が表示される」といった起動エラーです。これは、Electronのメインプロセス(Node.js環境)とレンダラープロセス(ブラウザ環境でVueアプリが動作)間の連携、そして両者のビルドシステム(特にWebpackやVite)の設定が複雑に絡み合っているためです。

主な原因としては、レンダラープロセスがVueアプリケーションのビルド成果物(index.htmlやバンドルされたJavaScriptファイル)を正しく読み込めないこと、またはWebpack/Viteの設定がElectronの要件と合致していないことが挙げられます。特に、ファイルパスの解決、アセットの参照、そして開発モードと本番モードでの挙動の違いが、多くの開発者を悩ませるポイントとなります。

Vue 3アプリとElectron Forgeの正しい統合手順とエラー解決ガイド

ここでは、Electron ForgeにVue 3アプリケーションを正しく統合し、起動エラーを解決するための具体的な手順と設定について解説します。

ステップ1: Electron Forgeプロジェクトの初期化

まずは、Electron Forgeプロジェクトを初期化します。Vue 3との連携を考慮し、ここではWebpackテンプレートを使用します。(Viteテンプレートでも同様の問題が発生する可能性がありますが、本記事ではWebpackを例に進めます。)

Bash
# プロジェクトディレクトリを作成 mkdir my-electron-vue-app cd my-electron-vue-app # Electron ForgeプロジェクトをWebpackテンプレートで初期化 npm init electron-app@latest . -- --template=webpack # 依存関係をインストール npm install

この段階で一度、Electronアプリが起動するか確認しましょう。

Bash
npm run start

初期状態では、Electronのロゴが表示されたシンプルなウィンドウが起動するはずです。

ステップ2: Electron ForgeへのVue 3の統合

次に、Electron ForgeのレンダラープロセスでVue 3アプリケーションを実行できるように設定します。

  1. Vueと関連する依存関係のインストール: bash npm install vue@next vue-loader@next @vue/compiler-sfc

    • vue@next: Vue 3本体
    • vue-loader@next: WebpackでVue単一ファイルコンポーネント (.vue) を処理するためのローダー
    • @vue/compiler-sfc: Vue単一ファイルコンポーネントをコンパイルするためのコンパイラ
  2. webpack.renderer.config.js の修正: webpack.renderer.config.js は、Electronのレンダラープロセスで動作するアプリケーション(今回の場合はVueアプリ)のビルド設定を定義します。このファイルをVueアプリをバンドルできるように修正します。

    ```javascript const rules = require('./webpack.rules'); const plugins = require('./webpack.plugins');

    // Vue Loader プラグインをインポート const { VueLoaderPlugin } = require('vue-loader');

    rules.push( { test: /.css$/, use: [{ loader: 'style-loader' }, { loader: 'css-loader' }], }, // Vue ファイルを処理するためのルールを追加 { test: /.vue$/, loader: 'vue-loader', } );

    module.exports = { module: { rules, }, plugins: [ ...plugins, // VueLoaderPlugin を追加 new VueLoaderPlugin(), ], resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'], // .vue ファイルを解決できるように拡張子を追加 alias: { 'vue': '@vue/runtime-dom' // Vue 3のバンドルエイリアスを設定 } }, }; ```

  3. Vue アプリケーションのエントリポイントの作成: src/renderer.js をVueアプリケーションのエントリポイントとして使用します。このファイルでVueアプリをマウントします。

    ```javascript // src/renderer.js import { createApp } from 'vue'; import App from './App.vue'; // 後で作成するVueコンポーネント

    // VueアプリのCSSをインポート(必要であれば) import './index.css';

    createApp(App).mount('#app'); ```

  4. Vue コンポーネントの作成: src/App.vue を作成し、シンプルなVueコンポーネントを定義します。

    ```vue

    ```

  5. src/index.html の修正: src/index.html はレンダラープロセスがロードするHTMLファイルです。Vueアプリケーションをマウントする要素 (<div id="app"></div>) が必要です。

    html <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Electron with Vue 3</title> <!-- 必要に応じてスタイルシートをリンク --> <link rel="stylesheet" href="./index.css" /> </head> <body> <!-- Vue アプリケーションがマウントされる場所 --> <div id="app"></div> </body> </html>

これで基本的なセットアップは完了です。再度 npm run start を実行し、Electronアプリが起動し、Vueコンポーネントが表示されるか確認してください。

ハマった点やエラー解決

上記の手順でうまくいかない場合、いくつかの一般的な落とし穴があります。

  1. エラー: A JavaScript error occurred in the main process またはウィンドウが真っ白

    • 原因: レンダーラープロセスが正しくロードされていない、またはVueアプリケーションのJavaScriptファイルがバンドルされていないか、パスが間違っている可能性があります。
    • 具体的なメッセージ例:
      • Failed to load URL: file:///path/to/my-electron-vue-app/.webpack/renderer/main_window/index.html with error: ERR_FILE_NOT_FOUND
      • コンソールに Cannot find module 'vue' のようなエラーが表示される。
    • デバッグ方法:
      • Electron開発者ツールを開く: アプリ起動後に Ctrl+Shift+I (Windows/Linux) または Cmd+Option+I (macOS) で開発者ツールを開き、ConsoleタブやNetworkタブでエラーを確認します。Networkタブで必要なファイル(JS, CSS, HTML)が正しくロードされているか確認します。
      • forge.config.jsrenderer 設定を確認。Webpackが指定されたエントリポイントをバンドルできているか。
      • webpack.renderer.config.jsoutput.publicPath がElectron環境と合致しているか確認(通常はWebpack Forgeのデフォルトで問題ないはずですが、Viteなどではbase: './' が重要)。
  2. エラー: Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type (.vue ファイル関連)

    • 原因: webpack.renderer.config.jsvue-loader が正しく設定されていないか、@vue/compiler-sfc がインストールされていない。
    • 解決策:
      • webpack.renderer.config.jsvue-loader のルールと VueLoaderPlugin が正しく追加されているか確認してください。
      • npm install vue-loader@next @vue/compiler-sfc が完了しているか確認。
  3. エラー: [Vue warn]: Failed to resolve component: App または Could not find root element #app

    • 原因: Vueアプリケーションのエントリポイント (src/renderer.js) で App.vue が正しくインポートされていないか、src/index.html<div id="app"></div> が存在しない、またはIDが間違っている。
    • 解決策:
      • src/renderer.jsimport App from './App.vue'; が正しいパスを指しているか確認。
      • src/index.html<div id="app"></div> があり、src/renderer.jsmount('#app') とIDが一致しているか確認。
  4. 開発モードでは動くが、npm run make でビルドした後に起動しない

    • 原因: 開発モードと本番ビルドでパスの解決方法や環境変数の扱いが異なるため。特にアセットのパス。
    • 解決策:
      • forge.config.js で本番ビルド時の assets パスや publicPath の設定を確認。
      • Vue側(Viteの場合 vite.config.jsbase: './' など)で、ビルド後の相対パス参照を考慮した設定になっているか確認。
      • electron-forge はデフォルトで process.env.NODE_ENVproduction に設定するため、それに応じたパス解決が必要です。

解決策

上記のハマった点のほとんどは、webpack.renderer.config.js の適切な設定と、ファイルパスの整合性を確認することで解決できます。

1. webpack.renderer.config.js の再確認と修正ポイント:

  • rules 配列に .vue ファイルを vue-loader で処理する設定があるか? javascript { test: /\.vue$/, loader: 'vue-loader', }
  • plugins 配列に new VueLoaderPlugin() が含まれているか? javascript const { VueLoaderPlugin } = require('vue-loader'); // ... plugins: [ // ... new VueLoaderPlugin(), ],
  • resolve.extensions.vue が追加されているか? javascript resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'], },
  • Vue 3 の ESM ビルドを解決するための alias が設定されているか? javascript resolve: { // ... alias: { 'vue': '@vue/runtime-dom' // Vue 3のバンドルエイリアス } }, これはVue 3のさまざまなビルド(フルバンドル、ランタイムのみなど)に対応するために必要となることがあります。特にレンダラープロセスがブラウザ環境であることを考慮し、DOMレンダラーを使用するよう指定します。

2. src/renderer.jssrc/App.vue の連携:

  • src/renderer.jsApp.vue が正しくインポートされているか確認 (import App from './App.vue';)
  • src/renderer.jscreateApp(App).mount('#app'); が正しく呼び出されているか確認
  • src/index.htmlid="app" を持つ要素が存在するか確認

3. メインプロセスとレンダラープロセスのパス解決:

src/main.js (または src/index.js) における mainWindow.loadURL() の部分が重要です。 Electron ForgeのWebpackテンプレートを使用している場合、通常は以下のようになります。

Javascript
import { app, BrowserWindow } from 'electron'; // ... const createWindow = () => { const mainWindow = new BrowserWindow({ height: 600, width: 800, webPreferences: { preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY, // Node.jsの機能をレンダラープロセスで利用可能にするか(セキュリティに注意) // nodeIntegration: true, // コンテキスト分離を有効にするか(セキュリティ推奨) // contextIsolation: false, }, }); // MAIN_WINDOW_WEBPACK_ENTRY は webpack.renderer.config.js のバンドル結果を指す mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY); // ... };

MAIN_WINDOW_WEBPACK_ENTRY はElectron ForgeがWebpackを通じて自動的に注入する変数で、レンダラープロセスのエントリポイント(通常はバンドルされたHTMLファイル)のURLを指します。この変数が正しく解決されない場合も起動エラーの原因となります。

ポイント: Electron ForgeのWebpackテンプレートは、レンダラープロセスのバンドルを自動的に適切なパスに配置してくれます。そのため、自分で file://path.join(__dirname, ...) を使ってVueのビルド結果を指す必要はほとんどありません。もし別途Vue CLIやViteで作成したプロジェクトを直接読み込みたい場合は、mainWindow.loadURL() のパスをVueのビルド成果物(例: dist/index.html)を指すように調整する必要がありますが、その場合は webpack.renderer.config.js を使わず、Electron Forgeの plugin-webpack の代わりに plugin-custom などを使うか、Electron ForgeのWebpack設定を深く理解して調整する必要があります。一般的には、本記事で説明したように、Electron ForgeのWebpack設定にVueを直接統合するアプローチが最もシンプルで堅牢です。

まとめ

本記事では、Electron ForgeとVue 3を組み合わせたデスクトップアプリケーション開発において、アプリが起動しないという一般的なエラーに焦点を当て、その原因と具体的な解決策を解説しました。

  • Electron ForgeのWebpack設定 (webpack.renderer.config.js) とVue 3の連携が重要 です。特に vue-loaderVueLoaderPlugin の適切な設定、そして resolve.extensionsalias の調整が成功の鍵となります。
  • メインプロセスとレンダラープロセスのパス解決 を理解し、開発者ツールを活用してエラーを特定することがデバッグにおいて不可欠です。
  • 開発モードと本番ビルドでの挙動の違い を意識し、それぞれで正しく動作するか確認することが、リリースに向けた安定性を確保します。

この記事を通して、Electron ForgeとVue 3のセットアップにおけるつまずきやすい点を克服し、デスクトップアプリケーション開発をスムーズに進められるようになったことでしょう。

今後は、ElectronのIPC通信を用いたメインプロセスとレンダラープロセスの連携、ネイティブモジュールの利用、自動アップデートの実装といった発展的な内容についても記事にする予定です。

参考資料