Electron-quick-guide

提供:Dev Guides
移動先:案内検索

電子-概要

なぜ電子?

Electronは、ランタイムに豊富なネイティブ(オペレーティングシステム)APIを提供することにより、純粋なJavaScriptでデスクトップアプリケーションを作成できます。

これは、Electronがグラフィカルユーザーインターフェイス(GUI)ライブラリへのJavaScriptバインディングであることを意味しません。 代わりに、ElectronはWebページをGUIとして使用するため、JavaScriptで制御される最小限のChromiumブラウザーとして表示することもできます。 したがって、すべての電子アプリは、OS APIを活用できるブラウザーで実行される技術的にWebページです。

誰がElectronを使用していますか?

Githubは、テキストエディターAtomを作成するためにElectronを開発しました。 どちらも2014年にオープンソース化されました。 Electronは、Microsoft、Github、Slackなどの多くの企業で使用されています。

Electronは多くのアプリを作成するために使用されています。 以下はいくつかの注目すべきアプリです-

  • Slackデスクトップ
  • Wordpressデスクトップアプリ
  • Visual Studioコード
  • キャレットマークダウンエディター
  • Nylas Emailアプリ
  • GitKraken gitクライアント

Electron-インストール

Electronを使用した開発を開始するには、Nodeおよびnpm(node package manager)がインストールされている必要があります。 これらがまだない場合は、link:/nodejs/nodejs_environment_setup [Node setup]にアクセスして、ローカルシステムにノードをインストールします。 ターミナルで次のコマンドを実行して、ノードとnpmがインストールされていることを確認します。

node --version
npm --version

上記のコマンドは、次の出力を生成します-

v6.9.1
3.10.8

npmを使用してプロジェクトを作成するたびに、プロジェクトに関するすべての詳細が含まれる package.json ファイルを提供する必要があります。 npmを使用すると、このファイルを簡単にセットアップできます。 開発プロジェクトをセットアップしましょう。

  • ターミナル/cmdを起動し、hello-worldという名前の新しいフォルダーを作成し、cdコマンドを使用してそのフォルダーを開きます。
  • npmを使用してpackage.jsonファイルを作成するには、次のコマンドを使用します。
npm init
  • 次の情報を求められます-

Package.json creation

Enterを押し続け、「著者名」フィールドに名前を入力します。

新しいフォルダーを作成し、cdコマンドを使用して開きます。 次のコマンドを実行して、Electronをグローバルにインストールします。

$ npm install -g electron-prebuilt

実行したら、次のコマンドを実行して、Electronが正しい方法でインストールされているかどうかを確認できます-

$ electron --version

あなたは出力を取得する必要があります-

v1.4.13

Electronをセットアップしたので、それを使用して最初のアプリを作成することに移りましょう。

Electronの仕組み

Electronは、_package.json_ファイルで定義されたメインファイルを取得して実行します。 このメインファイルは、レンダリングされたWebページとオペレーティングシステムのネイティブGUI(グラフィカルユーザーインターフェイス)との対話を含むアプリケーションウィンドウを作成します。

Electronを使用してアプリケーションを起動すると、*メインプロセス*が作成されます。 このメインプロセスは、オペレーティングシステムのネイティブGUIと対話する役割を果たします。 アプリケーションのGUIを作成します。

メインプロセスを開始するだけでは、アプリケーションのユーザーにアプリケーションウィンドウは提供されません。 これらは、_BrowserWindow_モジュールを使用して、メインファイルのメインプロセスによって作成されます。 各ブラウザウィンドウは、独自の*レンダラープロセス*を実行します。 レンダラープロセスは、通常のCSSファイル、JavaScriptファイル、画像などを参照するHTMLファイルを受け取ります。 それをウィンドウにレンダリングします。

メインプロセスは、Electronで直接利用可能なモジュールを介してネイティブGUIにアクセスできます。 デスクトップアプリケーションは、ファイルを処理するためのファイルシステムモジュール、HTTP呼び出しの要求など、すべてのNodeモジュールにアクセスできます。

メインプロセスとレンダラープロセスの違い

メインプロセスは、_BrowserWindow_インスタンスを作成してWebページを作成します。 各_BrowserWindow_インスタンスは、独自のレンダラープロセスでWebページを実行します。 _BrowserWindow_インスタンスが破棄されると、対応するレンダラープロセスも終了します。

メインプロセスは、すべてのWebページとそれに対応するレンダラープロセスを管理します。 各レンダラープロセスは分離されており、そこで実行されているWebページのみを考慮します。

Electron-Hello World

プロジェクト用に package.json ファイルを作成しました。 ここで、Electronを使用して最初のデスクトップアプリを作成します。

_main.js_という新しいファイルを作成します。 それに次のコードを入力してください-

const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

app.on('ready', createWindow)

別のファイルを作成します。今回は_indexl_というHTMLファイルです。 次のコードを入力してください。

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>Hello World!</title>
   </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>

次のコマンドを使用してこのアプリを実行します-

$ electron ./main.js

新しいウィンドウが開きます。 次のようになります-

Electron Hello World

このアプリはどのように機能しますか?

メインファイルとHTMLファイルを作成しました。 メインファイルは、_app_と_BrowserWindow_の2つのモジュールを使用します。 アプリモジュールはアプリケーションのイベントライフサイクルを制御するために使用され、BrowserWindowモジュールはブラウザーウィンドウを作成および制御するために使用されます。

新しいBrowserWindowを作成し、このBrowserWindowにURLを添付する_createWindow_関数を定義しました。 これは、アプリの実行時にレンダリングおよび表示されるHTMLファイルです。

htmlファイルでは、ネイティブのElectronオブジェクトプロセスを使用しました。 このオブジェクトはNode.jsプロセスオブジェクトから拡張されており、 t = its のすべての機能を含み、さらに多くを追加します。

Electron-UIの構築

Electronアプリのユーザーインターフェイスは、HTML、CSS、JSを使用して構築されています。 そのため、ここでもフロントエンドWeb開発に利用可能なすべてのツールを活用できます。 Angular、Backbone、React、Bootstrap、Foundationなどのツールを使用して、アプリを構築できます。

Bowerを使用して、これらのフロントエンドの依存関係を管理できます。 -を使用してbowerをインストールします

$ npm install -g bower

これで、利用可能なすべてのJSおよびCSSフレームワーク、ライブラリ、プラグインなどを取得できます。 バウアーを使用して。 たとえば、ブートストラップの最新の安定バージョンを取得するには、次のコマンドを入力します-

$ bower install bootstrap

これにより、_bower_components_にブートストラップがダウンロードされます。 これで、HTMLでこのライブラリを参照できます。 これらのライブラリを使用して簡単なページを作成しましょう。

npmコマンドを使用してjqueryをインストールしましょう-

$ npm install --save jquery

さらに、これはview.jsファイルでは_required_になります。 次のようなmain.jsのセットアップが既にあります-

const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

app.on('ready', createWindow)
*indexl* ファイルを開き、それに次のコードを入力します-
<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>Hello World!</title>
      <link rel = "stylesheet"
         href = "./bower_components/bootstrap/dist/css/bootstrap.min.css"/>
   </head>

   <body>
      <div class = "container">
         <h1>This page is using Bootstrap and jQuery!</h1>
         <h3 id = "click-counter"></h3>
         <button class = "btn btn-success" id = "countbtn">Click here</button>
         <script src = "./view.js" ></script>
      </div>
   </body>
</html>
*view.js* を作成し、その中にクリックカウンターロジックを入力します-
let $ = require('jquery') //jQuery now loaded and assigned to $
let count = 0
$('#click-counter').text(count.toString())
$('#countbtn').on('click', () => {
   count ++
   $('#click-counter').text(count)
})

次のコマンドを使用してアプリを実行します-

$ electron ./main.js

上記のコマンドは、次のスクリーンショットのように出力を生成します-

UI

Webサイトを構築するのと同じように、ネイティブアプリを構築できます。 ユーザーを正確なウィンドウサイズに制限したくない場合は、レスポンシブデザインを活用して、ユーザーがアプリを柔軟に使用できるようにすることができます。

Electron-ファイル処理

ファイル処理は、デスクトップアプリケーションを構築する上で非常に重要な部分です。 ほとんどすべてのデスクトップアプリはファイルと対話します。

入力として名前と電子メールアドレスを受け取るフォームをアプリに作成します。 このフォームはファイルに保存され、これを出力として表示するリストが作成されます。

*main.js* ファイルで次のコードを使用してメインプロセスを設定します-
const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

app.on('ready', createWindow)
*indexl* ファイルを開いて、次のコードを入力します-
<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>File System</title>
      <link rel = "stylesheet"
         href = "./bower_components/bootstrap/dist/css/bootstrap.min.css"/>

      <style type = "text/css">
         #contact-list {
            height: 150px;
            overflow-y: auto;
         }
      </style>
   </head>

   <body>
      <div class = "container">
         <h1>Enter Names and Email addresses of your contacts</h1>
         <div class = "form-group">
            <label for = "Name">Name</label>
            <input type = "text" name = "Name" value = "" id = "Name"
               placeholder = "Name" class = "form-control" required>
         </div>

         <div class = "form-group">
            <label for = "Email">Email</label>
            <input type = "email" name = "Email" value = "" id = "Email"
               placeholder = "Email" class = "form-control" required>
         </div>

         <div class = "form-group">
            <button class = "btn btn-primary" id = "add-to-list">Add to list!</button>
         </div>

         <div id = "contact-list">
            <table class = "table-striped" id = "contact-table">
               <tr>
                  <th class = "col-xs-2">S. No.</th>
                  <th class = "col-xs-4">Name</th>
                  <th class = "col-xs-6">Email</th>
               </tr>
            </table>
         </div>

         <script src = "./view.js" ></script>
      </div>
   </body>
</html>

次に、追加イベントを処理する必要があります。 これは view.js ファイルで行います。

最初にファイルから連絡先を読み込む関数_loadAndDisplayContacts()_を作成します。 _loadAndDisplayContacts()_関数を作成したら、[リストに追加]ボタンにクリックハンドラーを作成します。 これにより、ファイルとテーブルの両方にエントリが追加されます。

あなたのview.jsファイルでは、次のコードを入力してください-

let $ = require('jquery')
let fs = require('fs')
let filename = 'contacts'
let sno = 0

$('#add-to-list').on('click', () => {
   let name = $('#Name').val()
   let email = $('#Email').val()

   fs.appendFile('contacts', name + ',' + email + '\n')

   addEntry(name, email)
})

function addEntry(name, email) {
   if(name && email) {
      sno++
      let updateString = '<tr><td>'+ sno + '</td><td>'+ name +'</td><td>'
         + email +'</td></tr>'
      $('#contact-table').append(updateString)
   }
}

function loadAndDisplayContacts() {

  //Check if file exists
   if(fs.existsSync(filename)) {
      let data = fs.readFileSync(filename, 'utf8').split('\n')

      data.forEach((contact, index) => {
         let [ name, email ] = contact.split(',')
         addEntry(name, email)
      })

   } else {
      console.log("File Doesn\'t Exist. Creating new file.")
      fs.writeFile(filename, '', (err) => {
         if(err)
            console.log(err)
      })
   }
}

loadAndDisplayContacts()

今、次のコマンドを使用して、アプリケーションを実行します-

$ electron ./main.js

あなたがそれにいくつかの連絡先を追加すると、アプリケーションは次のようになります-

ファイル

  • fsモジュールAPI呼び出し*の詳細については、リンク:/nodejs/nodejs_file_system [ノードファイルシステムのチュートリアル]を参照してください。

これで、Electronを使用してファイルを処理できます。 ダイアログの章で、ファイルの保存および開くダイアログボックス(ネイティブ)を呼び出す方法について説明します。

Electron-ネイティブノードライブラリ

前の章でノードモジュールfsを使用しました。 ここでは、Electronで使用できる他のノードモジュールをいくつか見ていきます。

OSモジュール

OSモジュールを使用すると、アプリケーションが実行されているシステムに関する多くの情報を取得できます。 以下は、アプリの作成中に役立ついくつかのメソッドです。 これらの方法は、実行しているOSに応じてアプリをカスタマイズするのに役立ちます。

Sr.No Function & Description
1

os.userInfo([options])

  • os.userInfo()*メソッドは、現在有効なユーザーに関する情報を返します。 この情報は、明示的に情報を要求しなくても、ユーザー向けにアプリケーションをパーソナライズするために使用できます。
2

os.platform()

  • os.platform()*メソッドは、オペレーティングシステムプラットフォームを識別する文字列を返します。 これを使用して、ユーザーOSに応じてアプリをカスタマイズできます。
3

os.homedir()

  • os.homedir()*メソッドは、現在のユーザーのホームディレクトリを文字列として返します。 通常、すべてのユーザーの構成は、ユーザーのホームディレクトリにあります。 したがって、これはアプリの同じ目的で使用できます。
4

os.arch()

  • os.arch()*メソッドは、オペレーティングシステムのCPUアーキテクチャを識別する文字列を返します。 これは、エキゾチックなアーキテクチャで実行しているときにアプリケーションをそのシステムに適合させるために使用できます。
5

os.EOL

オペレーティングシステム固有の行末マーカーを定義する文字列定数。 これは、ホストOS上のファイル内の行を終了するたびに使用する必要があります。

同じmain.jsファイルと次のHTMLファイルを使用して、画面にこれらのプロパティを印刷できます-

<html>
   <head>
      <title>OS Module</title>
   </head>

   <body>
      <script>
         let os = require('os')
         document.write('User Info: ' + JSON.stringify(os.userInfo()) + '<br>' +
            'Platform: ' + os.platform() + '<br>' +
            'User home directory: ' +  os.homedir() + '<br>' +
            'OS Architecture: ' + os.arch() + '<br>')
      </script>
   </body>
</html>

今、次のコマンドを使用してアプリを実行します-

$ electron ./main.js

上記のコマンドは、次の出力を生成します-

User Info: {"uid":1000,"gid":1000,"username":"ayushgp","homedir":"/home/ayushgp",
   "shell":"/usr/bin/zsh"}
Platform: linux
User home directory:/home/ayushgp
OS Architecture: x64

ネットモジュール

netモジュールは、アプリでのネットワーク関連の作業に使用されます。 このモジュールを使用して、サーバーとソケットの両方の接続を作成できます。 一般に、ネットワーク関連のタスクにnetモジュールを使用するよりも、npmのラッパーモジュールを使用することをお勧めします。

次の表は、モジュールから最も有用なメソッドをリストします-

Sr.No Function & Description
1

net.createServer([options][, connectionListener])

新しいTCPサーバーを作成します。 connectionListener引数は、「connection」イベントのリスナーとして自動的に設定されます。

2

net.createConnection(options[, connectionListener])

新しい 'net.Socket’を返し、指定されたアドレスとポートに接続するファクトリメソッド。

3

net.Server.listen(port[, host][, backlog][, callback])

指定されたポートとホストで接続の受け入れを開始します。 ホストを省略すると、サーバーは任意のIPv4アドレスへの接続を受け入れます。

4

net.Server.close([callback])

すべての接続が終了し、サーバーが「close」イベントを発行すると、最終的に閉じられます。

5

net.Socket.connect(port[, host][, connectListener])

指定されたソケットの接続を開きます。 ポートとホストが指定されている場合、ソケットはTCPソケットとして開かれます。

netモジュールには、他にもいくつかの方法があります。 より包括的なリストを取得するには、link:/nodejs/nodejs_net_module [this]を参照してください。

次に、netモジュールを使用してサーバーへの接続を作成するelectronアプリを作成します。 新しいファイル server.js を作成する必要があります-

var net = require('net');
var server = net.createServer(function(connection) {
   console.log('Client Connected');

   connection.on('end', function() {
      console.log('client disconnected');
   });

   connection.write('Hello World!\r\n');
   connection.pipe(connection);
});

server.listen(8080, function() {
   console.log('Server running on http://localhost:8080');
});

同じmain.jsファイルを使用して、HTMLファイルを次のように置き換えます-

<html>
   <head>
      <title>net Module</title>
   </head>

   <body>
      <script>
         var net = require('net');
         var client = net.connect({port: 8080}, function() {
            console.log('Connection established!');
         });

         client.on('data', function(data) {
            document.write(data.toString());
            client.end();
         });

         client.on('end', function() {
            console.log('Disconnected :(');
         });
      </script>
   </body>
</html>

次のコマンドを使用してサーバーを実行します-

$ node server.js

次のコマンドを使用してアプリケーションを実行します-

$ electron ./main.js

上記のコマンドは、次の出力を生成します-

ネットモジュール

サーバーに自動的に接続し、自動的に切断されることにも注意してください。

また、Electronを使用してフロントエンドで直接使用できる他のノードモジュールもいくつかあります。 これらのモジュールの使用法は、使用するシナリオによって異なります。

電子-プロセス間通信

Electronは、 ipcMain および ipcRenderer と呼ばれる2つのIPC(プロセス間通信)モジュールを提供します。

*ipcMain* モジュールは、メインプロセスからレンダラープロセスに非同期で通信するために使用されます。 メインプロセスで使用される場合、モジュールはレンダラープロセス(Webページ)から送信される非同期および同期メッセージを処理します。 レンダラーから送信されたメッセージは、このモジュールに送信されます。
*ipcRenderer* モジュールは、レンダラープロセスからメインプロセスに非同期で通信するために使用されます。 レンダラープロセス(Webページ)からメインプロセスに同期および非同期メッセージを送信できるように、いくつかのメソッドが用意されています。 メインプロセスから返信を受け取ることもできます。

上記のモジュールを使用して互いにメッセージを送信するメインプロセスとレンダラープロセスを作成します。

次の内容で main_process.js という新しいファイルを作成します-

const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')
const {ipcMain} = require('electron')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

//Event handler for asynchronous incoming messages
ipcMain.on('asynchronous-message', (event, arg) => {
   console.log(arg)

  //Event emitter for sending asynchronous messages
   event.sender.send('asynchronous-reply', 'async pong')
})

//Event handler for synchronous incoming messages
ipcMain.on('synchronous-message', (event, arg) => {
   console.log(arg)

  //Synchronous event emmision
   event.returnValue = 'sync pong'
})

app.on('ready', createWindow)

新しい indexl ファイルを作成し、次のコードを追加します。

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

   <body>
      <script>
         const {ipcRenderer} = require('electron')

        //Synchronous message emmiter and handler
         console.log(ipcRenderer.sendSync('synchronous-message', 'sync ping'))

        //Async message handler
         ipcRenderer.on('asynchronous-reply', (event, arg) => {
            console.log(arg)
         })

        //Async message sender
         ipcRenderer.send('asynchronous-message', 'async ping')
      </script>
   </body>
</html>

次のコマンドを使用してアプリを実行します-

$ electron ./main_process.js

上記のコマンドは、次の出力を生成します-

//On your app console
Sync Pong
Async Pong

//On your terminal where you ran the app
Sync Ping
Async Ping

レンダラープロセスで重いタスクやブロッキングタスクの計算を実行しないことをお勧めします。 これらのタスクをメインプロセスに委任するには、常にIPCを使用します。 これは、アプリケーションのペースを維持するのに役立ちます。

Electron-システムダイアログ

すべてのアプリがユーザーフレンドリーなものであることが非常に重要です。 そのため、alert()呼び出しを使用してダイアログボックスを作成しないでください。 Electronは、ダイアログボックスを作成するタスクを達成するための非常に優れたインターフェースを提供します。 それを見てみましょう。

Electronは、ファイルを開いたり保存したりするためのネイティブシステムダイアログの表示、警告などに使用できる*ダイアログ*モジュールを提供します。

例に直接ジャンプして、簡単なテキストファイルを表示するアプリを作成しましょう。

新しいmain.jsファイルを作成し、その中に次のコードを入力します-

const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')
const {ipcMain} = require('electron')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

ipcMain.on('openFile', (event, path) => {
   const {dialog} = require('electron')
   const fs = require('fs')
   dialog.showOpenDialog(function (fileNames) {

     //fileNames is an array that contains all the selected
      if(fileNames === undefined) {
         console.log("No file selected");

      } else {
         readFile(fileNames[0]);
      }
   });

   function readFile(filepath) {
      fs.readFile(filepath, 'utf-8', (err, data) => {

         if(err){
            alert("An error ocurred reading the file :" + err.message)
            return
         }

        //handle the file content
         event.sender.send('fileData', data)
      })
   }
})
app.on('ready', createWindow)

このコードは、メインプロセスがレンダラープロセスから「openFile」メッセージを受信するたびに、開いているダイアログボックスをポップします。 このメッセージは、ファイルコンテンツをレンダラープロセスにリダイレクトします。 次に、コンテンツを印刷する必要があります。

ここで、次の内容で新しい indexl ファイルを作成します-

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>File read using system dialogs</title>
   </head>

   <body>
      <script type = "text/javascript">
         const {ipcRenderer} = require('electron')
         ipcRenderer.send('openFile', () => {
            console.log("Event sent.");
         })

         ipcRenderer.on('fileData', (event, data) => {
            document.write(data)
         })
      </script>
   </body>
</html>

これで、アプリを実行するたびに、次のスクリーンショットに示すように、ネイティブのオープンダイアログボックスがポップアップ表示されます-

ダイアログを開く

表示するファイルを選択すると、その内容がアプリウィンドウに表示されます-

ダイアログを使用したファイル読み取り

これは、Electronが提供する4つのダイアログの1つにすぎません。 しかし、それらはすべて同様の使用法を持っています。 showOpenDialog を使用してその方法を学習したら、他のダイアログを使用できます。

同じ機能を持つダイアログは-

  • showSaveDialog([browserWindow、] options [、callback])
  • showMessageDialog([browserWindow、] options [、callback])
  • showErrorDialog(title、content)

Electron-メニュー

デスクトップアプリには2つのタイプのメニューがあります-アプリケーションメニュー(トップバー上)と*コンテキストメニュー*(右クリックメニュー)。 この章では、これらの両方を作成する方法を学習します。

_Menu_および_MenuItem_モジュールの2つのモジュールを使用します。 _Menu_および_MenuItem_モジュールは、メインプロセスでのみ使用できることに注意してください。 レンダラープロセスでこれらのモジュールを使用するには、_remote_モジュールが必要です。 これは、コンテキストメニューを作成するときに発生します。

さて、メインプロセス用の新しい main.js ファイルを作成しましょう-

const {app, BrowserWindow, Menu, MenuItem} = require('electron')
const url = require('url')
const path = require('path')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

const template = [
   {
      label: 'Edit',
      submenu: [
         {
            role: 'undo'
         },
         {
            role: 'redo'
         },
         {
            type: 'separator'
         },
         {
            role: 'cut'
         },
         {
            role: 'copy'
         },
         {
            role: 'paste'
         }
      ]
   },

   {
      label: 'View',
      submenu: [
         {
            role: 'reload'
         },
         {
            role: 'toggledevtools'
         },
         {
            type: 'separator'
         },
         {
            role: 'resetzoom'
         },
         {
            role: 'zoomin'
         },
         {
            role: 'zoomout'
         },
         {
            type: 'separator'
         },
         {
            role: 'togglefullscreen'
         }
      ]
   },

   {
      role: 'window',
      submenu: [
         {
            role: 'minimize'
         },
         {
            role: 'close'
         }
      ]
   },

   {
      role: 'help',
      submenu: [
         {
            label: 'Learn More'
         }
      ]
   }
]

const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
app.on('ready', createWindow)

ここでは、テンプレートからメニューを構築しています。 これは、関数にJSONとしてメニューを提供し、残りを処理することを意味します。 次に、このメニューをアプリケーションメニューとして設定する必要があります。

次に、indexlという空のHTMLファイルを作成し、このアプリケーションを実行します-

$ electron ./main.js

アプリケーションメニューの通常の位置に、上記のテンプレートに基づいたメニューが表示されます。

アプリケーションメニュー

このメニューはメインプロセスから作成しました。 アプリのコンテキストメニューを作成しましょう。 HTMLファイルでこれを行います-

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>Menus</title>
   </head>

   <body>
      <script type = "text/javascript">
         const {remote} = require('electron')
         const {Menu, MenuItem} = remote

         const menu = new Menu()

        //Build menu one item at a time, unlike
         menu.append(new MenuItem ({
            label: 'MenuItem1',
            click() {
               console.log('item 1 clicked')
            }
         }))

         menu.append(new MenuItem({type: 'separator'}))
         menu.append(new MenuItem({label: 'MenuItem2', type: 'checkbox', checked: true}))
         menu.append(new MenuItem ({
            label: 'MenuItem3',
            click() {
               console.log('item 3 clicked')
            }
         }))

        //Prevent default action of right click in chromium. Replace with our menu.
         window.addEventListener('contextmenu', (e) => {
            e.preventDefault()
            menu.popup(remote.getCurrentWindow())
         }, false)
      </script>
   </body>
</html>

リモートモジュールを使用して、MenuおよびMenuItemモジュールをインポートしました。次に、メニューを作成し、メニュー項目を1つずつ追加しました。 さらに、クロムでの右クリックのデフォルトアクションを防止し、メニューに置き換えました。

コンテキストメニュー

Electronでのメニューの作成は非常に簡単な作業です。 これで、これらのアイテムにイベントハンドラーをアタッチし、必要に応じてイベントを処理できます。

電子-システムトレイ

システムトレイは、アプリケーションウィンドウ外のメニューです。 MacOSおよびUbuntuでは、画面の右上隅にあります。 Windowsでは、右下隅にあります。 Electronを使用して、システムトレイにアプリケーションのメニューを作成できます。

新しい main.js ファイルを作成し、次のコードを追加します。 システムトレイアイコンに使用できるpngファイルを用意します。

const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

app.on('ready', createWindow)

基本的なブラウザウィンドウをセットアップした後、次の内容で新しい indexl ファイルを作成します-

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>Menus</title>
   </head>
   <body>
      <script type = "text/javascript">
         const {remote} = require('electron')
         const {Tray, Menu} = remote
         const path = require('path')

         let trayIcon = new Tray(path.join('','/home/ayushgp/Desktop/images.png'))

         const trayMenuTemplate = [
            {
               label: 'Empty Application',
               enabled: false
            },

            {
               label: 'Settings',
               click: function () {
                  console.log("Clicked on settings")
               }
            },

            {
               label: 'Help',
               click: function () {
                  console.log("Clicked on Help")
               }
            }
         ]

         let trayMenu = Menu.buildFromTemplate(trayMenuTemplate)
         trayIcon.setContextMenu(trayMenu)
      </script>
   </body>
</html>

Trayサブモジュールを使用してトレイを作成しました。 次に、テンプレートを使用してメニューを作成し、さらにメニューをトレイオブジェクトに添付しました。

次のコマンドを使用してアプリケーションを実行します-

$ electron ./main.js

上記のコマンドを実行するとき、使用したアイコンのシステムトレイを確認します。 私はアプリケーションにスマイリーフェイスを使用しました。 上記のコマンドは、次の出力を生成します-

トレイ

電子-通知

Electronは、MacOS専用のネイティブ通知APIを提供します。 そのため、これを使用するのではなく、_node-notifier_というnpmモジュールを使用します。 Windows、MacOS、Linuxのユーザーに通知できます。

そのフォルダで次のコマンドを使用して、アプリフォルダにノード通知モジュールをインストールします-

$ npm install --save node-notifier

このボタンをクリックするたびに通知を生成するボタンを持つアプリを作成しましょう。

新しい main.js ファイルを作成し、次のコードを入力します-

const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

app.on('ready', createWindow)

次に、通知をトリガーするWebページとスクリプトを作成しましょう。 次のコードで新しい indexl ファイルを作成します-

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>Menus</title>
   </head>

   <body>
      <button type = "button" id = "notify" name = "button">
         Click here to trigger a notification!</button>
      <script type = "text/javascript">
         const notifier = require('node-notifier')
         const path = require('path');

         document.getElementById('notify').onclick = (event) => {
            notifier.notify ({
               title: 'My awesome title',
               message: 'Hello from electron, Mr. User!',
               icon: path.join('','/home/ayushgp/Desktop/images.png'), //Absolute path
                  (doesn't work on balloons)
               sound: true, //Only Notification Center or Windows Toasters
               wait: true   //Wait with callback, until user action is taken
               against notification

            }, function (err, response) {
              //Response is response from notification
            });

            notifier.on('click', function (notifierObject, options) {
               console.log("You clicked on the notification")
            });

            notifier.on('timeout', function (notifierObject, options) {
               console.log("Notification timed out!")
            });
         }
      </script>
   </body>
</html>
*notify* メソッドを使用すると、タイトル、メッセージ、サムネイルなどの *objectwith* 情報を渡すことができます。 通知のカスタマイズに役立ちます。 通知にイベントリスナーを設定することもできます。

今、次のコマンドを使用してアプリを実行します-

$ electron ./main.js

作成したボタンをクリックすると、次のスクリーンショットに示すように、オペレーティングシステムからのネイティブ通知が表示されます-

通知

また、ユーザーが通知をクリックするか、通知がタイムアウトするイベントも処理しました。 これらのメソッドは、アプリがバックグラウンドで実行されている場合、アプリをよりインタラクティブにするのに役立ちます。

Electron-Webview

webviewタグは、ElectronアプリにWebページのような「ゲスト」コンテンツを埋め込むために使用されます。 このコンテンツは、webviewコンテナー内に含まれています。 アプリ内の埋め込みページは、このコンテンツの表示方法を制御します。

WebViewは、アプリとは別のプロセスで実行されます。 悪意のあるコンテンツからのセキュリティを確保するために、WebビューにはWebページと同じ権限がありません。 これにより、埋め込みコンテンツからアプリを安全に保ちます。 アプリと埋め込みページの間のすべての対話は非同期になります。

Electronアプリへの外部Webページの埋め込みを理解するための例を考えてみましょう。 右側のアプリにfinddevguides Webサイトを埋め込みます。 次の内容で新しい main.js ファイルを作成します-

const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

app.on('ready', createWindow)

メインプロセスを設定したので、finddevguides Webサイトを埋め込むHTMLファイルを作成します。 次の内容でindexlと呼ばれるファイルを作成します-

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>Menus</title>
   </head>

   <body>
      <div>
         <div>
            <h2>We have the website embedded below!</h2>
         </div>
         <webview id = "foo" src = "https://www.finddevguides.com/" style =
            "width:400px; height:480px;">
            <div class = "indicator"></div>
         </webview>
      </div>

      <script type = "text/javascript">
        //Event handlers for loading events.
        //Use these to handle loading screens, transitions, etc
         onload = () => {
            const webview = document.getElementById('foo')
            const indicator = document.querySelector('.indicator')

            const loadstart = () => {
               indicator.innerText = 'loading...'
            }

            const loadstop = () => {
               indicator.innerText = ''
            }

            webview.addEventListener('did-start-loading', loadstart)
            webview.addEventListener('did-stop-loading', loadstop)
         }
      </script>
   </body>
</html>

次のコマンドを使用してアプリを実行します-

$ electron ./main.js

上記のコマンドは、次の出力を生成します-

Webview

webviewタグは、他のリソースにも使用できます。 webview要素には、公式ドキュメントにリストされているイベントのリストがあります。 これらのイベントを使用して、Webビューで行われることに応じて機能を改善できます。

インターネットからスクリプトやその他のリソースを埋め込むときは、常にwebviewを使用することをお勧めします。 これは、大きなセキュリティ上の利点があり、通常の動作を妨げないため、推奨されます。

Electron-オーディオとビデオのキャプチャ

画面共有、音声メモなどのアプリを構築している場合、オーディオとビデオのキャプチャは重要な特性です。 また、プロファイル画像をキャプチャするアプリケーションが必要な場合にも便利です。

Electronでオーディオおよびビデオストリームをキャプチャするには、getUserMedia HTML5 APIを使用します。 次のように、 main.js ファイルでメインプロセスを最初にセットアップしましょう-

const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')

let win

//Set the path where recordings will be saved
app.setPath("userData", __dirname + "/saved_recordings")

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

app.on('ready', createWindow)

メインプロセスを設定したので、このコンテンツをキャプチャするHTMLファイルを作成しましょう。 次の内容で indexl と呼ばれるファイルを作成します-

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>Audio and Video</title>
   </head>

   <body>
      <video autoplay></video>
      <script type = "text/javascript">
         function errorCallback(e) {
            console.log('Error', e)
         }

         navigator.getUserMedia({video: true, audio: true}, (localMediaStream) => {
            var video = document.querySelector('video')
            video.src = window.URL.createObjectURL(localMediaStream)
            video.onloadedmetadata = (e) => {
              //Ready to go. Do some stuff.
            };
         }, errorCallback)
      </script>
   </body>
</html>

上記のプログラムは、次の出力を生成します-

オーディオおよびビデオストリーム

これで、ウェブカメラとマイクの両方からストリームを取得できました。 このストリームをネットワーク経由で送信したり、好みの形式で保存したりできます。

MDN Documentationをご覧になり、ウェブカメラから画像を取得して保存してください。 これは、HTML5 getUserMedia APIを使用して行われました。 Electronに付属の_desktopCapturer_モジュールを使用して、ユーザーのデスクトップをキャプチャすることもできます。 次に、画面ストリームを取得する方法の例を見てみましょう。

上記と同じmain.jsファイルを使用し、次の内容になるようにindexlファイルを編集します-

desktopCapturer.getSources({types: ['window', 'screen']}, (error, sources) => {
   if (error) throw error
   for (let i = 0; i < sources.length; ++i) {
      if (sources[i].name === 'Your Window Name here!') {
         navigator.webkitGetUserMedia({
            audio: false,
            video: {
               mandatory: {
                  chromeMediaSource: 'desktop',
                  chromeMediaSourceId: sources[i].id,
                  minWidth: 1280,
                  maxWidth: 1280,
                  minHeight: 720,
                  maxHeight: 720
               }
            }
         }, handleStream, handleError)
         return
      }
   }
})

function handleStream (stream) {
   document.querySelector('video').src = URL.createObjectURL(stream)
}

function handleError (e) {
   console.log(e)
}

_desktopCapturer_モジュールを使用して、開いている各ウィンドウに関する情報を取得しました。 これで、上記の* ifステートメント*に渡す名前に応じて、特定のアプリケーションまたは画面全体のイベントをキャプチャできます。 これにより、その画面で発生しているもののみがアプリにストリーミングされます。

デスクトップキャプチャ

https://stackoverflow.com/questions/36753288/saving-desktopcapturer-to-video-file-in-electron [このStackOverflowの質問]を参照して、使用方法を詳細に理解できます。

Electron-ショートカットの定義

通常、PCで毎日使用するすべてのアプリの特定のショートカットを記憶しています。 ユーザーが直感的で簡単にアクセスできるようにアプリケーションを作成するには、ユーザーがショートカットを使用できるようにする必要があります。

globalShortcutモジュールを使用して、アプリのショートカットを定義します。 Accelerators は、+文字で結合された複数の修飾子とキーコードを含むことができる文字列であることに注意してください。 これらのアクセラレータは、アプリケーション全体でキーボードショートカットを定義するために使用されます。

例を考えて、ショートカットを作成しましょう。 このため、ファイルを開くために開いたダイアログボックスを使用したダイアログボックスの例に従います。 CommandOrControl + O ショートカットを登録して、ダイアログボックスを表示します。

*main.js* コードは以前と同じままです。 新しい *main.js* ファイルを作成し、その中に次のコードを入力してください-
const {app, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')
const {ipcMain} = require('electron')

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'indexl'),
      protocol: 'file:',
      slashes: true
   }))
}

ipcMain.on('openFile', (event, path) => {
   const {dialog} = require('electron')
   const fs = require('fs')
   dialog.showOpenDialog(function (fileNames) {

     //fileNames is an array that contains all the selected
      if(fileNames === undefined)
         console.log("No file selected")
      else
         readFile(fileNames[0])
   })

   function readFile(filepath){
      fs.readFile(filepath, 'utf-8', (err, data) => {
         if(err){
            alert("An error ocurred reading the file :" + err.message)
            return
         }

        //handle the file content
         event.sender.send('fileData', data)
      })
   }
})

app.on('ready', createWindow)

このコードは、メインプロセスがレンダラープロセスから「openFile」メッセージを受け取るたびに、開いているダイアログボックスをポップします。 以前、このダイアログボックスは、アプリが実行されるたびにポップアップ表示されました。 CommandOrControl + O を押したときにのみ開くように制限しましょう。

ここで、次の内容で新しい indexl ファイルを作成します-

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8">
      <title>File read using system dialogs</title>
   </head>

   <body>
      <p>Press CTRL/CMD + O to open a file. </p>
      <script type = "text/javascript">
         const {ipcRenderer, remote} = require('electron')
         const {globalShortcut} = remote
         globalShortcut.register('CommandOrControl+O', () => {
            ipcRenderer.send('openFile', () => {
               console.log("Event sent.");
            })

            ipcRenderer.on('fileData', (event, data) => {
               document.write(data)
            })
         })
      </script>
   </body>
</html>

新しいショートカットを登録し、このショートカットを押すたびに実行されるコールバックを渡しました。 ショートカットは、必要に応じて登録解除できます。

これで、アプリを開くと、先ほど定義したショートカットを使用してファイルを開くようメッセージが表示されます。

ダイアログを開く

これらのショートカットは、ユーザーが定義済みのアクションに対して独自のショートカットを選択できるようにすることで、カスタマイズ可能にすることができます。

電子-環境変数

環境変数は、コードを変更せずにアプリケーションの構成と動作を制御します。 特定のElectronの動作は、コマンドラインフラグやアプリのコードよりも早く初期化されるため、環境変数によって制御されます。

electronでエンコードされた環境変数には、*生産変数*と*開発変数*の2種類があります。

生産変数

次の環境変数は、パッケージ化されたElectronアプリケーションで実行時に使用するためのものです。

Sr.No Variable & Description
1

GOOGLE_API_KEY

Electronには、Googleのジオコーディングウェブサービスにリクエストを送信するためのハードコードされたAPIキーが含まれています。 このAPIキーは、Electronのすべてのバージョンに含まれているため、多くの場合、使用クォータを超えています。

これを回避するには、環境内で独自のGoogle APIキーを提供できます。 ジオコーディングリクエストを行うブラウザウィンドウを開く前に、メインプロセスファイルに次のコードを配置します-

process.env.GOOGLE_API_KEY = 'YOUR_KEY_HERE'
2

ELECTRON_RUN_AS_NODE

通常のNode.jsプロセスとしてプロセスを開始します。

3

ELECTRON_FORCE_WINDOW_MENU_BAR (Linux Only)

Linuxではグローバルメニューバーを使用しないでください。

開発変数

次の環境変数は、主に開発およびデバッグを目的としています。

Sr.No Variable & Description
1

ELECTRON_ENABLE_LOGGING

Chromeの内部ログをコンソールに出力します。

2

ELECTRON_ENABLE_STACK_DUMPING

Electronがクラッシュしたときにスタックトレースをコンソールに出力します。

3

ELECTRON_DEFAULT_ERROR_MODE

ElectronがクラッシュしたときにWindowsのクラッシュダイアログを表示します。

これらの環境変数のいずれかをtrueに設定するには、コンソールで設定します。 たとえば、ロギングを有効にする場合は、次のコマンドを使用します-

Windowsの場合

> set ELECTRON_ENABLE_LOGGING=true

Linuxの場合

$ export ELECTRON_ENABLE_LOGGING=true

コンピュータを再起動するたびに、これらの環境変数を設定する必要があることに注意してください。 回避したい場合は、これらの行を .bashrc ファイルに追加してください。

Electron-デバッグ

アプリケーションを実行する2つのプロセス、メインプロセスとレンダラープロセスがあります。

レンダラープロセスはブラウザウィンドウで実行されるプロセスなので、Chrome Devtoolsを使用してデバッグできます。 DevToolsを開くには、ショートカット「Ctrl + Shift + I」または<F12>キーを使用します。 devtools こちらの使用方法を確認できます。

DevToolsを開くと、アプリは次のスクリーンショットに示すようになります-

DevTools

メインプロセスのデバッグ

ElectronブラウザーウィンドウのDevToolsは、そのウィンドウ(つまりWebページ)で実行されるJavaScriptのみをデバッグできます。 メインプロセスで実行されるJavaScriptをデバッグするには、外部デバッガーを使用し、-- debug_または-- debug-brk_スイッチを使用してElectronを起動する必要があります。

Electronは、指定されたポートでV8デバッガープロトコルメッセージをリッスンします。外部デバッガーはこのポートに接続する必要があります。 デフォルトのポートは5858です。

次を使用してアプリを実行します-

$ electron --debug = 5858 ./main.js

次に、V8デバッガープロトコルをサポートするデバッガーが必要になります。 この目的には、VSCodeまたはノードインスペクターを使用できます。 たとえば、次の手順に従って、この目的のためにVSCodeをセットアップします。 それを設定するには、次の手順に従ってください-

VSCodeをダウンロードしてインストールします。 ElectronプロジェクトをVSCodeで開きます。

次の構成でファイル .vscode/launch.json を追加します-

{
   "version": "1.0.0",
   "configurations": [
      {
         "name": "Debug Main Process",
         "type": "node",
         "request": "launch",
         "cwd": "${workspaceRoot}",
         "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
         "program": "${workspaceRoot}/main.js"
      }
   ]
}

-Windowsの場合、 runtimeExecutable には "$ \ {workspaceRoot}/node_modules/.bin/electron.cmd" を使用します。

*main.js* にいくつかのブレークポイントを設定し、デバッグビューでデバッグを開始します。 あなたがブレークポイントをヒットすると、画面は次のようになります-

デバッガ

VSCodeデバッガーは非常に強力で、エラーをすばやく修正するのに役立ちます。 Electronアプリをデバッグするための node-inspector のような他のオプションもあります。

Electron-パッケージングアプリ

アプリのパッケージ化と配布は、デスクトップアプリケーションの開発プロセスの不可欠な部分です。 Electronはクロスプラットフォームのデスクトップアプリケーション開発フレームワークであるため、すべてのプラットフォーム向けのアプリのパッケージングと配布もシームレスなエクスペリエンスでなければなりません。

Electronコミュニティは、https://github.com/electron-userland/electron-packager [electron-packager]というプロジェクトを作成しました。 これにより、JSまたはCLIを介して、ElectronアプリをOS固有のバンドル(.app、.exeなど)でパッケージ化して配布できます。

サポートされているプラ​​ットフォーム

Electron Packagerは、次のホストプラットフォームで実行されます-

  • Windows(32/64ビット)
  • OS X
  • Linux(x86/x86_64)

次のターゲットプラットフォームの実行可能ファイル/バンドルを生成します-

  • Windows(32/64ビットの両方でwin32とも呼ばれます)
  • OS X(ダーウィンとも呼ばれます)/Mac App Store(マスとも呼ばれます)
  • Linux(x86、x86_64、およびarmv7lアーキテクチャ用)

インストール

を使用して電子パッケージャーをインストールします-

# for use in npm scripts
$ npm install electron-packager --save-dev

# for use from cli
$ npm install electron-packager -g

アプリのパッケージ化

このセクションでは、コマンドラインからパッケージャーを実行する方法を説明します。 コマンドの基本的な形式は-

electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> [optional flags...]

これは-

  • Electronの正しいリリースを見つけるかダウンロードしてください。
  • Electronのバージョンを使用して、<output-folder>/<appname>-<platform>-<arch>にアプリを作成します。

-platform *および-arch は、2つの場合に省略できます。 代わりに-all *を指定すると、ターゲットプラットフォーム/アーキテクチャのすべての有効な組み合わせのバンドルが作成されます。 それ以外の場合、ホストプラットフォーム/アーキテクチャの単一のバンドルが作成されます。

電子-リソース

Electronの詳細については、次のリソースを使用しました。 このチュートリアルの作成中にこれらを参照しました。

最も重要なリソースは、https://electron.atom.io/docs [Electron documentation]です。このドキュメントには、フレームワークのほぼすべての機能と癖が広範囲に網羅されています。 アプリを作成するのに十分なのは彼らだけです。

electron-sample-appsリポジトリには、非常に優れたElectronの例もいくつかあります。

ビデオリソース

Web言語を使用したデスクトップアプリ

JavaScriptとElectronを使用した高速クロスプラットフォームデスクトップアプリ開発

ブログ投稿

Electronを使用したデスクトップアプリケーションの構築

React&Electronで音楽プレーヤーを構築

HTML、JS、Electronを使用した最初のデスクトップアプリの作成

Electronを使用したクロスプラットフォームデスクトップノードアプリの作成