サンプル
たのしくなって、基本的なところを実験してみました。
下記に、そのときのサンプルをあげました。
クイックスタートから、プロセス間通信、ファイルの読み込みなどのサンプルですので、これだけわかれば、一通りのことは使えるようになるのではないでしょうか。
下記は、quickstart の説明になります。
クイックスタート
OSは、Linuxを使っています。
前提条件として、下記のツールを入れておいてください。
- nim
- npm
- node.js
話をもどします。
入っていたら、早速はじめましょう。
まず、テスト用のディレクトリをつくって、npm initしましょう。
% mkdir nim-electron-test
% cd nim-electron-test
% npm init -y
package.jsonがつくられたはずです。
つぎに、electronをインストールしましょう。
% npm i -D electron
同じディレクトリに、index.nimという名前で、下記のコードを書いて保存ください。
import jsffi
let electron = require("electron")
let app = electron.app
app.whenReady().then(proc() =
(jsnew electron.BrowserWindow()).loadFile("index.html")
)
app.on("window-all-closed", proc() =
if require("process").platform.to(cstring) != "darwin":
app.quit()
)
require は、jsffi モジュールに入っている、javascriptのライブラリを読み込むもののようです。
参考:( https://nim-lang.org/docs/jsffi.html )
次に、index.htmlに、適当になにか書いてください。
ここでは面倒なのでタグなど書かず、以下のように書いたことにします。
こんにちわ
保存したら、コマンドラインで以下を実行します。
% nim js index.nim
エラーが出ていなければ、index.jsというファイルができています。
できていたら、下記を実行してください。
% npx electron .
一番最後に、ピリオド(.)の入力を忘れないようにしてください。
問題なければ、新しいwindowが開いて、「こんにちわ」と表示したと思います。
さて次にwindowの大きさを変えてみます。
ソースコード(index.nim)の一部に、下記のコードがあります。
(jsnew electron.BrowserWindow()).loadFile("index.html")
ここの「jsnew electron.BrowserWindow()」の()内に、大きさの指定を書きます。
Nimなので、インデントは忘れないように。
(jsnew electron.BrowserWindow(
JsObject{
width: 100,
height: 200
}
)).loadFile("index.html")
保存したら、前述したように、nim js ...して、npx ....を実行してみてください。
小さくなったwindowが開きましたか?
おまけで、preloadも記述します。
preloadがなにかは、ご自身でしらべてください。
index.nimの、大きさ指定したコードにつけたします。
(jsnew electron.BrowserWindow(
JsObject{
width: 100,
height: 200,
webPreferences: JsObject{
preload: "preload.js"
}
}
)).loadFile("index.html")
preload.js は、nimのコードで記述したければ、別途コンパイルが必要になります。
追記ですが、preload.jsは、フルパスで指定する必要があります。
% nim js preload.nim
index.htmlから外部ファイルで読み込みたいソースも、別途コンパイルが必要です。
% nim js renderer.nim
その場合、index.htmlには、以下のように記述が必要でしょう。
<script src="renderer.js"></script>
以上です。
閑話休題
よく、nim+electronで、参考にするのは、下記のサイト?だと思います。
これ、このままだと、electronが起動しません。
package.json内の、electronのバージョンが古すぎて、gconfなんたらがないと文句いわれて落ちます。
調べると、昔のchromeを入れてると自動でインストールされたらしいのですが、今は使わないとのこと。
なので、package.jsonの下記の部分を削除して、(もしくはバージョンを書き換えて)、最新のelectronをインストール必要があります。
"devDependencies": {
"electron": "~1.6.2"
}
また、main.nimも、なぜか、app.nimで作成されたアプリとsocket通信するサンプルになっています。
なので、このままだと、落ちます。
socket通信している部分は削除が必要です。
var client = jsnew net.createConnection(JsObject{ port: 1234 }, proc () =
console.log("Connected to server!")
)
client.write "Hello, world\r\n"
上記2箇所は不要です。
また、不要なモジュールをロードする必要がないので消しましょう。
{.emit: """
const electron = require('electron')
const path = require('path')
const url = require('url')
const net = require('net');
""".}
ここでいえば、一番下のnetは不要です。
これで、上記のサンプルは動作します。
さて、emitですが……(これは、コンパイル時に指定した言語を実行するものらしいです)
jsffiのドキュメントを英語がわからないなりに、ながめていると、requireというプロシージャがあるではないですか。
なので、思い切って、このemitの部分は削除して、直接、requireでelectronをロードしてみたら、うまく動作しました。
最近のelectronだと、BrowserWindowは、loadURL ではなく、loadFileを使うようです。
そうなると、urlモジュールは不要です。consoleは、デバッグする必要がなければ不要でしょうし、そもそも、ふつうにechoでもいけました。(レンダラープロセスで動作するかは不明)
__dirnameや、pathは、お好みでどうぞ、だと思います。
たぶん、こんな感じ。
let dirname {.importc: "__dirname", nodecl.}:cstring
let path = require("path")
dirname ですが、nim はアンダーバーではじまる変数名は使えないので、はずしてあげなきゃいけないです。最初から、cstringにしておけば、dirname.to(cstring) としなくても良いようです。
使う場合は、loadFileの引数で下記のように利用しているようです。loadFromの前は省略。
loadFile(dirname & "/index.html")
# または、
loadFile(path.resolve(dirname, "index.html"))
次にprocessは、一回しか使わないので、
if require("process").platform.to(cstring) != "darwin":
app.quit()
としています。
macで動作することを考慮しないのであれば、このif文は不要です。
蛇足ですが、macはwindowを閉じても、終了しない仕様なので、この判定をしています。
このように、できるかぎり削除していったら、最初の、main.nim ではなくて、index.nimのようになりました。
index.nimにしたのは、単に、npm init したときにできるpackage.jsonのデフォルトがmain.jsだからです。
ところで、自分で書いたコードなのですが、冷静になると、下記のコードはやりすぎ感はあります。
app.whenReady().then(proc() =
(jsnew electron.BrowserWindow()).loadFile("index.html")
)
proc内は、下記のように分けたほうが使い勝手はよいでしょう。
app.whenReady().then(proc() =
let win = jsnew electron.BrowserWindow()
win.loadFile("index.html")
)
他に下記コードは必要か不要か、好みなのかは、意見がわかれるような気がします。
win.on("closed", proc () =
win = nil
)
公式のドキュメントの翻訳だと入れてはいないですね。
なんにせよ、nimで、electronを動かすメリットがどの程度あるのかわかりませんが、参考になれば幸いです。