Electronはどういうものなのかと実際に簡単な例題を作ってみる。
npm i -g electron-prebuilt
electron-prebuilt
は土台である。これを設置したらElectronのスクリプトを簡単に実行することができる。
main.js
という名前でファイルを生成する
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
var mainWindow = null
app.on('window-all-closed', function () {
app.quit()
})
app.on('ready', function () {
mainWindow = new BrowserWindow({width: 800, height: 600})
mainWindow.loadURL('file://' + __dirname + '/index.html')
mainWindow.on('closed', function () {
mainWindow = null
})
})
Electronが提供しているAPIはrequire('electron')
から利用できる。
OSごとのAPIもかなり一般化されていてわかりやすくまとまっているので、
特殊な場合じゃなかったら、これだけですべての制御ができる。
app
はOSでのアプリ自体の動きに関与する。EventListener
であり、主にApplication自体で起きるイベントを受け取ったりする。
Chrome自体だと思ったらわかりやすいかも
BrowserWindow
はChromeの一つ一つのWindowである。これは必ずapp
のready
イベント以降から使うことができる。
その以前にするとエラーが出る。
これもEventListener
であり、Window自体に起きるイベントを受け取ったりする。
#loadURL
メッソドは見てわかるようにそのURLであるページをBrowserWindow
から開いてくれる。これをみるとHTMLファイルを書く必要が有るのかがわかると思う。では、ささっと書いてみよう
index.html
をつくる。
<!DOCTYPE html>
<html>
<head>
<title>This is my first app</title>
<meta charset="utf-8">
</head>
<body>
<h1>最初のアプリ</h1>
<a href='another.html'>他のページ</a>
<a href='https://github.com'>Github</a>
</body>
</html>
普通のHTMLと全く差がない。続いてanother.html
もつくる。
<!DOCTYPE html>
<html>
<head>
<title>他のページ</title>
<meta charset="utf-8">
</head>
<body>
<a id='backButton' href>戻る。</a>
<script>
var backButton = document.getElementById('backButton')
backButton.addEventListener('click', function (e) {
e.preventDefault()
history.back()
})
</script>
</body>
</html>
同じく純粋なHTMLで書かれている。
では、起動してみよう
electron-prebuilt
を-g
でちゃんと設置したら、ターミナルからelectron
という命令が使える。これを使ってmain.js
を起動してみる。
electron main.js
終了は普通にバツを押してもいいし、ターミナルから
Ctrl + C
を押してもいい
実行してみると、問題が一個問題があるのがわかると思う。another.html
に飛ぶリンクと戻るリンクは普通に働くが、github.com
に行くリンクを押すと、最初のページに戻る方法がない。
とりあえず、ここまで使ってみるとBrowserと全く同じであることがわかると思う。
Cmd + Alt + I
を押してみるとChromeのdevtoolもでる、、
では、次はBrowserとどういう差があるのかを見せる。
github.com
へのリンクを押してしまうと、どうしようもなくなる問題を解決してみよう。先話したようにelectron
はOSのAPIをjavascriptだけで使うことができる。なので、ユーザの基本Browserからあるリンクを開くこともできる。
では、やってみよう。
index.html
を次のように書き直す。
<!DOCTYPE html>
<html>
<head>
<title>This is my first app</title>
<meta charset="utf-8">
</head>
<body>
<h1>最初のアプリ</h1>
<a href='another.html'>他のページ</a>
<a id='externalLink' href='https://github.com'>Github</a>
<script>
const electron = require('electron')
const shell = electron.shell
var externalLink = document.getElementById('externalLink')
externalLink.addEventListener('click', function (e) {
e.preventDefault()
shell.openExternal(e.target.href)
})
</script>
</body>
</html>
BrowserでもCommonJSのrequire
が使える。これを使えば、Nodeのmoduleも普通に呼べる。次にやってみる。
普通にダブルクリックするときの機能などがまとまっている。
今回使ったopenExternal
はあるURLを開くためのメッソードで、それ以外には、普通にWordファイル(*.docx)をMS Office wordやPagesから開いたり、あるフォルダーをFinder(あるいはExplorer)から開くことができる。
では、ElectronとNodeのnative moduleを利用して簡単な機能を作ってみよう。
次のようにindex.html
書き直す。
<!DOCTYPE html>
<html>
<head>
<title>This is my first app</title>
<meta charset="utf-8">
</head>
<body>
<textarea id='textBox'>
</textarea>
<script>
const electron = require('electron')
const remote = electron.remote
const fs = require('fs')
const path = require('path')
var desktopPath = remote.app.getPath('desktop')
var textBox = document.getElementById('textBox')
textBox.addEventListener('keyup', function (e) {
fs.writeFileSync(path.join(desktopPath, 'hello.txt'), this.value)
})
</script>
</body>
</html>
簡単に説明をすると、<textarea>
に何かを書いたらそれをDesktopフォルダーのhello.txt
というファイルに書き込むアプリである。
個人的には
<script>
タグの中でNodeJSがそのまま使えるのがすごくショックだった。
remote
はBrowserWindowだけで使えるmoduleである。実はBrowserWindowで使われているJavascriptと最初書いたmain.js
は同じProcessではない。
BrwoserWindowのProcessはこれからRenderer processと呼ぶ
なので、main.js
で使ったapp
を呼びだそうとしても、Renderer processからはelectron.app
が存在しない。この時remote
を使ったら簡単にMain processのModuleを呼び出すことができる。
実はMain processのmoduleを呼び出しているんじゃなくて、IPC(Inter process communication)を利用して、遠隔でMain processにやらせている感じである。