React や Redux は 主に Webアプリケーション のライブラリなのですが
Electron を利用すると ディスクトップ アプリケーション を作成することができます。
前回 のアプリケーションを ディスクトップ アプリケーション にしましょう。
Learning
- Electron で ディスクトップ アプリケーション を作成する。
- Electron の メニュー と IPC(プロセス間通信) を利用する。
Environment
- node: v6.9.2
- npm: v4.0.5
- yarn: v0.18.0
Comment Box Form
- 完成される Source Code のファイルリストです。
-
main.js
とserver.js
の2ファイルが追加されます。
-
$ tree -a -I node_modules
.
├── .babelrc
├── app
│ ├── actions
│ │ └── index.js
│ ├── components
│ │ ├── Comment
│ │ │ └── index.js
│ │ ├── CommentBox
│ │ │ ├── index.js
│ │ │ └── style.css
│ │ ├── CommentForm
│ │ │ └── index.js
│ │ ├── CommentList
│ │ │ └── index.js
│ │ └── global.css
│ ├── containers
│ │ └── App
│ │ ├── index.js
│ │ └── style.css
│ ├── index.js
│ ├── reducers
│ │ └── index.js
│ └── store
│ └── index.js
├── test
│ └── app
│ ├── actions
│ │ └── index.test.js
│ ├── components
│ │ ├── Comment
│ │ │ └── index.test.js
│ │ └── CommentBox
│ │ └── index.test.js
│ └── reducers
│ └── index.test.js
├── index.html
├── main.js
├── package.json
├── server.js
├── webpack.config.js
└── yarn.lock
Let's hands-on
Setup application
-
git clone
コマンドでアプリケーションをダウンロードします。 -
yarn
コマンドで依存するモジュールをインストールします。
$ git clone https://github.com/ogom/react-comment-box-example.git
$ cd react-comment-box-example
$ git checkout jest
$ yarn
API Server は React Tutorial Example (Express) をご利用ください。
Electron
- Electron のモジュールをインストールします。
$ yarn add --dev electron
main.js
-
main.js
ファイルに Electron の設定をします。-
index.html
ファイルを参照しています。
-
import { app, BrowserWindow } from 'electron'
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({width: 800, height: 600})
mainWindow.loadURL(`file://${__dirname}/index.html`)
mainWindow.webContents.openDevTools()
mainWindow.on('closed', () => {
mainWindow = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (mainWindow === null) {
createWindow()
}
})
-
package.json
ファイルにmain
とscripts
の設定します。 - Electron でも
babel
を利用するのでbabel-register
をrequire
に設定します。
"name": "react-comment-box-example",
"version": "1.0.0",
"private": true,
+ "main": "main.js",
"scripts": {
- "start": "webpack-dev-server -d --progress --colors",
+ "start": "electron --require babel-register .",
"test": "jest",
"test:watch": "npm test -- --watch"
},
-
yarn start
コマンドで Electron が起動します。
$ yarn start
bundle.js
ファイルがロードできないエラーが発生しています。 ( Failed to load resource: net::ERR_FILE_NOT_FOUND )
なので、bundle.js
ファイルを参照できるように webpack の設定をしましょう。
server.js
-
server.js
ファイルに webpack の設定をします。-
webpack.config.js
ファイルを参照しています。
-
import webpack from 'webpack'
import WebpackDevServer from 'webpack-dev-server'
import config from './webpack.config'
const options = {
publicPath: config.output.publicPath,
hot: true,
inline: true,
historyApiFallback: true,
stats: {
colors: true,
hash: false,
timings: true,
chunks: false,
chunkModules: false,
modules: false
}
}
const compiler = webpack(config)
const server = new WebpackDevServer(compiler, options)
server.listen(4000)
-
main.js
ファイルにserver.js
をインポートします。- Electron の実行で webpack も実行されるようになります。
+import server from './server'
import { app, BrowserWindow } from 'electron'
let mainWindow
-
webpack.config.js
ファイルに entry と output の設定をします。
var webpack = require('webpack')
+var path = require('path')
module.exports = {
- entry: './app/index',
+ entry: [
+ 'webpack-dev-server/client?http://localhost:4000/',
+ 'webpack/hot/dev-server',
+ path.join(__dirname, './app/index')
+ ],
output: {
+ path: path.join(__dirname, './dist'),
+ publicPath: 'http://localhost:4000/dist/',
filename: 'bundle.js'
},
-
index.html
ファイルのbundle.js
ファイルの参照先を変更します。
</head>
<body>
<div id='content'></div>
- <script src='/bundle.js'></script>
+ <script src='http://localhost:4000/dist/bundle.js'></script>
</body>
</html>
bundle.js
ファイルがロードできるので Comment Box が表示されました。
それに Hot Module Replacement の機能も使えるので開発が捗ります。
Menu
- ディスクトップ アプリケーションのメニューは簡単に作成することができます。
-
Comment
のメニューにClear
のサブメニューを作成します。- アプリケーションを終了する
quit
のメニューもあると開発が捗ります。
- アプリケーションを終了する
import server from './server'
-import { app, BrowserWindow } from 'electron'
+import { app, BrowserWindow, Menu, dialog } from 'electron'
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({width: 800, height: 600})
mainWindow.loadURL(`file://${__dirname}/index.html`)
mainWindow.webContents.openDevTools()
mainWindow.on('closed', () => {
mainWindow = null
})
+
+ Menu.setApplicationMenu(
+ Menu.buildFromTemplate(
+ [
+ {
+ label: 'App',
+ submenu: [
+ {
+ role: 'quit'
+ }
+ ]
+ },
+ {
+ label: 'Comment',
+ submenu: [
+ {
+ label: 'Clear',
+ click(item, focusedWindow) {
+ dialog.showMessageBox({
+ type: 'info',
+ message: 'Message!',
+ detail: 'message detail.',
+ buttons: ['OK']
+ })
+ }
+ }
+ ]
+ }
+ ]
+ )
+ )
}
- メニューをクリックすると Message! のダイアログが表示されます。
IPC
- Electron のメニューとブラウザを連携するには IPC を利用します。
-
IPC に
store.dispatch(action)
を設定するとMenu -> Redux -> React
で連携が可能です。- さらに
ipcRenderer.send('ipc::getState' store.getState())
で State をメニューに送信することもできます。
- さらに
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
+import { ipcRenderer } from 'electron'
import App from './containers/App'
import configureStore from './store'
const store = configureStore()
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('content')
)
+
+ipcRenderer.on('ipc::dispatch', (e, action) => {
+ store.dispatch(action)
+})
-
Actions はブラウザの
app/actions/index.js
ファイルをインポートすると DRY ですね。
+import * as Actions from './app/actions'
import server from './server'
import { app, BrowserWindow, Menu, dialog } from 'electron'
- 先ほどのメニューに
send('ipc::dispatch', Actions.showComments([]))
を設定します。
label: 'Clear',
click(item, focusedWindow) {
dialog.showMessageBox({
type: 'info',
message: 'Message!',
detail: 'message detail.',
buttons: ['OK']
})
+ focusedWindow.webContents.send('ipc::dispatch', Actions.showComments([]))
}
}
]
-
webpack.config.js
ファイルにtarget: 'electron-renderer'
を設定します。-
server.js
ファイルに設定した項目は除去します。
-
- devServer: {
- hot: true,
- port: 4000,
- inline: true,
- historyApiFallback: true
- }
+ target: 'electron-renderer'
}
- これでメニューをクリックして Message! のダイアログの
OK
をクリックするとコメントがクリアされます。
Congrats!
リリースをするためには electron-packager
などでパッケージを作成するなど、いくつかの手順がありますが
Webアプリケーション のテクニックで ディスクトップ アプリケーション が作成できるのは便利ですね。
また、モバイル アプリケーションは React Native を利用すると作成できますよ。
React やその周辺のテクノロジーは変化が活発で、発展が楽しみなプロダクトです。
(React Tutorial も Comment Box から Tic tac toe に変更されました )
Enjoy React