美文网首页
vue-cli 里面引入electron 以及基本的配置

vue-cli 里面引入electron 以及基本的配置

作者: 冰落寞成 | 来源:发表于2021-05-12 19:21 被阅读0次

    引入electron,electron-builder,vue-cli-plugin-electron-builder,electron-devtools

    npm i --save-dev electron
    
    

    1,引入之后在package.json 文件下会自动生成

    image.png

    2,在vue-cli 项目src下 创建background.js

    代码如下:

    import { app, protocol, BrowserWindow, ipcMain, Menu, dialog, globalShortcut } from 'electron'
    import {
      createProtocol
    } from "vue-cli-plugin-electron-builder/lib";
    const fs = require("fs")  //引入node原生fs模块
    const os = require("os")
    const isDevelopment = process.env.NODE_ENV !== "production";
    let mainWindow
    // Scheme must be registered before the app is ready
    protocol.registerSchemesAsPrivileged([
      { scheme: "app", privileges: { secure: true, standard: true } }
    ]);
    const path = require('path')
    const menus = [{
      label: '视图',
      submenu: [{
        label: '刷新',
        role: 'reload'
      },
      {
        label: '退出',
        role: 'quit'
      }]
    }]
    const menu = Menu.buildFromTemplate(menus)
    
    function createWindow () {
      mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        show: false,
        webPreferences: {
          enableRemoteModule: true, // 允许弹框
          webSecurity: false,
          nodeIntegration: true,
          nodeIntegrationInWorker: true, // 在Web工作器中启用了Node集成
    
          preload: path.join(__dirname, 'preload.js'),
          defaultEncoding: 'utf-8'
        }
      })
      mainWindow.once('ready-to-show', () => {
        mainWindow.show()
      })
    
    
      if (process.env.WEBPACK_DEV_SERVER_URL) { // 开发环境
        // Load the url of the dev server if in development mode
        mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
        if (!process.env.IS_TEST) mainWindow.webContents.openDevTools();
        globalShortcut.register('CommandOrControl+Shift+i', function () { //  使用快捷键shift+ctrl+i  调起开发工具
          mainWindow.webContents.openDevTools()
        })
    
      } else { //  生产环境
        // mainWindow.webContents.openDevTools() //  生产环境关闭调试工具
        // Load the index.html when not in development
        createProtocol('app')
        // Load the index.html when not in development
        mainWindow.loadURL('app://./index.html')
      }
      Menu.setApplicationMenu(menu)
    }
    
    
    /**
     * 初始化
     */
    app.whenReady().then(() => {
    
    
      createWindow()
      app.setAppUserModelId('管理平台')
      // 点击MacOS底部菜单时重新启动窗口
      app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) {
          createWindow()
        }
      })
    })
    
    // 兼容MacOS系统的窗口关闭功能
    app.on('window-all-closed', () => {
      if (process.platform !== 'darwin') {
        app.quit()
      }
      mainWindow = null
    })
    // 最小化窗口(自定义导航条时)
    ipcMain.on('window-min', () => {
      mainWindow.minimize()
    })
    // 最大化窗口(自定义导航条时)
    ipcMain.on('window-max', () => {
      // 如果已经是最大化窗口就还原
      if (mainWindow.isMaximized()) {
        mainWindow.restore();
      } else {
        mainWindow.maximize()
      }
    })
    // 关闭窗口
    ipcMain.on('window-close', () => {
      mainWindow.close()
      mainWindow = null;
      app.exit();
    })
    
    // 主进程给进程通信
    
    ipcMain.on('toMain', function (event, arg) {
    
      event.sender.send('fromMain', arg); // 返回给渲染进程
    
    });
    // 下载进程
    ipcMain.on('downLoad', function (event, arg) {
      mainWindow.webContents.downloadURL(arg.url);
    });
    // 调用文件读入方法
    ipcMain.on('judgeUse', function (event, arg) {
      // 读入文件
    // 异步返回
      fs.readFile("./authorize.bin", { encoding: "utf-8" }, (err, data) => {
        // if (err) {
        //   // dialog.showMessageBox({
        //   //   type: 'error',
        //   //   title: '找不到authorize.bin文件',
        //   //   message: err.path,
        //   //   buttons: ['ok']
        //   // }).then((index) => {
        //   //   if (index.response === 0) {
        //   //     mainWindow.close()
        //   //     mainWindow = null;
        //   //     app.exit();
        //   //   }
        //   // })
        //   event.sender.send('fromMain', null); // 返回给渲染进程
        // } else {
        //   event.sender.send('fromMain', data); // 返回给渲染进程
        // }
        event.reply('authorizeBack', data); // 返回给渲染进程
      })
    
    });
    // 读取本地服务的IP 地址 同步
    ipcMain.on('syncGetLocalServer', function (event, arg) {
      // 读入文件,同步返回数据
      fs.readFile("./localServer.xml", { encoding: "utf-8" }, (err, data) => {
        event.returnValue=data; // 返回给渲染进程
      })
    });
    // 读取本地服务的IP 地址 异步
    ipcMain.on('asyncGetLocalServer', function (event, arg) {
      // 读入文件
    // 异步返回
      fs.readFile("./localServer.xml", { encoding: "utf-8" }, (err, data) => {
        event.reply('asyncBackLocalServer', data); // 返回给渲染进程
      })
    
    });
    //隐藏按钮
    ipcMain.on('hideMenu', function (event, arg) {
      mainWindow.setMenu(null);
    });
    //显示按钮
    ipcMain.on('showMenu', function (event, arg) {
      mainWindow.setMenu(menu);
    });
    
    // 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();
        });
      }
    }
    

    3,在vue-cli 项目src下 创建 preload.js(预加载文件)

    import { contextBridge, ipcRenderer } from 'electron'
    window.ipcRenderer = ipcRenderer
    
    contextBridge.exposeInMainWorld('ipcRenderer', {
      // 异步向主进程 发送消息
      send: (channel, data) => {
        let validChannels = ['toMain', 'downLoad', 'judgeUse', 'hideMenu', 'showMenu', 'window-close', 'asyncGetLocalServer']
        if (validChannels.includes(channel)) {
          ipcRenderer.send(channel, data)
        }
      },
      // 同步向主进程 发送消息,
      sendSync: (channel, data) => {
        let validChannels = ['syncGetLocalServer']
        if (validChannels.includes(channel)) {
          return ipcRenderer.sendSync(channel, data)
        }
      },
      // 异步接收主进程返回的数据
      receive: async (channel) => {
        let validChannels = ['authorizeBack', 'asyncBackLocalServer']
        if (validChannels.includes(channel)) {
          return new Promise((resolve) => {
            ipcRenderer.on(channel, (event, ...args) => {
              resolve(...args)
            })
          });
    
        }
      }
    })
    

    4,在package.json 里面添加 background.js 的引入

     "main": "background.js",
    
    image.png

    5, 在package.json =>scripts添加electron的启动、打包命令

    "electron:build": "vue-cli-service electron:build",
        "electron:serve": "vue-cli-service electron:serve",
        "postinstall": "electron-builder install-app-deps",
        "postuninstall": "electron-builder install-app-deps"
    
    image.png

    package.json 最终配置如下:

    {
      "name": "mine-exe",
      "author": {
        "name": "xd"
      },
      "description": "test",
      "version": "0.1.0",
      "private": true,
      "scripts": {
        "start": "vue-cli-service serve -open",
        "serve": "vue-cli-service serve",
        "build": "vue-cli-service build",
        "lint": "vue-cli-service lint",
        "electron:build": "vue-cli-service electron:build",
        "electron:serve": "vue-cli-service electron:serve",
        "postinstall": "electron-builder install-app-deps",
        "postuninstall": "electron-builder install-app-deps"
      },
      "dependencies": {
        "@babel/polyfill": "^7.12.1",
        "axios": "^0.21.1",
        "core-js": "^3.6.5",
        "dayjs": "^1.10.4",
        "echarts": "^5.1.0",
        "electron-builder": "^22.11.1",
        "element-ui": "^2.15.1",
        "js-md5": "^0.7.3",
        "vue": "^2.6.11",
        "vue-cli-plugin-electron-builder": "^2.0.0",
        "vue-router": "^3.2.0",
        "vuex": "^3.4.0"
      },
      "main": "background.js",
      "devDependencies": {
        "@vue/cli-plugin-babel": "~4.5.0",
        "@vue/cli-plugin-eslint": "~4.5.0",
        "@vue/cli-plugin-router": "~4.5.0",
        "@vue/cli-plugin-vuex": "~4.5.0",
        "@vue/cli-service": "~4.5.0",
        "@vue/eslint-config-standard": "^5.1.2",
        "babel-eslint": "^10.1.0",
        "electron": "^12.0.7",
        "electron-devtools-installer": "^3.2.0",
        "eslint": "^6.7.2",
        "eslint-plugin-import": "^2.20.2",
        "eslint-plugin-node": "^11.1.0",
        "eslint-plugin-promise": "^4.2.1",
        "eslint-plugin-standard": "^4.0.0",
        "eslint-plugin-vue": "^6.2.2",
        "sass": "^1.26.5",
        "sass-loader": "^8.0.2",
        "vue-template-compiler": "^2.6.11"
      }
    }
    

    6,在vue.config.js 里的配置如下

    const path = require('path')
    const resolve = dir => path.join(__dirname, dir)
    const CopyWebpackPlugin = require('copy-webpack-plugin')
    const webpack = require('webpack')
    const BASE_URL = process.env.NODE_EVN === 'production'
      ? './'
      : './'
    const port = process.env.PORT || 8080
    module.exports = {
      publicPath: BASE_URL,
      outputDir: 'mine-exe',
      assetsDir: 'static',
      lintOnSave: process.env.NODE_ENV === 'development',
      // 这里写你调用接口的基础路径,来解决跨域,如果设置了代理,那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串
      devServer: {
        // proxy: 'localhost:3000'
        port,
        open: false
      },
      pluginOptions: {
        electronBuilder: {
          removeElectronJunk: false,
          preload: './src/preload.js',
          builderOptions: {
            "appId": "com.example.app",
            "productName": "智慧矿山管理平台",//项目名,也是生成的安装文件名,即aDemo.exe
            "copyright": "Copyright © 2021",//版权信息
            "directories": {
              "output": "build"//输出文件路径
            },
            "win": {//win相关配置
              "icon": "./src/assets/icon.ico",//图标,当前图标在根目录下,注意这里有两个坑
              "target": [
                {
                  "target": "nsis",//利用nsis制作安装程序
                  "arch": [
                    "x64",//64位
                  ]
                }
              ]
            },
            "nsis": {
              "oneClick": false, // 是否一键安装
              "allowElevation": true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
              "allowToChangeInstallationDirectory": true, // 允许修改安装目录
              "installerIcon": "./src/assets/icon.ico",// 安装图标
              "uninstallerIcon": "./src/assets/icon.ico",//卸载图标
              "installerHeaderIcon": "./src/assets/icon.ico", // 安装时头部图标
              "createDesktopShortcut": true, // 创建桌面图标
              "createStartMenuShortcut": true,// 创建开始菜单图标
              "shortcutName": "mine", // 图标名称
            },
          }
        },
      },
      chainWebpack: config => {
        config.resolve.alias
          .set('@', resolve('src'))
        config.entry('polyfill').add('@babel/polyfill')
      },
    
      css: {
        loaderOptions: {
          sass: {
            prependData: `
              @import "@/styles/variables.scss";
              @import "@/styles/mixins.scss";
            `
          }
        }
      },
      // 设为false打包时不生成.map文件
      productionSourceMap: true
    }
    
    

    7,在终端里使用“npm run electron:serve ” 即可打开本地EXE程序

    8 在终端里使用“npm run electron:build ” 即可打包本地EXE程序:(注意有坑)

    打包本地程序解决下载依赖过慢的方法如下:
    https://www.jianshu.com/p/5d8ea14ce374

    9 最终vue-cli 项目目录如下

    红色箭头指的文件是新增的,绿色箭头指向的文件为要修改的


    image.png

    相关文章

      网友评论

          本文标题:vue-cli 里面引入electron 以及基本的配置

          本文链接:https://www.haomeiwen.com/subject/fsdadltx.html