Electron BrowserViewについてサンプルを読みつつ紹介

本記事では、ElectronのBrowserViewについてサンプルを読みつつ紹介します。
Electronは他のネイティブアプリと比べてWebアプリと連携するアプリが作りやすいので、Node.jsを使っている人はぜひ触ってみてください。

# Electronとは
ネイティブアプリケーションをWeb技術（HTML/JavaScript/CSS)で作るためのフレームワークです。
ネイティブアプリ特有の処理（ファイルアクセスなど）をNode.jsのメインプロセスが受け持ち、画面表示をHTML/JavaScript/CSSが受け持つという構造になっています。レンダラーにはChromiumが使われているので、JS対応状況に悩むことはほぼないです。
![Electronのアーキテクチャ](https://qiita-image-store.s3.amazonaws.com/0/153576/63c63e25-cb09-de41-11a8-8d3181f0712a.png "Electronのアーキテクチャ")
図１　Electronのアーキテクチャ

# BrowserViewとは
アプリウィンドウにWebコンテンツを埋め込むために使うモジュールです。Electronプロジェクトの一部として開発されています。
Webコンテンツ埋め込みには元々webviewというタグが使われていたのですが、バグの解決がChromium依存のため問題があってもElectron側としては修正を待つしかなく、ElectronプロジェクトとしてWebコンテンツ埋め込み機能を開発していくことになったようです。

参考　https://www.figma.com/blog/introducing-browserview-for-electron/

# BrowserViewの公式サンプル
公式サンプルはなぜか```app.on('ready')```が書かれていないためそのままだと動きません。以下のようにして、```npm start```で実行しましょう。

```json:package.json
{
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  }
}
```

```javascript:main.js
const {app, BrowserView, BrowserWindow} = require('electron')

app.on('ready', () => {
  let win = new BrowserWindow({width: 800, height: 600})
  win.on('closed', () => {
    win = null
  })

  let view = new BrowserView({
    webPreferences: {
      nodeIntegration: false
    }
  })
  win.setBrowserView(view)
  view.setBounds({ x: 0, y: 0, width: 300, height: 300 })
  view.webContents.loadURL('https://electronjs.org')
})
```

すると以下のようなウィンドウが出てきます。
![実行結果](https://qiita-image-store.s3.amazonaws.com/0/153576/478124ba-892b-e68c-df64-1416afd330ca.jpeg)
ウィンドウの一部だけにウェブページが表示されています。ウィンドウのサイズを変えても表示位置は変わりません。
ウィンドウサイズに合わせて表示したり、サイズを変えたら表示が変わったりしてほしいですね。

[ドキュメント](https://electronjs.org/docs/api/browser-view)を見るとview.setAutoResizeというが分かるので使ってみましょう。以下の１行を追加します。

```
view.setAutoResize({width: true, height: true})
```

すると以下のようになります。画面サイズ変更に合わせて表示の大きさが変わっていますね。
![setAutoResize](https://qiita-image-store.s3.amazonaws.com/0/153576/463dfddc-3371-b66f-2576-c3486880922c.jpeg)

また、setBoundsにウィンドウサイズを指定することでウィンドウいっぱいに表示できます。
※スクロールバーがウィンドウの外に隠れてしまっています。自動調整とかしてほしいですが、そういった機能は見つかりませんでした。

![WS000896.JPG](https://qiita-image-store.s3.amazonaws.com/0/153576/1db186da-e105-601c-0959-47877deb6bba.jpeg)

## 現状できないこと
1. スクロールバーを意識した表示サイズ調整
1. １つのBrowserWindowに複数のBrowserViewを表示する  
setBrowserViewにはBrowserViewを１つ指定できるだけで、一度BrowserViewをセットしてから別のBrowserViewをセットすると、最初にセットしたBrowserViewは表示されなくなってしまいます。

# 最後に
ネイティブアプリケーションをWeb技術（HTML/JavaScript/CSS)で作るためのElectronと、アプリウィンドウにWebコンテンツを埋め込むためのBrowserViewを紹介しました。
BrowserViewでできることはまだ少ないようですが、これからの開発が期待されますね。個人的には、１つのBrowserWindowに複数のBrowserViewを表示できるようにしてほしいです。

以下に本記事で作ったソースを置いておきます。

```javascript:main.js
const { app, BrowserView, BrowserWindow } = require('electron')

app.on('ready', () => {
    let width = 800
    let height = 600
    let win = new BrowserWindow({ width: width, height: height })
    win.on('closed', () => {
        win = null
    })

    let view = new BrowserView({
        webPreferences: {
            nodeIntegration: false
        }
    })
    win.setBrowserView(view)
    view.setBounds({ x: 0, y: 0, width: width, height: height })
    view.webContents.loadURL('https://electronjs.org')
    view.setAutoResize({ width: true, height: true })
})
```

追記
複数のBrowserViewが作れるようになったようです
https://electronjs.org/docs/api/browser-window#winaddbrowserviewbrowserview-experimental