下準備
下準備
npm init
# なんでもいいけど、エントリーポイントはmain.jsにしておく
entry point: (index.js) main.js
必要なモジュールのインストール
npm install \
electron-reload \
material-ui \
ramda \
react \
react-dom
# electron-reload ・・・ 開発時のオートリロード用
# material-ui ・・・ MaterialUI
# ramda ・・・ 個人的に使いやすいのでRamda.js
npm install -D \
electron \
electron-packager \
webpack \
webpack-cli \
webpack-node-externals \
babel-loader \
html-loader \
html-webpack-plugin \
babel-cli \
babel-preset-env \
babel-preset-react \
babel-preset-stage-1 \
babel-register
# electron-packager ・・・ Electronをパッケージするのに使う
# webpack-node-externals ・・・ node_modulesをwebpackの対象から外す
# babel-preset-stage-1 ・・・ MaterialUIで必要だったはず
# babel-register ・・・ webpack.configだってES6で書きたい
↓.babelrcとwebpack.configはコピペで。
.babelrc
{
"presets": [
["react"],
["stage-1"],
[
"env",
{
"targets": "electron"
}
]
]
}
webpack.config.babel.js
import HtmlWebpackPlugin from 'html-webpack-plugin';
import nodeExternals from 'webpack-node-externals';
import webpack from 'webpack';
export default {
mode: 'development',
target: 'electron-renderer', // レンダラープロセスをメインターゲットに
externals: [nodeExternals()], // node_modulesは依存関係から外すよ
entry: './src/js/index.js',
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.(html)$/,
use: {
loader: 'html-loader'
}
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'babel-preset-react',
'babel-preset-env'
]
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/html/index.html'
}),
new webpack.ProvidePlugin({
$: 'jquery'
})
]
};
ブラウザプロセス
以下をコピペ。
※内容は、
<公式の記載>
+ <electron_reload>
+ <パッケージ後のメニュー>
+ <ロードするhtmlの変更>
main.js
const {app, BrowserWindow, Menu} = require('electron');
require('electron-reload')(__dirname);
const path = require('path');
const url = require('url');
const template = [
{
label: 'Edit',
submenu: [
{role: 'undo'},
{role: 'redo'},
{type: 'separator'},
{role: 'cut'},
{role: 'copy'},
{role: 'paste'},
{role: 'pasteandmatchstyle'},
{role: 'delete'},
{role: 'selectall'}
]
},
{
label: 'View',
submenu: [
{role: 'reload'},
{role: 'forcereload'},
{role: 'toggledevtools'},
{type: 'separator'},
{role: 'resetzoom'},
{role: 'zoomin'},
{role: 'zoomout'},
{type: 'separator'},
{role: 'togglefullscreen'}
]
},
{
role: 'window',
submenu: [
{role: 'minimize'},
{role: 'close'}
]
},
{
role: 'help',
submenu: [
{
label: 'Learn More',
click () { require('electron').shell.openExternal('https://electronjs.org'); }
}
]
}
];
if (process.platform === 'darwin') {
template.unshift({
label: app.getName(),
submenu: [
{role: 'about'},
{type: 'separator'},
{role: 'services', submenu: []},
{type: 'separator'},
{role: 'hide'},
{role: 'hideothers'},
{role: 'unhide'},
{type: 'separator'},
{role: 'quit'}
],
});
// Edit menu
template[1].submenu.push(
{type: 'separator'},
{
label: 'Speech',
submenu: [
{role: 'startspeaking'},
{role: 'stopspeaking'}
]
}
);
// Window menu
template[3].submenu = [
{role: 'close'},
{role: 'minimize'},
{role: 'zoom'},
{type: 'separator'},
{role: 'front'}
];
}
let win;
function createWindow () {
win = new BrowserWindow({width: 800, height: 600});
win.loadURL(url.format({
// ここのhtmlをdistのhtmlにする
pathname: path.join(__dirname, 'dist/index.html'),
protocol: 'file:',
slashes: true
}));
//win.webContents.openDevTools();
win.on('closed', () => {
win = null;
});
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
}
app.on('ready', createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (win === null) {
createWindow();
}
});
webpack.config.babel.js
レンダラープロセス
前準備
mkdir -p ./src/html ./src/js ./src/jsx dist
HTML
index.htmlはReactの入り口だけ作ってあげる。
MaterialUI用にRobotoの設定もここで。
src/html/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
<style>
* {font-family: 'Open Sans', sans-serif;}
</style>
<title>タイトル</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
JS
ReactDOM.render。
これもほぼコピペでよく、あとはコンポーネントを増やして、追記していけば良い。
MuiThemeProviderをここで記載して、どこでもMaterialUIを使えるようにしておく。
src/js/index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
class App extends Component {
render() {
return (
<MuiThemeProvider>
hoge
</MuiThemeProvider>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
Electron起動
$(npm bin)/webpack
$(npm bin)/electron .
一応コンポーネントも増やしてみる
src/jsx/sub.jsx
import React, { Component } from 'react';
export default class Sub extends Component {
render() {
return (
<div>
Sub
</div>
);
}
}
index.jsでは、Subをimportする。
src/js/index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Sub from '../jsx/sub.jsx';
class App extends Component {
render() {
return (
<MuiThemeProvider>
hoge
<Sub />
</MuiThemeProvider>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);