Create a gist now

Instantly share code, notes, and snippets.

@Rokt33r /3.md
Created Nov 28, 2015

What would you like to do?
Electron x React x Webpack

Electron x React x Webpack

0. Synopsis

今回は次のような問題を解決してみる。

  1. ES6が使いたい
  2. よりアプリらしく作りたい
  3. 変更するとRefresh押すのが面倒いい

まず、Electronは現状Node v4.1.1を使っているので、ES6で使えないものがまだ多い。今回はこれをWebpackで抑えてみる。ついでに、WebpackのHot module replace(以下、HMR)を利用して、ScriptやCSSの変更をRefreshsせずに反映されるようにしてみる。その上にReactを導入する。

1. 初期設定

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において、windowexportsがグロバルに露出されている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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment