设置electron 安装路径

npm set config ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/"

核心思想

electron 分主进程和渲染进程,在这里,我们直接把主进程看成是创建主体窗口,而渲染进程看成是 页面的渲染

  • 渲染进程当成一般的webpack配置即可, vue-loader, less-loader, style-loader等等照常配置即可,
  • 主进程: 主进程我们只当他是创建主体窗口的,那么我们只需要配置 babel-loader,
  • 当主进程发生改变时,那么就重启窗口, 简单来说就是直接使用 electron .这个命令, 但是我们使用nodejs 的方式启动
  • 当渲染进程文件发生改变时,我们的electron 也跟着刷新,那么就要使用devServer + webpack-hot-middleware, 但我觉得直接使用devServer 也没问题
  • 在主进程中要监听localhost的变化 win.loadURL("http://localhost:9000"),才能达到 实时更新

配置渲染进程

我们根据 vue-cli 目录文件去配,vue-cli

渲染进程的目录路径:src/render/ 目录下

├─assets      // 资源文件
├─components  // vue 组件
├─pages       // 路由页面
├─App.vue     // vue 主体文件
├─index.js    // 入口文件
└─router.js   // 路由文件,配置路由的

渲染进程webpack 配置:

// configs/webpack.render.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack')

// loader 自行npm install
module.exports = {
    mode: 'development',
    entry: './src/render/index.js',
    devtool: 'eval-source-map', 
    // target: 'electron-renderer', // 加了反而报错
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, '../dist/render')
    },
    module: {
        rules: [
            // babel-loader, less-loader 等等
            {
                test: /\.vue$/,  // 编译vue
                loader: 'vue-loader'
            }
            // ... 图片字体文件等等的文件配置
        ]
    },
    plugins: [
        new VueLoaderPlugin(), // 编译vue
        new HtmlWebpackPlugin({template: path.resolve(__dirname, '../public/index.html')}),
        new webpack.HotModuleReplacementPlugin()
    ],
    // 往后devServer 会改成nodejs 的方式启动
    devServer: {
        contentBase: path.resolve(__dirname, '../dist/render'),
        hot: true,
        compress: true,
        port: 9000,
        open: true
    }
}

要是执行命令webpack-dev-server --config ./configs/webpack.dev.config.js 没报错,那没渲染进程基本没问题了,另外我们往后 会把devServer 改成 nodejs的方式启动

配置主进程

我们会把主进程的js 放入src/main/目录下, 但其实只有index.js

const path = require('path');

module.exports = {
    entry:  './src/main/index.js',
    mode: 'development',
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, "../dist/main")
    },
    target: 'electron-main'
}

用nodejs 的方式启动这些配置

// 渲染进程
//https://webpack.docschina.org/guides/development
// 因为webpack-hot-middleware 只能检测到文件发生变化时重新加载,但不能刷新浏览器,所以我们加入 webpack-dev-server, 让浏览器自动刷新
function createRendererServer() {
    return new Promise((resolve, reject) => {
        // 直接添加 wenpack-hot-middleware/client.js, 
        rendererConfig.entry = ['webpack-hot-middleware/client?noInfo=true&reload=true'].concat(rendererConfig.entry);

        const compiler = webpack(rendererConfig);
        hotMiddleware = webpackHotMiddleware(compiler, {
            log: false,
            heartbeat: 2500
        })

        compiler.hooks.done.tap('done', stats => { console.log("完成");})

        const server = new webpackDevServer(compiler, {
            contentBase: path.resolve(__dirname, '..'),
            quiet: true,
            before (app, ctx) {
                // express, 可获取 node 服务 app 实例,执行中间件操作
                app.use(hotMiddleware)
                ctx.middleware.waitUntilValid(() => {
                    resolve()
                })
            }
        });

        server.listen(9000);
    })

}
// 因为主进程的index.js 文件不常改,我们直接使用watch 的方式,监听文件变化,文件一变化,那么我们就重新启动electron
function createMainServer() {
    return new Promise((resolve, reject) => {
        const compiler = webpack(mainConfig);

        // 主进程监听文件变化, webpack watch 模式,那么就从起electron, 即调用electron .
        compiler.watch({
            aggregateTimeout: 300,
            poll: 1000
        }, (err, stats) => {
            if (err) {
                console.log(err)
                return
            }
            if (electronProcess && electronProcess.kill) {
                manualRestart = true
                process.kill(electronProcess.pid)
                electronProcess = null
                startElectron() // 用 nodejs spawn的方式启动electron , 启动加载的js 应该是在 /dist/main/main.js ,该方法就不写了
                setTimeout(() => {
                    manualRestart = false
                }, 5000)
            }
            resolve()
        })
    })
}

我们用Promise.all([createRendererServer(), createMainServer()]) 这两个都编译好之后再启动electron .then(() => startElectron());

效果

最后

浏览器打开localhost:9000 一样也可以,另外就是 nwjs 的开发环境也大致一样吧