メインコンテンツへ飛ぶ

Electron のシンプルなサンプル

· 読むのにかかる時間 1 分

先日、サンフランシスコにある女性のためのプログラミングスクール Hackbright Academy の会員のために、 GitHub 本社で Electron ハッカソンを開催しました。 参加者がプロジェクトを開始しやすくするために、 Kevin Sawicki がいくつかのサンプル Electron アプリケーションを作ってくれました。


あなたが Electron での開発を始めたばかりか、まだ試したことないのであれば、これらのサンプルアプリケーションは良いスタートとなるでしょう。 小さく、読みやすく、丁寧にコメントされたコードがどのように動いているかを説明してくれます。

始めるには、このリポジトリをクローンします:

git clone https://github.com/electron/simple-samples

いずれかのアプリを起動するには、そのアプリのディレクトリに入り、依存をインストールして開始します:

cd activity-monitor
npm install
npm start

アクティビティモニター

CPU におけるシステム、ユーザ、アイドル状態の時間をドーナツグラフで表示します。

スクリーンショット

ハッシュ

入力されたテキストのハッシュ値をいくつかのアルゴリズムを使って表示します。

スクリーンショット

ミラー

最大化されたサイズで、鏡を見ているかのようにコンピュータのカメラの映像を再生します。 任意で CSS アニメーションを利用した虹色フィルタ効果を含みます。

価格

Yahoo Finance API を用いて、現在の原油、金、銀の価格を表示します。

スクリーンショット

URL

コマンドラインで渡された URL をウィンドウに表示します。

その他の資料

Electron の利用を開始するためにこれらのアプリが役立つことを願います。 さらに学習するための便利な資料がこちらです:

  • electron-quick-start: 最小の Electron アプリケーションテンプレート。
  • Electron API Demos: Electron API のコア機能を試すためのインタラクティブアプリ。
  • electronjs.org/docs/all: すべての Electron ドキュメントが検索しやすい 1 ページに。
  • hokein/electron-sample-apps: Electron メンテナ Haojian Wu によってコンパイルされたサンプルアプリケーションたち。
  • awesome-electron - 最新で最良の Electron に関するチュートリアル、本、動画などを集めた GitHub リポジトリ。

Electron Userland

· 読むのにかかる時間 1 分

私達は新しい userland セックションを Electron のウェブサイトに追加して、ユーザーが私達の反映するオープンソースのエコシステムを構成する人々、パッケージ、アプリを発見する手助けをしています。


github-contributors

ユーザーランドの起源

Userland は、ソフトウェアコミュニティの人々が一緒にツールやアイデアを共有する場所です。 この用語は Unix のコミュニティに由来しています。カーネルの外で実行されたプログラムを Userland と呼んでいましたが、今日ではそれ以上のことを意味しています。 今日のJavaScript コミュニティの人々が Userland を参照するとき、通常は npm パッケージレジストリ について話しています。 これは実験とイノベーションが多く発生する場所です。一方 Node とJavaScript 言語は(Unixカーネルのように) 比較的小さく安定したコア機能のセット保持しています。

NodeとElectron

Node と同様に、Electron にはコア API の小さなセットがあります。 これらは、マルチプラットフォームのデスクトップアプリケーションの開発に必要な基本的な機能を提供します。 この設計思想により、Electronは過度にルールに則りすぎたものになることなく、柔軟性を持つツールであり続けることが可能になっています。

Userland はコアの対義語であり、ユーザーはElectronの機能を拡張するツールを作成し、共有することができます。

データ収集

私達のエコシステムのトレンドをよりよく理解するために、electronelectron-prebuiltに依存する15,000ものパブリックなGitHubリポジトリからメタデータを分析しました。

私達はGitHub API, とlibraries.io API、それに npm レジストリを使用して、依存関係、開発の依存関係、パッケージ、作者、リポジトリの貢献者、リポジトリからのダウンロード数、リポジトリのフォーク数、夢想家の数の情報を収集しました。

次に、レポートを生成するために以下のデータを使用しました。

結果のフィルタリング

アプリの依存関係 やパッケージ、アプリ、リポジトリなどのリストアップしたおきにいりアプリのようなレポートは結果をフィルタするために使用するテキスト入力をもっています。

この入力に入力すると、ページの URL が動的に更新されます。 特定のスライスを表す URL をコピーして他のユーザーと共有できます。

babel

より多くの人の参加

今回の第一号報告は、始まりに過ぎません。 今後も、コミュニティがどのように Electron を構築しているかについてのデータを収集し、ウェブサイトに新しいレポートを追加していく予定です。

このデータを収集し表示するためのツールはすべてオープンソースです。

これらのレポートを改善する方法についてのアイデアをお持ちでしたら、ウェブサイトリポジトリまたは上記のリポジトリのいずれかにIssueを立ててお知らせください。

Electron コミュニティのおかげで、今日の userland を作ることができました!

証明書の透明性の修正

· 読むのにかかる時間 1 分

Electron の基盤となる Chrome のライブラリ libchromiumcontent には、ビルド時間から 10 週間ずれた時間になることによって、一部の Symantec、GeoTrust、Thawte SSL/TLS 証明書が拒否されてしまう問題があります。Electron 1.4.12 には、この上流の Chrome の問題を修正する重要なパッチが含まれています。 影響を受けるサイトの証明書自体に問題はなく、これらの証明書を置き換えても何もありません。


Electron 1.4.0 — 1.4.11 では、これらの影響を受ける証明書のサイトへの HTTPS リクエストは、特定の日付以降、ネットワークエラーになります。 これは、window.fetch、Ajax リクエスト、Electron の net API、BrowserWindow.loadURLwebContents.loadURL<webview> タグの src 属性など、Chrome の基盤となるネットワーク API を使用して行われた HTTPS 要求に影響します。

アプリケーションを 1.4.12 にアップグレードすると、これらのリクエストエラーが発生しなくなります。

注釈: この問題は Chrome 53 から発生したため、1.4.0 以前のバージョンの Electron は影響を受けません。

影響日

以下は、Electron 1.4 の各バージョンと、影響を受ける証明書のサイトへのリクエストが失敗し始める日付の表です。

Electron のバージョン影響日
1.3.x影響なし
1.4.0既に失敗します
1.4.1既に失敗します
1.4.2既に失敗します
1.4.32016 年 12 月 10 日 午後 9:00 PST
1.4.42016 年 12 月 10 日 午後 9:00 PST
1.4.52016 年 12 月 10 日 午後 9:00 PST
1.4.62017 年 1 月 14 日 午後 9:00 PST
1.4.72017 年 1 月 14 日 午後 9:00 PST
1.4.82017 年 1 月 14 日 午後 9:00 PST
1.4.92017 年 1 月 14 日 午後 9:00 PST
1.4.102017 年 1 月 14 日 午後 9:00 PST
1.4.112017 年 2 月 11 日 午後 9:00 PST
1.4.12影響なし

アプリの影響日へコンピューターの時計を進めて、https://symbeta.symantec.com/welcome/ から正常に読み込まれるかどうか確認してください。

詳細情報

このトピック、大元の問題、修正の詳細については、以下のサイトで見ることができます。

2016 年 9 月号: 新しいアプリ

· 読むのにかかる時間 1 分

こちらは 9 月時点でサイトに追加された新しい Electron アプリと講演です。


このサイトはコミュニティからのプルリクエスト を通して新しい アプリ交流会 で更新されます。 レポジトリを Watch すれば新しい追加の通知を受け取ることができます。全て のサイトの変更に関心がない場合は、ブログ RSS フィード に登録してください。

Electron アプリを作成したり、交流会を開催したりしている場合、プルリクエスト を作成するとサイトに追加して次のまとめに載ります。

新しい講演

9 月に、GitHub は GitHub Universe カンファレンスを開催し、ソフトウェアの未来を築く人々のためのイベントだと宣言しました。 このイベントでは、面白い Electron の講演がいくつかありました。

また、12 月 5 日のパリで、Zeke は dotJS 2016 で Electron の講演を行います

新しいアプリ

Pexels完全無料の写真を検索、クリップボードにコピーします
Timestampカスタマイズ可能な日付/時刻表示とカレンダーを備える、優れた macOS メニューバー時計
HarmonySpotify、Soundcloud、Play Music、ローカルファイル互換の音楽プレーヤー
uPhoneWebRTC デスクトップ通話
SealTalkRongCloud IM Cloud Service と IM SDK による簡易メッセージングアプリ
Infinity簡単なプレゼン制作
Cycligent Git ToolGit プロジェクト用のわかりやすい視覚的 GUI
FocoFoco なら集中できて生産性向上
Strawberry一期一会のお客様によりよいサービスを提供するためのレストランソフトウェア一式
Mixmaxあなたのメールに、どんなアクションでも、どこでも、リアルタイムで。
Firebase AdminFirebase データ管理ツール
ANote簡単親切な Markdown ノート
Tempsシンプルで賢い天気アプリ
Amiumファイル対話型作業統合プロダクト
Soubeシンプルなミュージックプレイヤー
(Un)coloredHTML & Markdown 互換テーマでドキュメントを保存する次世代のデスクトップリッチコンテンツエディタ。 Windows、OS X、Linux 対応。
quickcalcメニューバー電卓
Forestpin Analytics企業向け財務データ分析ツール
LingREST クライアント
Shortexts頻繁にコピーするフォルダと絵文字のテキストショートカット
Front-End Boxフロントエンドコード生成機のセット

Electron の API ドキュメントを構造化データに

· 読むのにかかる時間 1 分

本日、Electron のドキュメントに対していくつか改善する点を発表します。 新しいリリースごとに、Electron のすべての公開 API を詳細に説明する JSON ファイル を同梱します。 このファイルを作成したことで、開発者は Electron の API ドキュメントの面白くて新しい使用方法ができるようになりました。


スキーマの概要

各 API は、名前、説明、型などの特性を持つオブジェクトです。 BrowserWindowMenu のようなクラスには、インスタンスメソッド、インスタンスプロパティ、インスタンスイベントなどもあります。

以下は BrowserWindow クラスを説明しているスキーマからの抜粋です。

{
name: 'BrowserWindow',
description: 'Create and control browser windows.',
process: {
main: true,
renderer: false
},
type: 'Class',
instanceName: 'win',
slug: 'browser-window',
websiteUrl: 'https://electronjs.org/docs/api/browser-window',
repoUrl: 'https://github.com/electron/electron/blob/v1.4.0/docs/api/browser-window.md',
staticMethods: [...],
instanceMethods: [...],
instanceProperties: [...],
instanceEvents: [...]
}

次に、メソッドの説明の例を示します。以下は apis.BrowserWindow.instanceMethods.setMaximumSize インスタンスメソッドです。

{
name: 'setMaximumSize',
signature: '(width, height)',
description: 'Sets the maximum size of window to width and height.',
parameters: [{
name: 'width',
type: 'Integer'
}, {
name: 'height',
type: 'Integer'
}]
}

新しいデータを使う

開発者がプロジェクトでこの構造化データを簡単に使用できるように、新しい Electron リリースごとに自動公開される小さな npm パッケージ electron-docs-api を作成しました。

npm install electron-api-docs --save

すぐに試したいなら、Node.js REPL 内でこのモジュールを試してみてください。

npm i -g trymodule && trymodule electron-api-docs=apis

データの収集方法

Electron の API ドキュメントは Electron Coding StyleElectron Styleguide に準拠しているため、内容はプログラムで解析できます。

electron-docs-linterelectron/electron レポジトリの新しい開発用依存関係となります。 これは、すべての Markdown ファイルを lint し、スタイルガイドのルールを適用するコマンドラインツールです。 エラーが見つかった場合、それらが列挙され、リリースプロセスが停止します。 API ドキュメントが有効な場合、electron-json.api ファイルが作成され、Electron リリースの一部として GitHub にアップロード されます。

Standard Javascript と Standard Markdown

今年の始め頃に Electron のコードベースが更新され、全 JavaScript で standard リンターが使用されました。 Standard の README は、この決定の後ろ盾である理由の要約です。

Standard スタイルを採用するということは、個人のスタイルよりもコードの明快さとコミュニティの慣習の重要性を高く位置付けるということです。 これはプロジェクトと開発の文化にとって 100% の意義を持たないかもしれませんが、オープンソースは初心者が嫌う場所になることがあるものです。 コントリビューターにしてほしいことを自動化して明確にすれば、プロジェクトがより健全になります。

また、ドキュメント内のすべての JavaScript コードスニペットが有効であり、コードベース自体のスタイルと一貫性があることを確認するために、少し前に standard-markdown を作成しました。

これらのツールを組み合わせて、継続的インテグレーション (CI) がプルリクエストのエラーを自動的に見つけることができます。 これにより、コードをレビューする人間の負担が軽減され、ドキュメントの正確性に関する信頼性が高まります。

コミュニティ活動

Electron のドキュメントは絶えず改善されており、素晴らしいオープンソースコミュニティがあることに感謝します。 このドキュメントの執筆時点で、約 300 人がドキュメントに貢献しています。

この新しい構造化データで皆さんが何をするのか楽しみです。 考えられる用途は以下の通りです。

Electron の舞台裏: 弱参照

· 読むのにかかる時間 1 分

ガベージコレクションがある言語 JavaScript は、ユーザーがリソースを手動で管理しなくてよくなります。 しかし、Electron はこの環境をホストしているため、メモリリークとリソースリークの両方を避けようと非常に慎重にならざるをえません。

この記事では、弱参照の概念と、それが Electron のリソース管理でどのように使われているかを紹介します。


弱参照

JavaScript でオブジェクトを変数に代入するというのは、必ずオブジェクトへの参照を追加していることになります。 オブジェクトへの参照がある限り、そのオブジェクトはずっとメモリに保持されます。 オブジェクトへのすべての参照がなくなる、例えばオブジェクトを格納する変数がなくなると、JavaScript エンジンは次のガベージコレクションでそのメモリを回収します。

弱参照とは、ガベージコレクションされるかどうかに影響せずオブジェクトを取得できるようにする参照です。 オブジェクトがガベージコレクションされたときにその通知もされます。 これにより、JavaScript でリソース管理を可能にします。

Electron の NativeImage クラスを例に挙げると、nativeImage.create() APIを呼び出すたびに NativeImage インスタンスが返され、これに画像データが C++ 側で格納されます。 インスタンスの処理が終わり JavaScript エンジン (V8) がオブジェクトをガベージコレクトしたら、C++ のコードが呼び出されてメモリ内の画像データが解放されるので、ユーザが手動で管理する必要はありません。

別の例としては、ウインドウ消失問題 があります。これはウインドウへの参照がすべてなくなったときにガベージコレクトされる様子を、視覚的に観察できます。

Electron での弱参照のテスト

生の JavaScript には弱参照を代入する方法がないので、弱参照を直接テストする方法はありません。 弱参照に関連する JavaScript の API だと WeakMap がありますが、これは弱参照のキーを作成するだけなので、オブジェクトがガベージコレクトされたかどうかは知ることができません。

v0.37.8 以前のバージョンの Electron では、内部の v8Util.setDestructor API を使用して弱参照をテストできました。以下のように、渡されたオブジェクトに弱参照を追加し、オブジェクトがガベージコレクションされたときにコールバックを呼び出すものです。

// 以下のコードは Electron < v0.37.8 でのみ実行できます。
var v8Util = process.atomBinding('v8_util');

var object = {};
v8Util.setDestructor(object, function () {
console.log('The object is garbage collected');
});

// オブジェクトへの参照を全て削除します。
object = undefined;
// GC を手動で起動します。
gc();
// コンソールに "The object is garbage collected" と出力されます。

注意としては、内部の gc 関数を公開させるために、--js-flags="--expose_gc" コマンドスイッチで Electron を起動する必要があります。

この API は後のバージョンで削除されました。このため V8 では実際にはデストラクタで JavaScript コードを実行できず、これをしようとしても確率でクラッシュします。

remote モジュールでの弱参照

C++ でネイティブリソースを管理する以外にも、Electron は JavaScript のリソースを管理するために弱参照が必要です。 例えば、Electron の remote モジュールはいわゆる Remote Procedure Call (RPC) モジュールで、レンダラープロセスからメインプロセス内のオブジェクトを使用できるようにます。

remote モジュールの重要な課題の 1 つに、メモリリークを避けるというものがあります。 ユーザがレンダラープロセス内のリモートオブジェクトを取得する場合、remote モジュールは、レンダラープロセス内の参照がなくなるまでオブジェクトがメインプロセスに存在し続けるよう保証しなければなりません。 さらに、レンダラープロセスでリモートオブジェクトへの参照がなくなったときに、そのオブジェクトがガベージコレクションされるようにする必要があります。

例えば、適切な実装を行わないと、以下のコードはすぐにメモリリークを起こしてしまいます。

const { remote } = require('electron');

for (let i = 0; i < 10000; ++i) {
remote.nativeImage.createEmpty();
}

remote モジュールのリソース管理は単純です。 オブジェクトの要求ごとにメインプロセスへメッセージが送信されます。それに対して Electron はオブジェクトをマップに保存して ID を割り当て、レンダラープロセスにその ID を送り返します。 レンダラープロセスでは、remote モジュールが ID を受け取ってプロキシオブジェクトでラップし、プロキシオブジェクトがガベージコレクションされると、オブジェクト解放のメッセージをメインプロセスに送信します。

remote.require API を例にすると、簡略化した実装は以下のようになります。

remote.require = function (name) {
// モジュールのメタデータを返すようにメインプロセスに伝えます。
const meta = ipcRenderer.sendSync('REQUIRE', name);
// プロキシオブジェクトを作成します。
const object = metaToValue(meta);
// プロキシオブジェクトがガベージコレクションされたときに
// オブジェクトの解放をメインプロセスに指示します。
v8Util.setDestructor(object, function () {
ipcRenderer.send('FREE', meta.id);
});
return object;
};

メインプロセスでは以下のようにします。

const map = {};
const id = 0;

ipcMain.on('REQUIRE', function (event, name) {
const object = require(name);
// オブジェクトへの参照を追加します。
map[++id] = object;
// オブジェクトをメタデータに変換します。
event.returnValue = valueToMeta(id, object);
});

ipcMain.on('FREE', function (event, id) {
delete map[id];
});

弱参照の辞書配列

先述の単純な実装では、remote モジュールを呼び出すたびにメインプロセスが新しいリモートオブジェクトを返し、各リモートオブジェクトがメインプロセスのオブジェクトへの参照を表します。

デザイン自体は問題ないのですが、同じオブジェクトを受信するために複数回呼び出すと、複数のプロキシオブジェクトが作成され、複雑なオブジェクトの場合にメモリ使用量とガベージコレクションを圧迫するという問題があります。

以下のようなコードがあったとします。

const { remote } = require('electron');

for (let i = 0; i < 10000; ++i) {
remote.getCurrentWindow();
}

まずプロキシオブジェクトを作成するためにメモリを多く使用し、そのガベージコレクションと IPC メッセージの送信に CPU(Central Processing Unit) を占有します。

明白な最適化としては、リモートオブジェクトのキャッシュがあります。すなわち、すでに同じ ID のリモートオブジェクトが存在する場合、新しいオブジェクトを作成するのではなく以前のリモートオブジェクトを返すようにします。

これは JavaScript コアの API ではできません。 通常の辞書配列を使ってオブジェクトをキャッシュすれば V8 によるオブジェクトのガベージコレクションを防げますが、WeakMap クラスではオブジェクトのみが弱参照のキーに使えます。

これを解決するために、値を弱参照として持つマップ型を追加しました。ID を持つオブジェクトのキャッシュに最適です。 これで、remote.require は以下のようになります。

const remoteObjectCache = v8Util.createIDWeakMap()

remote.require = function (name) {
// モジュールのメタデータを返すようにメインプロセスに伝えます。
...
if (remoteObjectCache.has(meta.id))
return remoteObjectCache.get(meta.id)
// プロキシオブジェクトを作成します。
...
remoteObjectCache.set(meta.id, object)
return object
}

注意として、remoteObjectCache はオブジェクトを弱参照として保管するので、オブジェクトがガベージコレクトされたときでもキーの削除は不要です。

ネイティブコード

Electron の弱参照の C++ コードに興味がある方は、以下のファイルを参照してください。

setDestructor API:

createIDWeakMap API:

2016 年 8 月号: 新しいアプリ

· 読むのにかかる時間 1 分

こちらは 8 月時点でサイトに追加された新しい Electron アプリです。


このサイトは、コミュニティからの プルリクエスト を経て新しい アプリ交流会 に更新されます。 レポジトリを Watch すれば新しい追加の通知を受け取ることができます。全て のサイトの変更に関心がない場合は、ブログ RSS フィード に登録してください。

Electron アプリを作成したり、交流会を開催したりしている場合、プルリクエスト を作成するとサイトに追加して次のまとめに載ります。

新しいアプリ

Code RPGifyRPG スタイルコーディングアプリケーション
PamFaxFAX を送受信するクロスプラットフォームアプリ
BlankUpすっきり度 +1 の Markdown エディタ
Rambox一般のウェブアプリケーションを 1 つにする、無料でオープンソースのメッセージング & メールアプリ
Gordieカードコレクションに最適なアプリ
Ionic Creator綺麗なモバイルアプリを、素早く構築
TwitchAlerts美麗なアラートと通知で視聴者を笑顔に
Museeksシンプル、クリーン、クロスプラットフォームな音楽プレーヤー
SeaPigMarkdown から HTML へのコンバータ
GroupMeGroupMe 非公式アプリ
Moeditor汎用 Markdown エディター
SoundnodeSoundnode アプリはデスクトップ向け Soundcloud です
QMUI WebQMUI ウェブデスクトップは、QMUI ウェブフレームワークをベースにプロジェクト管理をするアプリケーションです
SvgsusSVG の整理、整頓、変換
Ramme非公式 Instagram デスクトップアプリ
InsomniaREST API クライアント
CorreoWindows、macOS、Linux 向けメニューバー/タスクバー Gmail アプリ
KongDashKong Admin API のデスクトップクライアント
Translation EditorINTL ICU メッセージの翻訳ファイルエディター (formatjsio を参照)
5EClient5EPlay CSGO クライアント
Theme Juiceローカルの WordPress 開発を簡単に

アクセシビリティツール

· 読むのにかかる時間 1 分

アクセシビリティの高いアプリケーションを作ることは重要です。開発者がすべてのユーザ向けのより良いアプリケーション開発を手助けする新機能 DevtronSpectron を紹介します。


Electron アプリケーションのアクセシビリティに関する懸念は、どちらも最終的に HTML であるため、ウェブサイトと同様です。 しかし、Electron アプリケーションでは、アプリケーションに監査機を指す URL がないため、アクセシビリティ監査にオンラインリソースを使用することはできません。

これらの新機能は、監査ツールを Electron アプリに提供します。 Spectron でテストに監査を追加するか、開発者向けツール内で Devtron で監査を使用するかを選択できます。 詳細は、ツールの概要を読むか アクセシビリティドキュメント をご覧ください。

Spectron

Spectron テストフレームワークで、アプリケーション内の各ウィンドウと <webview> タグを監視できます。 以下がその例です。

app.client.auditAccessibility().then(function (audit) {
if (audit.failed) {
console.error(audit.message);
}
});

この機能の詳細は Spectron のドキュメント にて閲覧できます。

Devtron

Devtronでは新機能のアクセシビリティタブが利用できます。このタブでは、アプリケーション内の監視結果をソートしたり、フィルタによって絞り込んだりできます。

devtron スクリーンショット

いずれのツールも Google が Chrome 向けに開発した Accessibility Developer Tools ライブラリを利用しています。 このライブラリが使用しているアクセシビリティ監査のルールに関する詳細は、リポジトリの wiki に記載されています。

これ以外の Electron 向けに使用可能な素晴らしいアクセシビリティツールをご存じの方は、 ぜひアクセシビリティに関するドキュメント に追加してプルリクエストをお送りください。

npm install electron

· 読むのにかかる時間 1 分

Electron バージョン 1.3.1 では、 npm install electron --save-dev とすればコンパイル済みの Electron をアプリにインストールできます。


npm install electron

ビルド済み Electron ライブラリ

Electron アプリの開発経験があれば、おそらく electron-prebuilt npm パッケージを触ったことがあるでしょう。 このパッケージはほぼすべての Electron プロジェクトにおいて不可欠なものです。 インストールされると、オペレーティングシステムを検出し、ビルド済みバイナリの中からそのシステムアーキテクチャに適したものをダウンロードします。

新しい名前

Electron のインストール過程は、新規開発者にとっての壁となりがちでした。 多くの勇敢な人々が、npm install electron-prebuilt ではなく npm install electron を実行して Electron アプリの開発を始めようとしたところ、(多くの場合、混乱の末に) それが探していた electron ではないことに気づいたでしょう。

これは、 GitHub の Electron プロジェクトが作られる前から electron プロジェクトが npm に存在していたためです。 Electron での開発がより簡単で直感的になるよう、私たちは既存の electron の所有者に連絡を取り、名前を使わせてもらえないかを交渉しました。 幸い、彼は私たちのプロジェクトに賛同しており、名前の再利用に協力して下さいました。

Prebuilt との営み

バージョン 1.3.1 では、electronelectron-prebuilt のパッケージを npm に同時公開するようになりました。 2 つのパッケージは同じです。 現在プロジェクトで electron-prebuilt を使用している数多の開発者のために、しばらくの間、両方の名前でパッケージを公開することを決めました。 新しい electron に依存するように package.json ファイルを更新することを推奨しますが、 2016 年末までは新しいバージョンの electron-prebuilt もリリースされます。

electron-userland/electron-prebuiltelectron npm パッケージに対する正規のホームリポジトリとして残ります。

謝辞

@mafintosh には特別な感謝を捧げます。 @maxogden をはじめとする多くの 貢献者の方々 には、electron-prebuilt の作成と保守、そして JavaScript、Node.js、Electron コミュニティへのたゆまぬご協力に感謝します。

そして npm で electron パッケージを引き取らせてくれた @logicalparadox に感謝します。

プロジェクトの更新

この変更に影響される人気のパッケージを更新するために、コミュニティと協力してきました。 electron-packagerelectron-rebuildelectron-builder のようなパッケージは、古い名前をサポートしつつ、既に新しい名前で動作するように更新されています。

新しいパッケージをインストールするときに何らかの問題が発生した場合、 electron-userland/electron-prebuilt リポジトリに Issue を開いてお知らせください。

Electron に関する他の問題については、 electron/electron リポジトリを使用してください。

Electron の舞台裏: Node をライブラリとして使用する

· 読むのにかかる時間 1 分

Electron の舞台裏について説明するシリーズ、第二弾です。 イベントループの統合についてまだ読んでいない方は 最初の記事 をご覧ください。

ほとんどの人は Node をサーバサイドアプリケーションに使っていますが、Node の豊富な API セットと活発なコミュニティのおかげで組み込みライブラリにも最適です。 この記事では、Electron のライブラリとして Node がどのように使われているかを解説します。


ビルドシステム

Node も Electron も GYP をビルドシステムとして使用しています。 アプリ内に Node を埋め込みたい場合は、あなたもビルドシステムとして GYP を使用する必要があります。

GYP は初めてですか? そうであれば、この記事を読み進める前に このガイド を読んでからにしてください。

Node のフラグ

Node のソースコードディレクトリにある node.gyp ファイルには、Node をどのように構築するかが記述されており、多くの GYP 変数とともに Node のどの部分を有効にするのか、特定の設定ファイルを開くかどうかを制御しています。

ビルドフラグを変更するには、プロジェクトの .gypi ファイルに変数を設定する必要があります。 Node の configure スクリプトは、いくつかの一般的な設定ファイルを生成できます。例えば、./configure --shared を実行すると、Node を共有ライブラリとしてビルドするように指示する変数を含んだ config.gypi が生成されます。

Electron は独自のビルドスクリプトを持っているので、この configure スクリプトは使いません。 Node の設定は、Electron のルートソースコードディレクトリにある common.gypi ファイルで定義されています。

Electron と Node のリンク

Electron では、GYP 変数 node_sharedtrue に設定することで Node を共有ライブラリとしてリンクしています。このため、Node のビルドタイプは executable から shared_library に変更され、Node の main エントリポイントを含むソースコードはコンパイルされません。

Electron は Chromium に同梱されている V8 ライブラリを使用しているため、Node のソースコードに含まれている V8 ライブラリは使用しません。 これは node_use_v8_platformnode_use_bundled_v8 の両方を false に設定することで実現しています。

共有ライブラリか静的ライブラリか

Node とリンクする際には 2 つの選択肢があります。静的ライブラリとしてビルドし最終的な実行ファイルにインクルードするか、共有ライブラリとしてビルドし最終的な実行ファイルと一緒に頒布するかです。

Electron では、Node は長い間静的ライブラリとしてビルドしていました。 これはビルドがシンプルで、高水準なコンパイラの最適化が可能で、余分な node.dll ファイルいらずで Electron を頒布できました。

しかし、これは Chrome が BoringSSL を使うようになってから変わりました。 BoringSSL は OpenSSL のフォークで、いくつかの未使用の API を削除し、多くの既存のインターフェースを変更しています。 Node は依然 OpenSSL を使用しているため、コンパイラがそれらをリンクすると、矛盾するシンボルのために多数のリンクエラーを発生させてしまいます。

Electron では、Node で BoringSSL を使うことも Chromium で OpenSSL を使うこともできませんでした。そのため、Node を共有ライブラリとしてビルドするように切り替え、BoringSSL と OpenSSL のシンボルをそれぞれのコンポーネントで隠す という選択肢しかありませんでした。

この変化は、Electron にいくぶんかプラスの副作用をもたらしました。 この変更以前は、Windows 上でネイティブモジュールを使用している場合、インポートライブラリ内で実行ファイル名をハードコーディングしていたため、実行ファイル名を変更できませんでした。 Node が共有ライブラリとして構築されてからは、すべてのネイティブモジュールを node.dll にリンクしたため、この制限がなくなりました。

ネイティブモジュールのサポート

Node のネイティブモジュール は、Node がロードするエントリ関数を定義し、Node から V8 や libuv のシンボルを検索することで動作します。 これは組み込み開発者にとっては少し面倒です。なぜなら、デフォルトではライブラリとして Node をビルドする際に V8 と libuv のシンボルが隠されており、ネイティブモジュールはシンボルを見つけられずロードに失敗するからです。

そこで、ネイティブモジュールを動作させるために Electron では V8 と libuv のシンボルを公開しました。 V8 では、Chromium の設定ファイル内の全シンボルを強制的に公開する ことで実現しています。 libuv の場合、BUILDING_UV_SHARED=1 定義を設定する ことで実現しています。

アプリで Node を起動する

Node をビルドしてリンクする全作業の後は、最後の段階としてアプリで Node を実行します。

Node は、自分自身を他のアプリに組み込むための公開 API は多く提供していません。 通常は、node::Startnode::Init を呼び出すだけで Node の新しいインスタンスを起動できます。 しかし、Node ベースで複雑なアプリを構築する場合は、node::CreateEnvironment のような API を使用して全ステップを正確に制御する必要があります。

Electron で Node を起動する際には、公式の Node バイナリに近いメインプロセスで動作するスタンドアロンモードと、ウェブページに Node API を挿入する組み込みモードの、2 つのモードがあります。 この詳細は後々の記事で解説する予定です。