1.前言
本文詳細介紹如何使用electron將若依框架前后端分離版的前端Vue頁面打包為Exe文件,并且包括如何實現應用更新。使用若依基礎代碼體現不出打包功能,因此我使用開發的文件管理系統,介紹上述過程,具體可以查看我的文章《若依前后端分離版實現文件管理》。雖然沒有使用若依基礎代碼,但是打包過程是完全一樣的。本文章完全免費,使用若依版本為3.8.9。打包之前,復制一份前端代碼進行,不要在原來前端代碼基礎上打包,因為exe打包修改的配置會影響原來PC端的功能。
2.安裝插件
1.在終端執行下面代碼,查看當前鏡像庫。
npm get registry
2.如果當前鏡像不是上面地址,執行下面代碼,將鏡像設置淘寶鏡像。再次執行上面代碼,查看鏡像庫是否正確。
npm config set registry https://registry.npmmirror.com/
3.在終端依次執行下面代碼,安裝這個5個插件到ruoyi-ui。
npm install electron
npm install electron-devtools-installer
npm install electron-store
npm install vue-cli-plugin-electron-builder
npm install electron-updater
4.如果安裝失敗,請使用科學上網的方式進行安裝,具體如何科學上網,這里就不介紹了。如果使用科學上網的方式還是安裝失敗,可以在科學上網的前提下依次執行下面代碼。此種方式,應該能夠解決大部分問題,不行就多嘗試幾次。如果還是不行,只能自己想辦法安裝這幾個插件了。
npm install electron --registry=https://registry.npmmirror.com --disturl=https://npmmirror.com/mirrors/electron/
npm install electron-devtools-installer --registry=https://registry.npmmirror.com --disturl=https://npmmirror.com/mirrors/electron/
npm install electron-store --registry=https://registry.npmmirror.com --disturl=https://npmmirror.com/mirrors/electron/
npm install vue-cli-plugin-electron-builder --registry=https://registry.npmmirror.com --disturl=https://npmmirror.com/mirrors/electron/
npm install electron-updater --registry=https://registry.npmmirror.com --disturl=https://npmmirror.com/mirrors/electron/
5.在IDEA終端執行下面代碼,進入ruoyi-ui文件夾(如果沒有IDEA在cmd界面執行一樣。)。
cd ruoyi-ui
5.在IDEA終端執行下面代碼,查看vue版本。
vue --version
6.如果提醒“ 'vue' 不是內部或外部命令,也不是可運行的程序或批處理文件。 ”繼續在IDEA終端中執行下面代碼。先不要關閉窗口,
npm root -g
7.Win + R 輸入 sysdm.cpl,按回車或點擊“確定”按鈕,打開環境變量設置。
8.選擇“高級”,點擊“環境變量”。
9.選擇系統變量下面的Path選項,點擊“編輯”按鈕。
10.復制第6步的值,不要全部復制,復制到node_global路徑即可。比如:我的第6步顯示:D:\work\nodejs\node_global\node_modules,我需要復制D:\work\nodejs\node_global。
點擊“新建”按鈕,將復制的路徑,加入到最后。添加完成后,點擊“確定”按鈕。
11.再次點擊“確定”按鈕。之后,再此打開環境變量,找到剛才位置,確認下是否保存成功。
12.環境變量重新保存的前提下,關閉IDEA,再次打開。如果使用cmd,請關閉后,再打開。如果執行下面代碼,顯示版本號了,就代表配置成功了。如果關閉后再打開不生效,請重啟下電腦。
vue --version
13.在IDEA終端執行下面代碼,會提示選擇版本,選擇最新版,然后回車。等待添加完成后,打開前端文件,如果再src文件夾下多了個backgroud.js文件,代表添加成功。
vue add electron-builder
如果卡住了,不用關,只要前端成功添加了backgroud.js文件即可。
等待backgroud.js文件添加成功,通過Ctrl+C兩次,強制停止IDEA終端。不然后面打包時,會出現異常。
一定不要在vs終端執行上面代碼,會報錯。
14.打開package.json文件,由于我安裝的nodejs版本較高,將electron:build和electron:serve添加以下前綴。并不是所有人都需要添加此配置,如果原來代碼,再不添加的前提下可以運行,就不用添加。
SET NODE_OPTIONS=--openssl-legacy-provider &&
3.修改原文件
1.打開router/index.js,將路由模式改為hash。如果不修改,打包后直接無法顯示頁面。
2.通過Vs的全局搜索功能,1. 將所有文件中的Cookies.get替換為localStorage.getItem,將Cookies.set全部替換為localStorage.setItem,Cookies.remove全部替換為localStorage.removeItem。如果不修改,使用Cookies的地方都報錯。比如:點擊“登錄”按鈕后無反應,因為登錄頁面就使用了Cookies。
3. 打開src/layout/components/Navbar文件,設置退出后,跳轉到登錄頁。如果不設置,退出后,顯示空白頁。
this.$router.push('/login');
4.打開src\utils\request.js文件,修改登錄超時頁面跳轉。導入路由插件,實現路由調轉。
import router from '@/router'
router.push('/login');
4.配置Electron
1.打開vue.config.js文件,在module.exports中,增加Electron配置,配置代碼如下。下面配置上都有說明,就不一一介紹了,主要介紹下容易出錯的配置。
// electron配置pluginOptions: {electronBuilder: {nodeIntegration: false, //禁止 Node.js 直接運行,提升安全性contextIsolation: true, //使 `preload.js` 安全地暴露 APIenableRemoteModule: false, // 禁止 `remote`,避免被攻擊builderOptions: {appId: 'com.py', // appidproductName: 'py', // 生產名稱copyright: "Copyright ? 2018-2025",asar: true, //啟用 asar 打包,防止文件被篡改directories: {output: "dist_electron", //指定打包后的文件夾buildResources: "src/assets" //資源文件路徑(圖標等)},nsis: {oneClick: false, // 允許用戶自定義安裝路徑allowToChangeInstallationDirectory: true, // 允許用戶修改安裝路徑perMachine: true, // 所有用戶都可安裝(系統級安裝)allowElevation: true, // 允許以管理員權限運行createDesktopShortcut: true, // 創建桌面快捷方式createStartMenuShortcut: true, // 創建開始菜單快捷方式shortcutName: "若依管理系統", // 自定義快捷方式名稱installerIcon: "src/assets/logo/piaoyi_stall.ico", // 安裝程序圖標uninstallerIcon: "src/assets/logo/piaoyi_stall.ico", // 卸載程序圖標installerHeaderIcon: "src/assets/logo/piaoyi_stall.ico", // 安裝界面標題圖標},win: {// 下方任務欄圖標icon: "src/assets/logo/piaoyi.ico",target: [{target: "nsis", //生成 Windows 安裝包arch: ["ia32", "x64"] // 32 位 & 64 位兼容}],// 安裝包文件名artifactName: "py_${version}.${ext}"},publish: [{provider: "generic", // 允許手動配置更新服務器url: "http://localhost:8080/profile/" // 更新服務器地址}],// 額外打包資源,會打包到resources文件夾,使用時加上此文件夾路徑extraResources: [// 打包應用左上角圖標{from: "src/assets/logo/piaoyi_stall.ico",to: "logo/logo.ico",}]}}}
注意:
1.上面的所有圖標必須要求為.ico格式,并且最小為256*256。icon格式轉換后的圖片有可能無法識別,導致報錯。我使用的wps,如果關于圖標報錯,一定按照上面要求,如果還是不行,就得換個轉換軟件了。
2.publish.url為更新文件的地址,需要為一個后端映射的文件夾,我使用了若依文件后端映射文件夾的根路徑。需要更新文件時,將打包后的exe文件和latest.yml文件上傳到這個文件夾,應用會自動更新。
3.extraResources配置項導出到打包文件,能夠和public文件夾下的文件類似,我這將一個icon導出到了打包文件夾。需要注意的是,會將文件導出到resources文件夾下,因此使用文件時,需要加上此文件夾前綴,具體可以看backgroud.js文件中icon配置。
2.打開.env.production文件,將VUE_APP_BASE_API改為后端地址。因為electron自動讀取這個文件中的配置,一定不要和vue一樣加上訪問前綴。真正發布時,后端地址肯定需要映射到外網,就和小程序或者APP的后端類似。
3.打開src\background.js文件,用以下代碼替換。一般根據實際情況修改icon即可,如果調試階段可以win.webContents.openDevTools()代碼注釋去掉,會顯示一個類似于web調試的框。
'use strict'import { app, protocol, BrowserWindow, Menu, dialog } from 'electron'
import { autoUpdater } from 'electron-updater'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
//手動配置當前環境
const isDevelopment = process.env.NODE_ENV !== 'production'// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true, standard: true } }
])async function createWindow() {// 關閉頂部導航菜單欄Menu.setApplicationMenu(null)// Create the browser window.const win = new BrowserWindow({width: 1000,height: 800,// 應用左上角圖標icon: "resources/logo/logo.ico",webPreferences: {// Use pluginOptions.nodeIntegration, leave this alone// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more infonodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION}})// 啟動自動更新檢查checkForUpdates();//打開調試框// win.webContents.openDevTools()if (process.env.WEBPACK_DEV_SERVER_URL) {// Load the url of the dev server if in development modeawait win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)if (!process.env.IS_TEST) win.webContents.openDevTools()} else {createProtocol('app')// Load the index.html when not in developmentwin.loadURL('app://./index.html')}
}// Quit when all windows are closed.
app.on('window-all-closed', () => {// On macOS it is common for applications and their menu bar// to stay active until the user quits explicitly with Cmd + Qif (process.platform !== 'darwin') {app.quit()}
})app.on('activate', () => {// On macOS it's common to re-create a window in the app when the// dock icon is clicked and there are no other windows open.if (BrowserWindow.getAllWindows().length === 0) createWindow()
})// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {if (isDevelopment && !process.env.IS_TEST) {// Install Vue Devtoolstry {await installExtension(VUEJS_DEVTOOLS)} catch (e) {console.error('Vue Devtools failed to install:', e.toString())}}createWindow()
})// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {if (process.platform === 'win32') {process.on('message', (data) => {if (data === 'graceful-exit') {app.quit()}})} else {process.on('SIGTERM', () => {app.quit()})}
}// 自動更新邏輯
function checkForUpdates() {autoUpdater.autoDownload = false; // 禁止自動下載,讓用戶手動確認autoUpdater.checkForUpdates();// 有新版本可用autoUpdater.on('update-available', (info) => {dialog.showMessageBox({type: 'info',title: '更新可用',message: `發現新版本 ${info.version},是否立即更新?`,buttons: ['是', '否']}).then((result) => {if (result.response === 0) {autoUpdater.downloadUpdate();}});});// 更新下載完成autoUpdater.on('update-downloaded', () => {dialog.showMessageBox({type: 'info',title: '更新完成',message: '更新下載完成,是否立即安裝?',buttons: ['立即安裝', '稍后']}).then((result) => {if (result.response === 0) {autoUpdater.quitAndInstall();}});});// 更新錯誤autoUpdater.on('error', (error) => {dialog.showErrorBox('更新錯誤', error == null ? "未知錯誤" : error.toString());});
}
4.上面設置了很多東西,就是沒有應用版本號。應用版本號對更新很重要,會自動讀取package.json文件中的version,可以根據實際情況修改。我這里修改成1.0.0,方便以后的更新測試。
5.復制icon到文件夾,請根據實際情況修改icon相關代碼。
5.打包與更新
1.執行下面代碼,進行打包。
npm run electron:build
2.以為要成功了,結果插件報錯了,只能重新安裝下。先要強制結束下2.13步驟中,IDEA終端中的命令,不然會顯示electron占用。重新安裝下還是不行,直接刪除node_modules文件夾下所有內容,并且刪除了 package-lock.json文件。然后再執行npm install安裝所有插件命令,終于可以打包了。
3.第一次打包需要從github上下載相關依賴,如果速度很慢,可以強制停止了這個程序,然后使用了科學上網的方式,再次打包。以后打包,不刪除win-相關的文件夾,就不用使用科學上網的方式進行打包了。通過不斷嘗試,終于打包成功了,一般出問題就是插件原因,這也是沒辦法,只能不斷下載。
4.將py_1.0.0.exe和latest.yml文件,復制到若依后端映射文件夾根目錄下。
5.執行py_1.0.0.exe文件,根據步驟選擇安裝路徑,進行安裝。
6.成功啟動,登錄后,測試功能正常。
文件預覽功能也能正常使用,其他功能也能正常,其他功能不一一測試了。需要注意點是web新開網頁,在應用中會新打開個窗口。
7.打開package.json文件,修改version為1.0.1,然后重新打包。
8.等待打包成功,將最新打包的exe文件和latest.yml文件,復制到若依后端映射文件夾根目錄下。
9.關閉剛才的應用,然后重新打開。會提醒更新消息,點擊“是”。
10.點擊“立即安裝”按鈕。
11.自動安裝,會顯示安裝進度,由于截圖有點慢,更新完了。
6.總結
electron打包還是比較簡單的,只要復制我上面的配置文件,并且按照我的過程修改原文件就能使用。很多坑我都給踩了,超時或退出登錄白屏問題等問題,但是那個插件安裝容易出錯問題,我真的無能為力,大家只能多嘗試幾次了,要敢于嘗試,代碼一般不會出問題的。
如果本文章對您有幫助的話,并且條件允許的話,可以給我打賞下。不打賞也沒關系,您可以給我點贊支持下,您的支持就是我最大的動力。關注我的小伙伴應該發現了,我寫文章過程會非常具體,希望每個小伙伴都能夠跟著文章完成操作。我會不定時發布一些關于若依框架、java、Vue、uniapp等方面的內容,如果感興趣的話,可以關注我。如果您需要前后端分離版的文件預覽系統、流程管理系統或其他以上四方面涉及的內容,查看我的主頁一定不后悔。