踩坑 electron-vue

第一次开发桌面应用。在此记录使用electron-vue搭建桌面版应用所遇到的问题。

process is not defined

按照官网步骤搭建项目,运行npm run dev 时出现 process is not defined 错误。
解决方案:
在.electron-vue/webpack.renderer.config.js和.electron-vue/webpack.web.config.js文件中找到HtmlWebpackPlugin代码段并更改为如下代码:

new HtmlWebpackPlugin({
  filename: 'index.html',
  template: path.resolve(__dirname, '../src/index.ejs'),
  templateParameters(compilation, assets, options) {
    return {
      compilation: compilation,
      webpack: compilation.getStats().toJson(),
      webpackConfig: compilation.options,
      htmlWebpackPlugin: {
        files: assets,
        options: options
      },
      process,
    };
  },
  minify: {
    collapseWhitespace: true,
    removeAttributeQuotes: true,
    removeComments: true
  },
  nodeModules: process.env.NODE_ENV !== 'production'
    ? path.resolve(__dirname, '../node_modules')
    : false
}),

打包找不到文件报错

第一次运npm run build时报了一大堆文件下载错误,比如electron-vxxx-winxxx.zip 、nsis-xxx等
解决方案:
自己去taobao镜像网站或github上下载相关版本的文件包,放入本地相关目录下。

自定义桌面窗口栏目

通过配置主进程src\main\index.js文件相关属性,完成窗口自定义

import { app, BrowserWindow, ipcMain} from 'electron'
    mainWindow = new BrowserWindow({
        height: 880,
        useContentSize: true,
        width: 1200,
        minWidth: xxx,
        minHeight: xxx,
        title: "XXX",
        frame: false, //添加后自定义标题//自定义边框
        resizable: false, //可否缩放
        movable: true, //可否移动
    })
// 相关事件
ipcMain.on('close', e => {
    mainWindow.close()
})
ipcMain.on('minimize', e => {
    mainWindow.minimize()
})
ipcMain.on('unmaximize', e => {
    mainWindow.unmaximize()
})
ipcMain.on('maximize', e => {
    mainWindow.maximize()
})

vue页面监听事件

const { ipcRenderer } = require("electron");
methods:{
    minimize() {
      ipcRenderer.send("minimize");
    },
    // 文档说可以用这个方法mainWindow.isMaximized()判断窗口是否最大化,但是我测试没有效果,所以就自己定义了一个状态
    maximize() {
      if (this.isMaxSize) {
        ipcRenderer.send("unmaximize");
      } else {
        ipcRenderer.send("maximize");
      }
      this.isMaxSize = !this.isMaxSize;
    },
    close() {
      ipcRenderer.send("close");
    }
}

打包相关配置

1、图标命名自定义
修改package.json文件,在build中配置自定义图标路径和安装名称,需要在build文件夹中放置自定义图标

    "build": {
        "win": {
            "icon": "build/icons/icon.ico", 
            "artifactName": "${productName}_Setup_${version}.${ext}"
        }
    },

2、打包后应用安装目录自定义
修改package.json文件,在build中添加配置

        "nsis": {
            "oneClick": false,
            "allowToChangeInstallationDirectory": true,
            "perMachine": true
        },

3、自动检测版本并更新
修改package.json文件,在build中添加配置

        "publish": [{
            "provider": "generic",
            "url": "http://xxxxxxx/download/" // 打包生成的exe安装包和latest.yml存放路径,浏览器输入地址能下载这两个文件
        }]

安装 electron-updater,在 src\main\index.js中添加更新事件

 
import {
    autoUpdater
} from 'electron-updater'
// 和package.json中配置的下载地址一致
let feedUrl = "http://xxxxxxx/download/";
//检测版本更新
updateHandle(mainWindow, feedUrl);

function updateHandle(window, feedUrl) {
    mainWindow = window;
    let message = {
        error: '检查更新出错',
        checking: '正在检查更新……',
        updateAva: '检测到新版本,正在下载……',
        updateNotAva: '现在使用的就是最新版本,不用更新',
    };
    //设置更新包的地址
    autoUpdater.setFeedURL(feedUrl);
    //监听升级失败事件
    autoUpdater.on('error', function (error) {
        sendUpdateMessage({
            cmd: 'error',
            message: error
        })
    });
    //监听开始检测更新事件
    autoUpdater.on('checking-for-update', function (message) {
        sendUpdateMessage({
            cmd: 'checking-for-update',
            message: message
        })
    });
    //监听发现可用更新事件
    autoUpdater.on('update-available', function (message) {
        sendUpdateMessage({
            cmd: 'update-available',
            message: message
        })
    });
    //监听没有可用更新事件
    autoUpdater.on('update-not-available', function (message) {
        sendUpdateMessage({
            cmd: 'update-not-available',
            message: message
        })
    });

    // 更新下载进度事件
    autoUpdater.on('download-progress', function (progressObj) {
        sendUpdateMessage({
            cmd: 'download-progress',
            message: progressObj
        })
    });
    //监听下载完成事件
    autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl) {
        sendUpdateMessage({
            cmd: 'update-downloaded',
            message: {
                releaseNotes,
                releaseName,
                releaseDate,
                updateUrl
            }
        })
        //退出并安装更新包
        autoUpdater.quitAndInstall();
    });

    //接收渲染进程消息,开始检查更新
    ipcMain.on("checkForUpdate", (e, arg) => {
        //执行自动更新检查
        // sendUpdateMessage({cmd:'checkForUpdate',message:arg})
        autoUpdater.checkForUpdates();
    })
}
//给渲染进程发送消息
function sendUpdateMessage(text) {
    mainWindow.webContents.send('message', text)
}

在App.vue中添加检测更新事件

<script>
const ipcRenderer = require("electron").ipcRenderer;
//接收主进程版本更新消息
ipcRenderer.on("message", (event, arg) => {
  // for (var i = 0; i < arg.length; i++) {
  if ("update-available" == arg.cmd) {
  } else if ("download-progress" == arg.cmd) {
    //更新升级进度
    alert("更新中");
    console.log(arg.message.percent);
  } else if ("error" == arg.cmd) {
    alert("更新失败");
  }
}
});
//20秒后开始检测新版本
let timeOut = window.setTimeout(() => {
  console.log("检查更新");
  ipcRenderer.send("checkForUpdate");
}, 2000);
clearTimeout;
//间隔1小时检测一次
let interval = window.setInterval(() => {
  ipcRenderer.send("checkForUpdate");
}, 3600000);
</srript>
首先将打包成功后生成的exe安装文件和latest.yml放到配置的下载服务器上,再修改package.json中的版本号,重新打包新的版本,把生成的安装文件和latest.yml放到下载服务器同一个位置,latest.yml会覆盖上一次生成的。应用会通过检测这个文件判断是否有新版本
   "version": "0.0.2", // 打包版本号
注意:用vue-electron脚手架搭建的应用electron版本是2.xx的,我查资料说版本太低不支持自动检测更新,所以我最开始就把electron升级了,没有测试2版本是否可以自动检测更新;自动更新成功后发现每次更新都需要重新安装一次,很不友好。如果有人了解局部更新的知识,我想请教学习,谢谢。

打包安装引入外部exe或者dll文件

由于项目中需要启动另外的exe程序,所以必须把其他exe程序和electron关联起来安装
修改package.json文件,配置需要引入的相关exe程序。

        "extraResources": {
            "from": "./extraResources/",
            "to": "./extraResources/"
        }

在src\main\index.js中使用chile_process

const {
    spawn
} = require('child_process')
const vmPath = require('path').join(process.cwd(),'/resources/extraResources/xxx.exe').replace(/\\/g, '\\\\')
ipcMain.on('connect-server', (e, appUrl) => {
    //spawn("D:/xxx/xxx/=xxx.exe")  开发模式写绝对路径
    spawn(vmPath)  // 打包安装后的路径
})
路径方面的问题,借用https://segmentfault.com/a/1190000018878931 原作者的话

使用 nodeJS 的被执行 js 文件的绝对路径:__dirname。
返回: D:\【文件夹】\win-ia32-unpacked\resources\app.asar\dist\electron
使用 electron 文档中提到的:“当前应用程序所在目录”:app.getAppPath()。
返回: D:\【文件夹】\win-ia32-unpacked\resources\app.asar
使用 process.execPath 即可获取: D:\【文件夹】\build\win-ia32-unpacked\vsqx.exe
使用 process.cwd() 即可获取: D:\【文件夹】\build\win-ia32-unpacked
最终我选用process.cwd()方法,完成在安装程序中启动内部exe程序

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349