Electron
+ React
+ Webpack
這個組合開發桌面應用仍是挺爽的。html
若是再搭上 Webpack
的 Hot Module Replacement 那簡直完美,不用刷新就搞定。react
關於 HMR
的演示能夠看 Dan Abramov 的演講視頻 Hot Reloading with Time Travel。webpack
在 Electron
中使用 HMR
碰到的問題是打開的文件是本地的,host
就變成了 file://
,git
因此監聽到變化以後,Webpack
嘗試更新模塊時,就查找不到 hot-update.json
,而後 Webpack
沒法更新模塊...github
當時這個問題搞瘋了我,花了很長時間,因此這篇就是爲了記錄下當時的坑。web
上圖出現的狀況,當時用的配置就是使用的比較官方的方式, 使用 webpack-dev-server
和 react-hot-loader
。express
import path from 'path' import webpack from 'webpack' module.exports = { devtool: 'eval', entry: [ 'webpack-dev-server/client?http://localhost:3000', 'webpack/hot/only-dev-server', './src/index' ], output: { path: path.join(__dirname, 'dist'), filename: 'bundle.js', publicPath: '/static/' }, plugins: [ new webpack.HotModuleReplacementPlugin() ], module: { loaders: [{ test: /\.js$/, loaders: ['react-hot', 'babel'], include: path.join(__dirname, 'src') }] } }
而後換成 React Hot Loader 3 試了一下,果真不出所料,仍是沒能成功。json
本來覺得問題就是出在 webpack-dev-server
上,因此就把精力集中在替換 webpack-dev-server
上了。babel
而後用 express
+ webpack-dev-middleware
+ webpack-hot-middleware
本身搭建服務。app
'use strict' import express from 'express' import webpack from 'webpack' import webpackDevMiddleware from 'webpack-dev-middleware' import webpackHotMiddleware from 'webpack-hot-middleware' import config from './webpack.config.dev' const app = express() const compiler = webpack(config) const PORT = 3000 app.use(webpackDevMiddleware(compiler, { publicPath: config.output.publicPath, noInfo: false, reload: true, stats: { colors: true } })) // hot app.use(webpackHotMiddleware(compiler)) app.listen(PORT, 'localhost', (err) => { if (err) { console.error(err) return } console.log(`Listening at http://localhost:${PORT}`) })
然而仍是不行, 最後研究了這個倉庫的配置,
發現還有這樣的一個配置 target: 'electron-renderer'
,然而官方文檔上卻沒有說明。
Note: target: 'electron-renderer'
屬性是在 Webpack
v1.12.15
版本中加入的 make electron-main
and electron-renderer
targets works in 1.x。
爲了不更多人步我後塵,就去給 Webpack
文檔增長了說明 Compare: configuration。
這時候熱替換的問題也就解決了,這個過程還能從提交歷史中看到 PupaFM。
But...
當後來有時間再回顧這個問題的時候,一直在想第一種方式應該能解決纔對啊,
因此在第一種方式的配置上加了 target: 'electron-renderer'
,然而並無什麼軟用...
最後再一次查看了一遍 Webpack
的文檔,仔細的看了 output.publicPath
這個配置。
The
publicPath
specifies the public URL address of the output files when referenced in a browser.
For loaders that embed <script>
or <link>
tags or reference assets like images, publicPath
is used as the href or url() to the file when it’s different then their location on disk (as specified by path).
This can be helpful when you want to host some or all output files on a different domain or on a CDN.
The Webpack Dev Server also takes a hint from publicPath
using it to determine where to serve the output files from.
As with path you can use the [hash] substitution for a better caching profile.
那我是否是隻要把相對路徑改爲絕對地址,就能夠監聽到文件的更新了。
只要這樣就行了嘛 publicPath: 'http://localhost:3000/static/'
...
而後寫了個 demo ,具體代碼可參考 Electron React Hot Boilerplate。
果真...
仍是須要好好閱讀完文檔啊,雖然 Webpack
的文檔也略坑。
原文連接 http://xwartz.github.io/pupa/2016/06/electron-with-hmr/