今回は次のような問題を解決してみる。
- ES6が使いたい
- よりアプリらしく作りたい
- 変更するとRefresh押すのが面倒いい
まず、Electronは現状Node v4.1.1を使っているので、ES6で使えないものがまだ多い。今回はこれをWebpackで抑えてみる。ついでに、WebpackのHot module replace(以下、HMR)を利用して、ScriptやCSSの変更をRefreshsせずに反映されるようにしてみる。その上にReactを導入する。
Electronを設置する。
npm i -D electron-prebuiltWebpackの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-reactReact関連のものを入れる。
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!