今回は次のような問題を解決してみる。
- ES6が使いたい
- よりアプリらしく作りたい
- 変更するとRefresh押すのが面倒いい
まず、Electronは現状Node v4.1.1を使っているので、ES6で使えないものがまだ多い。今回はこれをWebpackで抑えてみる。ついでに、WebpackのHot module replace(以下、HMR)を利用して、ScriptやCSSの変更をRefreshsせずに反映されるようにしてみる。その上にReactを導入する。
Electronを設置する。
npm i -D electron-prebuilt
WebpackのLoaderとPluginを設置する。
まずは、WebpackとJSXをコンパイルするためのBabel loader、React transfrom pluginなどなど
npm i -D webpack webpack-dev-server babel-loader babel-plugin-react-transform react-transform-catch-errors react-transform-hmr redbox-react
React関連のものを入れる。
npm i -D react react-dom
devDependencies
に入れることに注意する。ReactなどのWebにも使うしNodeでも使えるmoduleにおいて、window
とexports
がグロバルに露出されているElectronの環境は非常にバグる余地が多い。なので、devDependencies
に入れておいて、Webpackからcompileさせて使うようにしたほうがいいと思う。
基本的な設置はこれでおわり。
.babelrc
からBabelの設定をしよう。これはJSXをReact用で、更にHMRまで挟んでおく。
{
"stage": 0,
"env": {
"development": {
"plugins": ["react-transform"],
"extra": {
"react-transform": {
"transforms": [{
"transform": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}, {
"transform": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}]
}
}
}
}
}
webpack.config.js
からWebpackの設定をする。
Webpackを使うとModuleをどこから持ってくるのかが自由自在に設定ができる。
まず、Reactは先話したようにWebpackでCompileする対象であるのでいれない。
そして、electron
などのNative moduleはexternals
の配列に追加させて、コンパイルせずにrequireできるようにする。
var webpack = require('webpack')
var JsonpTemplatePlugin = webpack.JsonpTemplatePlugin
var FunctionModulePlugin = require('webpack/lib/FunctionModulePlugin')
var NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin')
var ExternalsPlugin = webpack.ExternalsPlugin
var opt = {
filename: 'bundle.js',
libraryTarget: 'commonjs2',
publicPath: 'http://localhost:8080/assets/'
}
var config = {
module: {
loaders: [
{
test: /\.js?$/,
loaders: ['babel-loader'],
exclude: /node_modules/
}
]
},
debug: true,
devtool: 'cheap-module-eval-source-map',
entry: [
'./src/index.js'
],
output: opt,
resolve: {
extensions: ['', '.js', '.jsx'],
packageMains: ['webpack', 'browser', 'web', 'browserify', ['jam', 'main'], 'main']
},
plugins: [
new webpack.NoErrorsPlugin(),
new ExternalsPlugin('commonjs', [
'app',
'auto-updater',
'browser-window',
'content-tracing',
'dialog',
'global-shortcut',
'ipc',
'menu',
'menu-item',
'power-monitor',
'protocol',
'tray',
'remote',
'web-frame',
'clipboard',
'crash-reporter',
'screen',
'shell'
]),
new NodeTargetPlugin()
],
externals: [
// 'socket.io-client',
// 'md5',
// 'superagent',
// 'superagent-promise',
// 'lodash',
// 'markdown-it',
// 'moment'
]
}
config.target = function renderer (compiler) {
compiler.apply(
new JsonpTemplatePlugin(opt),
new FunctionModulePlugin(opt)
)
}
module.exports = config
I can't read Japanese, but the example was a huge help. Thank you!