最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Electron开发实践

    正文概述 掘金(搬砖_胖子)   2021-03-12   639

    背景

    公司需要制作一个桌面程序,之前有一个python写的cli工具,需要封装一个GUI跨平台使用,技术采用Electron + Vue技术栈,模板使用electron-vue,特殊之处是应用中使用pyinstaller打包成跨平台应用使用node调用。

    基础项目中遇到的问题

    上面提到该项目是根据electron-vue模板创建,在创建时,选用了electron-builder作为打包工具,打包后会在build目录下生成*-unpacked目录和对应的.exe.deb等可安装文件。下面说下基于该模板开发时遇到的问题。

    升级electron版本

    • 模板使用的electron版本是2.X版本,版本较低,故升级到了11.3.0版本,以方便使用最新的框架特性
    • 升级后模板自带的vuex-electron插件不好使故去掉了

    系统中的路径分隔符的问题

    • 由于历史原因路劲的分割符在WindowsPOSIX不同
      • \ 反斜杠,在Windows,如C:\tmp\test.txt
      • / 斜杆,在POSIX,如/tmp/test.txt
    • 各个编程语言均有获取当前系统分隔符方法的api,node中可以使用:
      const sep = require('path').sep
      
    • 故在手动添加路径的地方需要通过上面提到的api获取路径分割符,动态进行拼接:
      import path from 'path'
      const downloadPath = `${this.$electron.remote.app.getPath('downloads')}${path.sep}合并表格.xlsx`
      

    关于使用electron-builder打包遇到的问题

    • 据说使用electron-builder可以打包出跨操作系统的应用程序,保险起见,在WindowsDeepin系统分别进行打包
    • 打包的配置基本通过package.json即可配置完成:
      "build": {
        "productName": "excel-util",
        "appId": "com.excelUtil.xxx",
        "directories": {
          "output": "build"
        },
        "files": [
          "dist/electron/**/*"
        ],
        "dmg": {
          "contents": [
            {
              "x": 410,
              "y": 150,
              "type": "link",
              "path": "/Applications"
            },
            {
              "x": 130,
              "y": 150,
              "type": "file"
            }
          ]
        },
        "mac": {
          "icon": "build/icons/icon.icns"
        },
        "win": {
          "icon": "build/icons/icon.ico"
        },
        "nsis": {
          "shortcutName": "ExcelUtil",
          "oneClick": false,
          "allowToChangeInstallationDirectory": true,
          "include": "./installer.nsh"
        },
        "asar": false,
        "linux": {
          "icon": "build/icons",
          "target": "deb"
        }
      }
      
    • 以上是electron-builder中关于打包的所有配置,下面拆分一下
      • Windows打包配置,指定图标路径和nsis配置Windows应用安装和卸载的行为
        "win": {
          "icon": "build/icons/icon.ico"
        },
        "nsis": {
          "shortcutName": "ExcelUtil",
          "oneClick": false,
          "allowToChangeInstallationDirectory": true,
          "include": "./installer.nsh"
        }
        
      • Linux打包配置,指定图标和打包目标格式等
        "linux": {
          "icon": "build/icons",
          "target": "deb"
        }
        
    • 打包使用的依赖包的镜像问题
      • 打包会依赖很多外部的安装包,默认都是通过github或者npm官方仓库,会有下载缓慢或者下载失败的问题
      • 需要增加.yarnrc配置文件在根目录下,配置下载涉及到依赖的的仓库地址
        registry "https://registry.npm.taobao.org"
        sass_binary_site "https://npm.taobao.org/mirrors/node-sass/"
        phantomjs_cdnurl "http://cnpmjs.org/downloads"
        electron_mirror "https://npm.taobao.org/mirrors/electron/"
        sqlite3_binary_host_mirror "https://foxgis.oss-cn-shanghai.aliyuncs.com/"
        profiler_binary_host_mirror "https://npm.taobao.org/mirrors/node-inspector/"
        chromedriver_cdnurl "https://cdn.npm.taobao.org/dist/chromedriver"
        

    开发中遇到的问题

    主进程和渲染进程

    • electron本质是一个nodejs runtime和一个开源的chromium浏览器,开发时分为主进程和渲染进程
    • 主进程的代码在src/main目录下
    • 渲染进程的代码在src/renderer目录下
    • 同时会通过webpack分别对mainrenderer进行打包构建
    • 进程间通信可以使用ipcMainipcRenderer中的事件进行通信,以达到渲染进程可以调用主进程中的原生资源

    主进程窗口配置

    • 由于本次开发涉及的主进程开发相对简单,只涉及到一个src/main/index.js,那就直接拿文件中BrowserWindow配置代码说事儿吧

      new BrowserWindow({
        height: 563,
        useContentSize: true,
        width: 1000,
        fullscreen: false, // 是否允许全屏
        fullscreenable: false,
        titleBarStyle: 'hidden',
        maximizable: false,
        webPreferences: {
          nodeIntegration: true, // 是否引入node api 这样渲染进程就可以i使用node api了
          nodeIntegrationInWorker: true,
          enableRemoteModule: true // 是否引入remote模块 这样渲染进程就可以使用remote模块api了
        }
      })
      
    • 当然其中还涉及到引用本地数据库lowdb,这里是参考掘友的文章

    • 本应用还涉及到了单窗口实现,使用的是requestSingleInstanceLock api来获取是否有窗口正在运行

      const gotTheLock = app.requestSingleInstanceLock()
      // 获取单体实例锁,设置应用单开
      if (!gotTheLock) {
        app.quit()
      } else {
        app.on('second-instance', (event, commandLine, workingDirectory) => {
          // 当运行第二个实例时,将会聚焦到mainWindow这个窗口
          if (mainWindow) {
            if (mainWindow.isMinimized()) mainWindow.restore()
            mainWindow.focus()
          }
        })
        app.on('ready', createWindow)
        app.on('window-all-closed', () => {
          if (process.platform !== 'darwin') {
            app.quit()
          }
        })
        app.on('activate', () => {
          if (mainWindow === null) {
            createWindow()
          }
        })
      }
      

    调用python应用程序时遇到的问题

    • 首先需要通过pyinstaller分别打包出各操作系统环境中使用的cli应用程序
    • 将打包后的cli工具未压缩的包放入static/cli目录下
    • 调用时即可通过webpack吐出的全局__static变量获取对应的路径供node子进程调用
    • 这里需要对打包配置进行修改才能达到打包后仍然可以正确调用cli
      • package.jsonbuild字段中增加"asar": false,来保证打包后的应用不被压缩,node仍可以正常访问cli资源

      • 对于Windows来说,通过配置nsis的默认安装路径来保证路径可用,因为默认安装到C:\\Program Files下,有空格的路径会造成调用不通,故需要增加一下配置

        "nsis": {
          "some": "other config",
          "include": "./installer.nsh"
        }
        

        package.json中增加一个nsis安装脚本installer.nsh,让应用默认安装到C:\excel-utils目录下

        !macro preInit
            SetRegView 64
            WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\excel-utils"
            WriteRegExpandStr HkCU "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\excel-utils"
            SetRegView 32
            WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\excel-utils"
            WriteRegExpandStr HkCU "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\excel-utils"
        !macroend
        
      • 对于Deepin系统来说,由于在webpack打包复制static/cli目录时会丢失cli程序的可执行权限,导致打包后命令不能执行,故增加一个增加权限的脚本和命令

      package.json
      "scripts": {
        "build:linux": "node .electron-vue/build.js && .electron-vue/changeMainMod.sh && electron-builder",
      }
      
      .electron-vue中增加changeMainMod.sh,并使其在业务代码打包完成后调用
      #!/bin/bash
      for main in `ls ./dist/electron/static/cli/*/main`
      do
        echo "正在设置$main为可执行权限"
        chmod +x $main
      done
      
    • webpack.renderer.config白名单的问题
      • 由于使用的vue2.X,UI库使用的则是element-ui,开发时发现使用el-table组件不正确显示,查阅资料后发现需要增加到打包白名单里面,注释写的也很详细,需要指定UI libraries来让编译.vue文件
      /**
       * List of node_modules to include in webpack bundle
       *
       * Required for specific packages like Vue UI libraries
       * that provide pure *.vue files that need compiling
       * https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
       */
      let whiteListedModules = ['vue', 'element-ui']
      

    番外

    技术选型时有两个选择一个是Electron,一个是NW.js,这里有一个文档来说明二者的异同,主要区别就是:

    • Electron有很多成功案例AtomVScode等等耳熟能详的大众应用,当然NW.js也有钉钉和微信开发者工具这样的巨头应用
    • 总体来说Electron有更多的用户群,更多三方工具包,更活跃的社区,有问题可以很快找到解决方案
    • NW.js保持了对Windows xp系统的支持,而Electron并出于安全性考虑并不支持
    • 再就是对node的集成,Electron集成了libuv在两个进程中,均可以直接使用,避免了对Chromium的hack,而NW.js则需要通过派发的方式使用

    搬砖

    • electron
    • electron-vue
    • node

    起源地下载网 » Electron开发实践

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元