はじめに
を参考に、とりあえず書いて真似させていただきながら書き方を勉強していました。
しかし、「アプリっぽく」の
'use strict';
//electronの読み込みができない
const electron = require('electron');
const remote = electron.remote;
const fileUtil = remote.require('./lib/fileUtil');
//当然ここも動かない
fileUtil.fetchReadmeList(function(err, matches) {
if(!err) document.write(matches.join());
});
のところでconst electronの読み込みがうまく行きませんでした。
改善策
Electronのメインプロセス側で
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
let mainWindow = null;
app.on('window-all-closed', function() {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('ready', function() {
// nodeIntegrationをtrueに!!!
mainWindow = new BrowserWindow({width: 800, height: 600, webPreferences: {
nodeIntegration: true
}});
mainWindow.loadURL('file://' + __dirname + '/index.html');
mainWindow.on('closed', function() {
mainWindow = null;
});
});
nodeIntegrationプロパティをtrueにすると
きちんとHTMLで読み込んだindex.jsから、requireすることができました。
どうしてうまく動かなかったのか?
うまく動かなかった理由は、Electronの仕組みにあります。
プロセス
Electronでは2つのプロセスがあります。
メインプロセスは、Node.jsの機能をすべて触ることのできるものであり、一つのプロセスしかありません。
そして、ユーザからすると目でみることができません。
(見えるとすれば、Macなどでは、左上にあるメニューバーに当たります。)
レンダラープロセスは、ChoroniumからHTMLを読み込んで描画する、いわゆるウィンドウのプロセスです。
当然、ウィンドウは何枚でも出せるので、レンダラープロセスは何個でも作れます。
このレンダラープロセスはメインプロセスから生成されます。
このとき、これらメインプロセスとレンダラープロセスはそれぞれ別々であることに注意してください。
セキュリティ
レンダラープロセスはユーザが触ることができます。
なぜならば、普段自分たちが使っているChromeのように、画面がでます。
そして、キーボードからの入力やマウスクリックを可能とします。
このような性質から、レンダラープロセスでユーザが悪い操作をすると
メインプロセスと同じNode.jsの機能すべてを触ることができます。
Node.jsはfsというディレクトリ管理系も持っているため、すべてのファイルを削除してしまう!ということも可能であり、危険です。
そのため、Electron version5からは
mainWindow = new BrowserWindow({width: 800, height: 600, webPreferences: {
nodeIntegration: false
}});
となっていて、レンダラープロセス、HTML側からはNode.jsの機能が一切使えない、
よってただのChromeで使えるようなECMAJSしか使えないということになります。
この、nodeIntegrationをtrueにすれば、Node.jsの機能も触れるのでrequireなどを使うことができます。
ただし、セキュリティ上の危険が生えます。