HTMLやJavaScriptだけでPC用のアプリが作成できるツールはいくつかありますが、その中でもVisualStudioCodeやSlackなどの実績があるElectronは検討候補から外せないでしょう。
1つのソースコードで複数のプラットフォーム用のアプリを同時に開発できるのは非常に魅力的です。 今回はElectronでHelloWolrd的なアプリを作成し、実際にWindowsやmacOSで動作する実行可能なファイルを作成するところまでをまとめてみます。
- Electronのチュートリアルを試す
- 実行可能なファイルを作成する - electron-packager編
- 実行可能なファイルを作成する - electron-builder編
- 今回のソースコード
- まとめ
- 参考ページ
Electronのチュートリアルを試す
環境の確認
Node.jsが入っていない場合は公式サイトからダウンロード、インストールします。LTS版でも最新版でもどちらでも動きます。 https://nodejs.org/ja/nodejs.org
手元の環境は以下のようになっていたのでこのまま行きます。
$ node --version v12.16.2 $ npm --version 6.14.8
初期設定
Node.jsのプロジェクトを始めるときと同様に、適当なディレクトリを作成し移動、npm init
します。今回はチュートリアルを実施するだけなので設問項目はすべてエンターキー連打で構いません。
$ mkdir 1stapp; cd 1stapp $ npm init
npm init
で作成されたpackage.jsonを開き7行目の内容を追加します。面倒な場合は省略しても構いません。
{ "name": "1stapp", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start":"electron .", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
最後にElectronそのものをインストールします。ぼちぼち大きなファイルが落ちてきますので時間がかかります(インストール後のnode_modulesフォルダは190Mほどでした)
$ npm install --save-dev electron
ソースコード
今回はElectronの公式サイトにある内容をほぼそのまま利用します。
index.js
アプリの「側」になります。ウィンドウを開いたり、ウィンドウを閉じた際の挙動を制御します。
const { app, BrowserWindow } = require('electron') /** * ウィンドウを作成する */ function createWindow () { // ウィンドウを新たに開く const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }) // ファイルを開く win.loadFile('index.html') } // 初期化が終了したらウィンドウを新規に作成する app.whenReady().then(createWindow) // すべてのウィンドウが閉じられたときの処理 app.on('window-all-closed', () => { // macOS以外はアプリを終了する if (process.platform !== 'darwin') { app.quit() } }) // アプリがアクティブになった時の処理 // (macOSはDocのアイコンがクリックされたとき) app.on('activate', () => { // ウィンドウがすべて閉じられている場合は新しく開く if (BrowserWindow.getAllWindows().length === 0) { createWindow() } })
index.html
ウィンドウ内に表示する内容です。こちらは公式ドキュメントそのまま。通常のWebブラウザ用のHTMLと変わりませんが、JavaScript内でprocess
というグローバル変数(オブジェクト)が利用されているのがわかりますね。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hello World!</title> <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" /> </head> <body> <h1>Hello World!</h1> We are using node <script>document.write(process.versions.node)</script>, Chrome <script>document.write(process.versions.chrome)</script>, and Electron <script>document.write(process.versions.electron)</script>. </body> </html>
metaタグのContent-Security-Policy
はその名の通りセキュリティ関連の設定を行うものです。ここではJavaScriptが実行可能な場所を同じオリジン(アプリ内のJSファイル)、HTML内のscriptタグなどでの実行を許可しつつ、onclick=""
などタグの属性での実行は禁止しています。
実行する
開発用に現在の状態を確認するために実行をしてみます。
$ npm start
以下のようにウィンドウが立ち上がり、index.html
の内容が表示されました。
Windowsでも同様の結果が確認できます。
実行可能なファイルを作成する - electron-packager編
npm start
ではデバッグ用にパパっと表示することができますが、このままの状態では配布することができません。そこでElectron Packagerを利用し、WindowsやmacOSで起動することができるアプリを生成します。
※詳しくは後述しますが、2020年現在では後継のelectron-builderの方が機能も充実しており支持を集めているようです。特にpackagerにこだわりがない場合は次のelectron-builderの章をご覧いただくのが良いかと思います。
インストール
先ほどの1stapp
フォルダで以下のコマンドを実行します。
$ npm install --save-dev electron-packager
生成する
以下を実行すると「sample-darwin-x64」フォルダが新たに作成され、その中にmacOS用の実行可能なファイルが生成されます。
$ npx electron-packager . sample --platform=darwin --arch=x64
WindowsやLinux用のアプリを生成する場合には --platform
で指定している箇所を以下のように変更するだけです。
オプション | 説明 |
---|---|
win32 | Windows用のEXEファイルを生成 |
linux | Linux用のファイルを生成 |
darwin | macOS用のappファイルを生成 |
mas | macOS用のAppStoreで販売するためのファイルを生成 |
また--arch
には以下のようなアーキテクチャを指定します。そのうちmacOSはARMを指定することになりそうですね。
- ia32
- x64
- armv7l
- arm64
- mips64el
ちなみに、例えばmacOSでWindows用のファイルを作成することも可能なようですが、動作確認の問題もあるので基本的にはWindows用のファイルを生成する場合はWindowsで、macOSの場合はmacOS上で実行するのが良さそうですね。
npm scriptsにまとめる
毎回このコマンドを打つのは面倒なので、npm scripts
にまとめておきます。
{ "name": "1stapp", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "electron .", "build-mac": "electron-packager . sample --platform=darwin --arch=x64 --overwrite", "build-win": "electron-packager . sample --platform=win32 --arch=x64 --overwrite", "build-linux": "electron-packager . sample --platform=linux --arch=x64 --overwrite" }, "author": "", "license": "ISC", "devDependencies": { "electron": "^10.1.2", "electron-packager": "^15.1.0" } }
すると以下のように簡潔なコマンドで実行可能になります。
$ npm run build-mac
実行可能なファイルを作成する - electron-builder編
electron-builderはpackagerよりも高機能なツールです。 例えば以下のような機能が利用できます。
- 自動更新
- 様々な出力形式
- ビルド後のファイルをGitHub Releases, Amazon S3, DigitalOcean Spacesへ公開
- 好きなプラットフォームでLinuxまたはWindows用のElectronアプリをビルドするためのDockerイメージ。
とりあえずインストーラーを自動で付けてくれるのはありがたい。
インストール
先ほどのelectron-packagerをインストールしている場合はいったん抜きます。またpackage.json
のscripts
に追加した内容も消しておきます。
$ npm remove electron-packager
その後electron-builder先生をインストール。
$ npm install --save-dev electron-builder
package.jsonで設定する
electron-builderではpackage.jsonにビルド設定を記述します。scripts
にはそれぞれmacOSとWindows用のビルドコマンドのショートカットをまとめ、build
内に具体的な設定をまとめています。
{ "name": "1stapp", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "electron .", "build-mac": "electron-builder --mac --x64", "build-win": "electron-builder --win --x64" }, "author": "", "license": "ISC", "devDependencies": { "electron": "^10.1.2", "electron-builder": "^22.8.1" }, "build":{ "appId": "net.makitokatsube.app.1st", "files": [ "package.json", "package-lock.json", "index.js", "index.html" ], "mac":{ "target": "dmg" }, "win":{ "target": "nsis" }, "nsis":{ "oneClick": false, "allowToChangeInstallationDirectory": true } } }
- appId
- OSがアプリを識別する際に、他のアプリと重複しない文字列。いわゆるBundleIDです。自分で所有しているドメインを逆にしたものを指定しています。
- files
- アプリ内に埋め込むファイル。これを指定しないとnode_modulesフォルダなども入りファイル容量が大変なことになります。ここではファイルだけではなくフォルダも指定できるのでファイル数が多くなってきたらフォルダにまとめてやります。
- mac, win
- それぞれOSごとのビルド設定を記述します。
target
は最終的な出力形式の指定です。 - nsis
- Windowsの
target
にnsisを指定した場合ここで具体的な設定を行います。よくミカエルボタンをどんどん押していく形式のインストーラとして動いてくれます。なおoneClick
はクリック一発でインストールを完了するか、allowToChangeInstallationDirectory
はインストール先の指定を許可するかどうかの設定になります。
これ以外にも様々なオプションが用意されているので、必要に応じて指定します。 www.electron.build
生成する
では実際に各OSごとに実行可能なファイルを生成します。
macOS用アプリ
package.jsonのscriptsに登録したコマンドを実行します。
$ npm run build-mac
すると以下のようにdist
フォルダが作成され、dmgファイルが生成されているのがわかります。dist/mac
フォルダの下にあるappファイルがインストーラーに入る前の純粋なアプリです。こちらもそのまま利用できます。
dmgファイルを開くと、アプリのインストール時によく見かける「アレ」が眼前に!テンション上がりますねw
実際にApplicationフォルダへコピーするとLaunchPadにアイコンが出現します。ついでにDocに追加することももちろん可能です。
Windows用アプリ
こちらもpackage.jsonのscriptsに登録したコマンドを実行します。
$ npm run build-win
するとこちらもdist
フォルダの下に、Windows用のインストーラーであるEXEファイルが作成されます。dist\win-unpacked
フォルダの下にはインストーラーに含まれる実際のアプリケーションを確認できます(ここからも起動できます)。
EXEを実行するとこれもよく見かけるインストーラーが起動します。「次へ」ボタンを連打する感じ、まさにアレですね!
インストールが完了すると「スタート」メニューから起動できます。またアンインストールもWindowsの「設定」→「アプリ」から行うことができます。OSから正式なアプリと認めてもらえてるようで最初は興奮しますねーw
今回のソースコード
GitHubに上げました。こちらからもご覧いただけます。 github.com
まとめ
セットアップからHelloWorldアプリを作成するまで10分もあれば出来てしまうのは感動しますね。しかもクロスプラットフォーム!中身はChromiumがそのまま入っているようなので、最近だとReactやVueなど好きなフレームワークを利用できるのも良いですね。
反面、Chromiumがそのまま中に入ることから、今回のようなHelloWorldアプリのみでも生成されるアプリ自体の容量がmacOS版だと168Mbyteとかなり大きくなってしまいます。小規模なアプリを開発する場合には少しためらいますね。また基本的にはC/C++などでネイティブアプリを作成するのと比べるとパフォーマンスは出ないのはトレードオフですね。
すでにあるWebサービスをローカルで動かしたい、アプリとして配布したいといった場合など利用シーンがマッチすればかなり便利に使えそうです。