当前位置:   article > 正文

使用Electron包装ruoyi-ui/ruoyi-vue实践总结_electron 打包ruoyi

electron 打包ruoyi

背景:最近公司新起的项目,由于工期、资源等原因,采用ruoyi框架快速实现开发,由于需要构建客户端,所以借助electron来实现。

electron 是使用javascript html css来构建跨平台的桌面应用程序。

官网地址:简介 | Electron

查了很多资料,好像后台管理做成客户端的很少很少,主要参考这篇文章:

ruoyi-vue | electron打包教程(超详细)_ruoyi 打包_七维大脑的博客-CSDN博客

加上自己的实践,在这里记录一下过程以及踩过的坑。

一、基础环境说明

  1. node:16.14.2 && 20.3.1 推荐nvm来管理切换
  2. ruoyi-ui: 3.8.3
  3. java:20
  4. mysql:8.0

经过个人实践,主要就是node的版本比较重要,其他的不管是ruoyi-ui 还是ruoyi-vue,后端的java及mysq版本就更是毫无关系了。

二、ruoyi前端工程的改造

1.依赖安装
  1. # electron
  2. npm install electron
  3. # 在 Electron 应用程序中安装和管理开发者工具
  4. npm install electron-devtools-installer
  5. # 简单的持久化数据存储库
  6. npm install electron-store
  7. # 在 Vue CLI 项目中集成 Electron 打包和构建
  8. npm install vue-cli-plugin-electron-builder

如果安装错误的话,可以改一下安装源 npm install --registry=https://registry.npmmirror.com

是不是发现报错了呢?

 问题就出在,直接安装electron,没有指定版本,存在与node的兼容问题。官网可是说了

没问题,切换到最新的node版本, nvm use 20.3.1,成功安装,继续。。。

2.修改配置
.env.production 生产环境配置
  1. # 若依管理系统/生产环境
  2. VUE_APP_BASE_API = '/prod-api'
  3. # 这里先改成后端服务地址:
  4. VUE_APP_BASE_API = 'http://localhost:8080'

这里说明一下,生产环境涉及到打包部署,所以说

  1. # 如果项目web前端没有部署改为线上后端地址:
  2. VUE_APP_BASE_API = 'http://localhost:8080'
  3. # 如果项目web前端已经部署可写改为:
  4. VUE_APP_BASE_API = 'http://IP/prod-api'
clipboard

解决clipboard报错问题

老哥推荐,暴力注释全部代码:src/directive/module/clipboard.js

vue.config.js
  1. # 修改静态资源路径
  2. publicPath: './',
  3. # 修改为实际接口地址
  4. target: `http://localhost:8080`

module.exports中新增下面配置,与 devServer 同级

  1. pluginOptions: {
  2. electronBuilder: {
  3. // preload: 'src/preload.js',
  4. nodeIntegration: true,
  5. contextIsolation: false,
  6. enableRemoteModule: true,
  7. publish: [{
  8. "provider": "xxxx有限公司",
  9. "url": "http://xxxxx/"
  10. }],
  11. "copyright": "Copyright © 2022",
  12. builderOptions:{
  13. appId: 'com.ruoyi',
  14. productName: 'ruoyi',
  15. nsis:{
  16. "oneClick": false,
  17. "guid": "idea",
  18. "perMachine": true,
  19. "allowElevation": true,
  20. "allowToChangeInstallationDirectory": true,
  21. "installerIcon": "build/app.ico",
  22. "uninstallerIcon": "build/app.ico",
  23. "installerHeaderIcon": "build/app.ico",
  24. "createDesktopShortcut": true,
  25. "createStartMenuShortcut": true,
  26. "shortcutName": "若依管理系統"
  27. },
  28. win: {
  29. "icon": "build/app.ico",
  30. "target": [
  31. {
  32. "target": "nsis", //使用nsis打成安装包,"portable"打包成免安装版
  33. "arch": [
  34. "ia32", //32
  35. "x64" //64
  36. ]
  37. }
  38. ]
  39. },
  40. },
  41. // preload: path.join(__dirname, "/dist_electron/preload.js"),
  42. },
  43. },

路由文件 src/router/index.js,改为 hash 模式

解决菜单栏跳转404,部分无法跳转问题

 全局修改
  1. 全局搜索Cookies.get并替换为localStorage.getItem
  2. 全局搜索Cookies.set并替换为localStorage.setItem
  3. 全局搜索Cookies.remove并替换为localStorage.removeItem
  4. // src/views/login.vue 去掉过期时间
  5. localStorage.setItem("username", this.loginForm.username);
  6. localStorage.setItem("password", encrypt(this.loginForm.password));
  7. localStorage.setItem('rememberMe', this.loginForm.rememberMe);
  1. // 为了解决菜单栏跳转为404的问题
  2. // electron中的路由跳转路径解析path.resolve结果与在浏览器中的web项目解析结果不一致
  3. // path 模块的默认操作会因 Node.js 应用程序运行所在的操作系统而异。 具体来说,当在 Windows 操作系统上运行时, path模块会假定正被使用的是 Windows 风格的路径。
  4. // path.posix 属性提供对 path 方法的 POSIX 特定实现的访问。(意思就是无视操作系统的不同,统一为 POSIX方式,这样可以确保在任何系统上结果保持一致)
  5. 全局修改path.resolve为path.posix.resolve

但是要注意,使用path.posix.resolve,会造成npm run dev 的时候报错,记得切换修改

修复无法登出问题,也就是退出后的跳转页面 
  1. async logout() {
  2. this.$confirm('确定注销并退出系统吗?', '提示', {
  3. confirmButtonText: '确定',
  4. cancelButtonText: '取消',
  5. type: 'warning'
  6. }).then(() => {
  7. this.$store.dispatch('LogOut').then(() => {
  8. this.$router.push('/login')
  9. })
  10. }).catch(() => {});
  11. }
3.新增electron的相关配置

src根目录下新建background.js文件

  1. 'use strict'
  2. import { app, protocol, BrowserWindow, ipcMain } from 'electron'
  3. import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
  4. import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
  5. const isDevelopment = process.env.NODE_ENV !== 'production'
  6. const Store = require('electron-store');
  7. // Scheme must be registered before the app is ready
  8. protocol.registerSchemesAsPrivileged([
  9. { scheme: 'app', privileges: { secure: true, standard: true } }
  10. ])
  11. async function createWindow() {
  12. // Create the browser window.
  13. const win = new BrowserWindow({
  14. width: 800,
  15. height: 600,
  16. webPreferences: {
  17. // Use pluginOptions.nodeIntegration, leave this alone
  18. // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
  19. contextIsolation:false, //上下文隔离
  20. enableRemoteModule: true, //启用远程模块
  21. nodeIntegration: true, //开启自带node环境
  22. webviewTag: true, //开启webview
  23. webSecurity: false,
  24. allowDisplayingInsecureContent: true,
  25. allowRunningInsecureContent: true
  26. }
  27. })
  28. win.maximize()
  29. win.show()
  30. win.webContents.openDevTools()
  31. ipcMain.on('getPrinterList', (event) => {
  32. //主线程获取打印机列表
  33. win.webContents.getPrintersAsync().then(data=>{
  34. win.webContents.send('getPrinterList', data);
  35. });
  36. //通过webContents发送事件到渲染线程,同时将打印机列表也传过去
  37. });
  38. if (process.env.WEBPACK_DEV_SERVER_URL) {
  39. // Load the url of the dev server if in development mode
  40. await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
  41. if (!process.env.IS_TEST) win.webContents.openDevTools()
  42. } else {
  43. createProtocol('app')
  44. // Load the index.html when not in development
  45. win.loadURL('app://./index.html')
  46. }
  47. }
  48. // Quit when all windows are closed.
  49. app.on('window-all-closed', () => {
  50. // On macOS it is common for applications and their menu bar
  51. // to stay active until the user quits explicitly with Cmd + Q
  52. if (process.platform !== 'darwin') {
  53. app.quit()
  54. }
  55. })
  56. app.on('activate', () => {
  57. // On macOS it's common to re-create a window in the app when the
  58. // dock icon is clicked and there are no other windows open.
  59. if (BrowserWindow.getAllWindows().length === 0) createWindow()
  60. })
  61. // This method will be called when Electron has finished
  62. // initialization and is ready to create browser windows.
  63. // Some APIs can only be used after this event occurs.
  64. app.on('ready', async () => {
  65. Store.initRenderer();
  66. if (isDevelopment && !process.env.IS_TEST) {
  67. // Install Vue Devtools
  68. try {
  69. await installExtension(VUEJS_DEVTOOLS)
  70. } catch (e) {
  71. console.error('Vue Devtools failed to install:', e.toString())
  72. }
  73. }
  74. createWindow()
  75. })
  76. // Exit cleanly on request from parent process in development mode.
  77. if (isDevelopment) {
  78. if (process.platform === 'win32') {
  79. process.on('message', (data) => {
  80. if (data === 'graceful-exit') {
  81. app.quit()
  82. }
  83. })
  84. } else {
  85. process.on('SIGTERM', () => {
  86. app.quit()
  87. })
  88. }
  89. }

package.json中新增指令、引入electron配置文件

 4.测试打包
npm run electron:build

项目会新增文件夹,dist_electron,先把它加入.gitignore中,进入文件夹:

exe文件就是应用程序,收工...

补一张最后的成果图

 

接下来,会继续单开一篇文章,学习记录一下electron的打包配置,bye~ 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/926934
推荐阅读
相关标签
  

闽ICP备14008679号