第一次開(kāi)發(fā)桌面應(yīng)用唆垃。在此記錄使用electron-vue搭建桌面版應(yīng)用所遇到的問(wèn)題五芝。
process is not defined
按照官網(wǎng)步驟搭建項(xiàng)目,運(yùn)行npm run dev 時(shí)出現(xiàn) process is not defined 錯(cuò)誤辕万。
解決方案:
在.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
}),
打包找不到文件報(bào)錯(cuò)
第一次運(yùn)npm run build時(shí)報(bào)了一大堆文件下載錯(cuò)誤枢步,比如electron-vxxx-winxxx.zip 、nsis-xxx等
解決方案:
自己去taobao鏡像網(wǎng)站或github上下載相關(guān)版本的文件包渐尿,放入本地相關(guān)目錄下醉途。
自定義桌面窗口欄目
通過(guò)配置主進(jìn)程src\main\index.js文件相關(guān)屬性,完成窗口自定義
import { app, BrowserWindow, ipcMain} from 'electron'
mainWindow = new BrowserWindow({
height: 880,
useContentSize: true,
width: 1200,
minWidth: xxx,
minHeight: xxx,
title: "XXX",
frame: false, //添加后自定義標(biāo)題//自定義邊框
resizable: false, //可否縮放
movable: true, //可否移動(dòng)
})
// 相關(guān)事件
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頁(yè)面監(jiān)聽(tīng)事件
const { ipcRenderer } = require("electron");
methods:{
minimize() {
ipcRenderer.send("minimize");
},
// 文檔說(shuō)可以用這個(gè)方法mainWindow.isMaximized()判斷窗口是否最大化砖茸,但是我測(cè)試沒(méi)有效果隘擎,所以就自己定義了一個(gè)狀態(tài)
maximize() {
if (this.isMaxSize) {
ipcRenderer.send("unmaximize");
} else {
ipcRenderer.send("maximize");
}
this.isMaxSize = !this.isMaxSize;
},
close() {
ipcRenderer.send("close");
}
}
打包相關(guān)配置
1、圖標(biāo)命名自定義
修改package.json文件,在build中配置自定義圖標(biāo)路徑和安裝名稱(chēng),需要在build文件夾中放置自定義圖標(biāo)
"build": {
"win": {
"icon": "build/icons/icon.ico",
"artifactName": "${productName}_Setup_${version}.${ext}"
}
},
2凉夯、打包后應(yīng)用安裝目錄自定義
修改package.json文件货葬,在build中添加配置
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"perMachine": true
},
3、自動(dòng)檢測(cè)版本并更新
修改package.json文件劲够,在build中添加配置
"publish": [{
"provider": "generic",
"url": "http://xxxxxxx/download/" // 打包生成的exe安裝包和latest.yml存放路徑震桶,瀏覽器輸入地址能下載這兩個(gè)文件
}]
安裝 electron-updater,在 src\main\index.js中添加更新事件
import {
autoUpdater
} from 'electron-updater'
// 和package.json中配置的下載地址一致
let feedUrl = "http://xxxxxxx/download/";
//檢測(cè)版本更新
updateHandle(mainWindow, feedUrl);
function updateHandle(window, feedUrl) {
mainWindow = window;
let message = {
error: '檢查更新出錯(cuò)',
checking: '正在檢查更新……',
updateAva: '檢測(cè)到新版本征绎,正在下載……',
updateNotAva: '現(xiàn)在使用的就是最新版本蹲姐,不用更新',
};
//設(shè)置更新包的地址
autoUpdater.setFeedURL(feedUrl);
//監(jiān)聽(tīng)升級(jí)失敗事件
autoUpdater.on('error', function (error) {
sendUpdateMessage({
cmd: 'error',
message: error
})
});
//監(jiān)聽(tīng)開(kāi)始檢測(cè)更新事件
autoUpdater.on('checking-for-update', function (message) {
sendUpdateMessage({
cmd: 'checking-for-update',
message: message
})
});
//監(jiān)聽(tīng)發(fā)現(xiàn)可用更新事件
autoUpdater.on('update-available', function (message) {
sendUpdateMessage({
cmd: 'update-available',
message: message
})
});
//監(jiān)聽(tīng)沒(méi)有可用更新事件
autoUpdater.on('update-not-available', function (message) {
sendUpdateMessage({
cmd: 'update-not-available',
message: message
})
});
// 更新下載進(jìn)度事件
autoUpdater.on('download-progress', function (progressObj) {
sendUpdateMessage({
cmd: 'download-progress',
message: progressObj
})
});
//監(jiān)聽(tīng)下載完成事件
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl) {
sendUpdateMessage({
cmd: 'update-downloaded',
message: {
releaseNotes,
releaseName,
releaseDate,
updateUrl
}
})
//退出并安裝更新包
autoUpdater.quitAndInstall();
});
//接收渲染進(jìn)程消息,開(kāi)始檢查更新
ipcMain.on("checkForUpdate", (e, arg) => {
//執(zhí)行自動(dòng)更新檢查
// sendUpdateMessage({cmd:'checkForUpdate',message:arg})
autoUpdater.checkForUpdates();
})
}
//給渲染進(jìn)程發(fā)送消息
function sendUpdateMessage(text) {
mainWindow.webContents.send('message', text)
}
在App.vue中添加檢測(cè)更新事件
<script>
const ipcRenderer = require("electron").ipcRenderer;
//接收主進(jìn)程版本更新消息
ipcRenderer.on("message", (event, arg) => {
// for (var i = 0; i < arg.length; i++) {
if ("update-available" == arg.cmd) {
} else if ("download-progress" == arg.cmd) {
//更新升級(jí)進(jìn)度
alert("更新中");
console.log(arg.message.percent);
} else if ("error" == arg.cmd) {
alert("更新失敗");
}
}
});
//20秒后開(kāi)始檢測(cè)新版本
let timeOut = window.setTimeout(() => {
console.log("檢查更新");
ipcRenderer.send("checkForUpdate");
}, 2000);
clearTimeout;
//間隔1小時(shí)檢測(cè)一次
let interval = window.setInterval(() => {
ipcRenderer.send("checkForUpdate");
}, 3600000);
</srript>
首先將打包成功后生成的exe安裝文件和latest.yml放到配置的下載服務(wù)器上人柿,再修改package.json中的版本號(hào)柴墩,重新打包新的版本,把生成的安裝文件和latest.yml放到下載服務(wù)器同一個(gè)位置凫岖,latest.yml會(huì)覆蓋上一次生成的江咳。應(yīng)用會(huì)通過(guò)檢測(cè)這個(gè)文件判斷是否有新版本
"version": "0.0.2", // 打包版本號(hào)
注意:用vue-electron腳手架搭建的應(yīng)用electron版本是2.xx的,我查資料說(shuō)版本太低不支持自動(dòng)檢測(cè)更新哥放,所以我最開(kāi)始就把electron升級(jí)了歼指,沒(méi)有測(cè)試2版本是否可以自動(dòng)檢測(cè)更新;自動(dòng)更新成功后發(fā)現(xiàn)每次更新都需要重新安裝一次婶芭,很不友好。如果有人了解局部更新的知識(shí)着饥,我想請(qǐng)教學(xué)習(xí)犀农,謝謝。
打包安裝引入外部exe或者dll文件
由于項(xiàng)目中需要啟動(dòng)另外的exe程序宰掉,所以必須把其他exe程序和electron關(guān)聯(lián)起來(lái)安裝
修改package.json文件呵哨,配置需要引入的相關(guān)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") 開(kāi)發(fā)模式寫(xiě)絕對(duì)路徑
spawn(vmPath) // 打包安裝后的路徑
})
路徑方面的問(wèn)題,借用https://segmentfault.com/a/1190000018878931 原作者的話
使用 nodeJS 的被執(zhí)行 js 文件的絕對(duì)路徑:__dirname孟害。
返回: D:\【文件夾】\win-ia32-unpacked\resources\app.asar\dist\electron
使用 electron 文檔中提到的:“當(dāng)前應(yīng)用程序所在目錄”: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()方法击你,完成在安裝程序中啟動(dòng)內(nèi)部exe程序