読者です 読者をやめる 読者になる 読者になる

Electronの使い方(自分流)

Electronの使い方(自分流)

はじめに

最近気になっているクロスプラットフォーム開発環境(?)Electronの使い方を自分用にまとめてみました。

node.jsは事前にインストールしておきます。VisualStudioなどのアプリケーションを入れるとnode.jsも一緒にインストールされることもありますが、比較的古いものがインストールされるので、公式サイトからダウンロードしておいたほうがいいと思います。パッケージはLTSとStableがありますが、通常はLTSで問題ないと思います。

node.jsがインストールが完了したら、npm(Node Package Manager)コマンドを使ってElectronに必要なパッケージをインストールしていくことになります。

必要になるものは以下の2つ

  • electron-prebuilt
  • electron-packager

今後がめんどくさくならないようにするためにグローバル環境にインストールします。 他にもアーカイブするためのパッケージ(asar)などもありますが、必要であればインストールしてください。

electron-prebuiltのインストール

PS C:\> npm install -g electron-prebuilt

electron-packagerのインストール

PS C:\> npm install -g electron-packager

(必要なら)asarのインストール

PS C:\> npm install -g asar

Electronでサンプルアプリケーションを作成してみる

ディレクトリなどの準備

PS C:\> mkdir sample
PS C:\> cd sample
PS C:\> npm init -y

最後のnpmコマンドでpackage.jsonのひな型を生成しています。コマンド実行時にauthorなどの質問がくることもありますが、適切に入力します。出来上がったpackage.jsonは以下のようになっています。(authorの質問がなかったので空になっています。)

package.json

{
  "name": "sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

このpackage.jsonのscriptに以下のものを変更しておくと後から便利になります。

変更部分抜粋(変更前)

・・・中略・・・
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
・・・中略・・・

変更部分抜粋(変更後)

・・・中略・・・
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "node_modules/.bin/electron .",
    "release": "node release.js"
  },
・・・中略・・・

変更を反映すると次のようになります。

変更終了後のpackage.json

{
  "name": "sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "node_modules/.bin/electron .",
    "release": "node release.js"
  },
  "keywords": [],
  "author": "ueponx",
  "license": "ISC"
}

サンプルを内容を「Hello Worldを出力するアプリ」とする。

使い方のサンプルとして「Hello Worldを出力するアプリ」にします。別にどんなものでもよいと思います。 Electronのデフォルトのエントリーポイントはindex.js(package.jsonのmainの値がエントリーファイルになります)としているので作成します。

'use strict';
var app = require('app');
var BrowserWindow = require('browser-window');

var mainWindow = null;
app.on('window-all-closed', function() {
  if (process.platform != 'darwin') {
    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;
  });
});

詳しい記載はしませんが、このJavaScriptでは同一ディレクトリ内にあるindex.htmlの内容表示しています。次に表示するためのhtmlファイルを作成します。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Sample</title>
</head>
<body>
  <p>Hello World</p>
</body>
</html>

これで実行する準備ができました。それでは以下のようにコマンドを実行します。

PS C:\>  npm run build

すると以下のようなウインドウが表示されます。このコマンドでは先のpackage.jsonで追加したscriptsの部分にbuildの値をコマンドとして起動することができます。(make hogeのような感じです)

f:id:ueponx:20160329232153j:plain

これでElectronで作成したアプリの起動ができました。

プラットフォームアプリへのパッケージング

このままでは、Electronをインストールしている人のみが実行できる状態なので、その他の環境でも実行可能する必要があります。このとき、Electronの実行環境と一緒にパッケージングしてくれるelectron-packagerを使用します。

それに先立って次のrelease.jsファイルを作成します。

var packager = require('electron-packager');
var config = require('./package.json');
 
packager({
    dir: './',
    out: '../dist',
    name: config.name,
    platform: 'win32',
    arch: 'x64',
    version: '0.37.2',
    icon: './app.icns', //<- アプリアイコン
 
    'app-bundle-id': 'com.hatenadiary.uepon',
 
    'app-version': config.version,
    'helper-bundle-id': 'com.hatenadiary.uepon',
    overwrite: true,
    asar: true,
    prune: true,
    ignore: "node_modules/(electron-packager|electron-prebuilt|\.bin)|release\.js",
    'version-string': {
        CompanyName: '',
        FileDescription: 'HelloWorld',
        OriginalFilename: config.name,
        FileVersion: config.version,
        ProductVersion: config.version,
        ProductName: config.name,
        InternalName: config.name
    }
}, function done (err, appPath) {
    if(err) {
        throw new Error(err);
    }
    console.log('Done!!');
});

ファイルの内容はwindows用の64bit環境で動作するアプリケーションを作成するものとなっています。出力先は一つ上の階層のdistディレクトリです。 作成後に実際にパッケージングを行います。

PS > npm run release

実行に成功すると..\distディレクトリ内にsample-win32-x64ディレクトリが作成され、その中にWindows向けのパッケージが作成されます。このディレクトリ内のexeファイルを実行することでElectron上と同様の実行結果を得ることができます。

できるはずなのですが、うまくいきません。

以下のようなエラーが発生します。

PS C:\sample> npm run release

> sample@1.0.0 release C:\Users\uepon\Documents\electron\sample
> node release.js

module.js:328
    throw err;
    ^

Error: Cannot find module 'electron-packager'
    at Function.Module._resolveFilename (module.js:326:15)
    at Function.Module._load (module.js:277:25)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (C:\sample\release.js:1:78)
    at Module._compile (module.js:410:26)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:442:10)

内容を読んでみるとどうもグローバル環境でインストールしたはずのelectron-packagerのモジュールが読み込めずエラーを発生しているようです。確かにrelease.jsの一行目に

var packager = require('electron-packager');

と記載しているのでここでエラーがでているのでしょう。 ただ、グローバル環境にインストールしているはずなのになぜこのようなエラーが出るのでしょうか。原因はよくわかりませんが、ネットを検索すると同じようなエラーを出している方いるようなので、それを参考に調べてみると、どうも環境変数のNODE_PATHにグローバルモジュールのPATHを記述すればエラーがでないようでした。

まずは下記のコマンドでグローバルのnode_modulesディレクトリの場所を調べます。

PS C:\> npm root -g
C:\Users\ueponx\AppData\Roaming\npm\node_modules

あとは環境変数のNODE_PATHの値に調べたディレクトリを格納します。 その後再度パッケージングを行います。

PS C:\sample> npm run release


> sample@1.0.0 release C:\sample
> node release.js

Packaging app for platform win32 x64 using electron v0.37.2
Cannot create symlinks; skipping darwin platform
Done!

エラーなく完了しました。 これらの手順でelectronのアプリケーションが作成できました。 exeファイルを実行すると無事にアプリケーションを実行できます。(これだけの内容なのに100Mを超えますが…)

f:id:ueponx:20160329232925j:plain

そのほかの方法でも問題なくできます。ただ、個人的に気になったのがアプリを作成してからディレクトリの移動をコマンドないで行わないといけないのが面倒だなと思い、いろいろといい方法を探した結果が今回のものになりました。

ビルドツールのようなものがあればもっと簡単なのかなとは思いますが・・・。