Electron WebView のデバッグで DevTools を使う

Electron での開発で自分で作ったアセット (HTML / JavaScript / CSS) を WebView で表示することはあまりないと思いますが、アプリの構造上 WebView を使う必要がある場合、困るのは Main Wndow 用の DevTools では WebView コンテンツの JavaScript デバッグとか DOM のインスペクトができないことです。

WebView には openDevTools メソッドがあり専用の DevTools を起動できます。WebView のdom-ready イベントで使うと別ウインドウで上がってきます。

const webview = document.querySelector('webview');
webview.addEventListener('dom-ready', () => {
  webview.openDevTools();
});

開発時 (Electron アプリがパッケージングされていない時) だけ DevTools を起動したい場合、App モジュールの isPackaged を使って判定ができます。DEBUG モードのように使えるわけです。App モジュールは main process で使うもので renderer process では require しても取れませんが Remote モジュール経由で使えます。

const {app} = require("electron").remote;

const webview = document.querySelector('webview');
webview.addEventListener('dom-ready', () => {
  if (!app.isPackaged) {
    webview.openDevTools();
  }
});

f:id:kondoumh:20190517204717p:plain

これで DevTools が使えるようになりましたが、毎回オープンするのはウザいので開発時だけ表示するメニューを用意して、そこから起動できるようにします。

main process では メニュー構築用のテンプレートにパッケージングされていない場合のみ Debug メニューを追加します。このメニューには強制リロードと Main Window 用のサブメニューも role で追加しておくと便利です。

  const template = [
    {
      // snip
    }
  ];

  if (!app.isPackaged) {
    template.unshift({
      label: "Debug",
      submenu: [
        { role: "forceReload"},
        { role: "toggledevtools" },
        { 
          label: "open devTools for WebView",
          click () {
            mainWindow.webContents.send("openDevTools");
          }
        }
      ]
    });
  }

f:id:kondoumh:20190517204817p:plain

renderer process では コマンドに応じて WebView の openDevTools を呼びます。

ipcRenderer.on("openDevTools", () => {
  const webview = document.querySelector('webview');
  webview.openDevTools();
});

これで必要時だけ DevTools を起動できて Remote モジュール使わなくてよくなりました。