electron上のreactから外部コマンド(child_process)を使う


概要/要約

electron上のreactから直接ローカル環境にアクセスすることはできない。
一度windowオブジェクトを挟んでrequireすることで解決できる。


const childProcess = window.require("child_process")
childProcess.exec("ls", (error, stdout, stderr) => {
if(error != null){
   console.log(error)
}else{
  console.log(stdout)
}
})

はじめに

electronが参照するhtmlファイルとしてreactによってbuildされたファイルを指定することで、electron上でreactを使うことができる。
https://qiita.com/maecho/items/c34de805101ae489532e
https://qiita.com/tashxii/items/290a3421d520bdae0c36

reactのために蓄積された資源をデスクトップアプリに用いることができるのでとっても便利。
しかし、もともとwebのために作られた技術なのでいろいろ問題もある。

問題点

electronはローカルで動作するアプリケーションであるため、ローカル環境にアクセスすることができる。(ローカルにインストールされたコマンドを実行、ローカルのファイルを扱う、など)
しかし、reactからこのような処理を実行しようとするとエラーとなってしまう。


const childProcess = require("child_process")
childProcess.exec("ls", (error, stdout, stderr) => {
if(error != null){
   console.log(error)
}else{
  console.log(stdout)
}
})
TypeError: Cannot read property 'exec' of undefined

解決法

一度electron側のオブジェクトを挟めば良い。
直接require()するのではなく、window.require()とする。


const childProcess = window.require("child_process")
childProcess.exec("ls", (error, stdout, stderr) => {
if(error != null){
   console.log(error)
}else{
  console.log(stdout)
}
})

原因

調査中

reactはhtmlファイルを生成するだけなのでelectron側を直接見ることができない、ので、
requireが参照する場所がelectronとは違う場所になっちゃうからみたいな理由かなぁ......

requireが参照してる場所をしらべればわかりそう。

おわりに

electron+reactを使うと雑アプリが量産できるのでおすすめ。

おまけ

cloneしてnpm installするだけで動く雛形をつくったのでご活用ください。
(テストとかは全くしていないので僕の環境以外で動くかどうかはわからないです)
https://github.com/tortuepin/min-react-electron