Electronアプリで組み込みDBを利用したという場合の選択肢として、SQLite を使用するというのが第1の選択肢として挙がりそうだが、ピュア(?)Javascriptで動作するライブラリを使いたかったので今回はNeDBを使うことにした。
ところがNeDBを画面プログラムで使用するとファイルへのデータ保存ができずIndexedDBをファイルシステムの代わりに使用してデータを保存するという動きとなってしまう。
これを解決するために、以下の2つの問題を解決する必要がある。
- NeDBをElectronの画面(レンダラプロセス)で使用すると、NeDB自身がIndexedDBを利用する挙動を示すため、それを抑える必要がある
- ファイルへのアクセスをするにはNodeJSのライブラリを利用する必要があるが、Electronはメインプロセスとレンダラープロセスという2種類のプロセスがあり、画面が動作するレンダラープロセスではNodeJSが実行できない
1番目の問題は解決するために以下のような方法として例えば以下のような方法がある。
- node_modules にインストールされたNeDBをディレクトリごとコピーして別の場所に配置する。
- コピーしたディレクトリにある package.json から以下を削除し、レンダラプロセスでもメインプロセスと同じ処理が行われるようにする。
"browser": {
"./lib/customUtils.js": "./browser-version/browser-specific/lib/customUtils.js",
"./lib/storage.js": "./browser-version/browser-specific/lib/storage.js"
},
- コピーしたディレクトリで npm install を実行し、必要なモジュールをインストールする。
- 利用するアプリの package.json の dependencies にある nedb の設定値としてバージョン番号ではなく、以下のようなコピーしたディレクトリへのパスを記述する。
"dependencies": {
・・・
"nedb": "file:./nedb-custom",
・・・
},
2番めの問題は、画面を生成する(BrowserWindow を newする)際に nodeIntegration: true というオプションを指定し、レンダラプロセスからNodeJSへのアクセスを許可することで解決できる。
これで、レンダラプロセスでもNeDBを使ってデータをファイル保存することが可能になる。
ただし、セキュリティのことを考えると nodeIntegration: true は使用しないというのがセオリーらしいので、本来はメインプロセス側でNeDBを使用した処理を記述し、IPC(プロセス間通信)によってレンダラープロセスからメインプロセスに処理を委譲すべきだとは思う・・・
そうすることで、そもそもNeDBのカスタマイズ自体が不要になるわけで分かりやすい形にはなると思うが・・・必要なインターフェースをすべて実装していくのは、正直かなり面倒臭い。
このあたりは、作成するアプリの性質に合わせ、どちらの方法を取るべきか考えて実装する必要がありますね。
コメントを残す