• 原生js结合electron。通过electron-builder和electron-updater打包并自动更新


    一.package.json文件

    先展示一个最终的package.json文件。后边再说都是怎么来的。(注释部分手动清理)

      还有些

    {
      "name": "name",//项目名
      "main": "main.js",
      "version": "0.0.2",
      "scripts": {
        "start": "electron .",
        "pack": "electron-builder --dir",
        "dist": "electron-builder" //打包命令 npm run dist 就可以执行打包
      },
    //默认安装完electron-builder会在dependencies里,一定要放在这。要不然会报模块找不到 "devDependencies": { "electron": "^10.1.1", "electron-builder": "^22.8.0", "menu": "^0.2.5", "path": "^0.12.7", "socket.io": "^2.3.0" },
    //其他的electron就要放在这。要不然也会报模块找不到(最重要的就是electron-updater) "dependencies": { "is-electron": "^2.2.0", "electron-log": "^4.2.4", "electron-updater": "^4.3.4" }, "build": { "productName": "naem",//应用名称 "appId": "**",//应用程序id "directories": { "output": "build"//输出目录 },
      //electron-updater需要的 "publish": [ { "provider": "generic", "url": "http://localhost/",//放latest.yml和.exe文件的服务器路径。(这里我用的nginx) "updaterCacheDirName": "name-updater" } ],
       //安装包源文件目录 把一些公用的提出来,要不然有可能找不到。 "files": [ "./installer.nsh", "./icon.ico", "./index.html", "./main.js", "./package.json", "app/**/*" ],
      //是否用asar打包,默认是true。如果用asar打包的话,那么项目目录将会都打包到asar中。打包完的resource中看不到项目目录
      //如果不用他打包的话,那么resource中将会有完整的项目路径
      //当然就算用asar打包的话。也可以下载asar模块,进行解压。 一般为true默认就好
      "asar":false,  
    "dmg": { "contents": [ { "x": 410, "y": 150, "type": "link", "path": "/Applications" }, { "x": 130, "y": 150, "type": "file" } ] }, "mac": { "icon": "./icon.png", "artifactName": "${productName}_setup_${version}.${ext}" }, "win": { "icon": "./icon.png",//exe图标 "artifactName": "${productName}_setup_${version}.${ext}" //exe名称 }, "linux": { "icon": "./icon.png", "artifactName": "${productName}_setup_${version}.${ext}" },
      //增加用户体验的配置(说白了就是安装界面的配置)更人性化了一点 "nsis": { "oneClick": false,//一键安装 "allowElevation": true,//如果为false,就必须提升权限重新启动安装 "allowToChangeInstallationDirectory": true,//修改安装目录 "installerIcon": "./tianyiyun.ico",//安装图标 "uninstallerIcon": "./tianyiyun.ico",//卸载图标 "createDesktopShortcut": true,//快捷方式 "createStartMenuShortcut": true,////开始菜单图标 "include": "./installer.nsh" //自定义脚本。比如一些开机启动啊一类的。可以自己写、找。找不到就算了吧。
        "script" : "build/script/installer.nsh" // NSIS脚本的路径,用于自定义安装程序。 默认为build / installer.nsi
        //最后两个一般不要,除非你想花里胡哨! } },
      //文件输出。可以把文件输出到其他目录。(这里我的是找不到exe图标。所以输出了下) "extraResources": { "from": "/icon.png", "to": "./" } }

    1.1 安装依赖(electron-bulider和electron-updater)

      推荐使用tyarn或者cnpm。(因为快)

    cnpm install electron-builder --save
    cnpm install electron-updater--save

      安装完package.json中会出现这样的配置。上边也说过。一定要改到devDependencies里 

      安装updater时。千万别动。就放在dependencies里。如果还有其他的electron-... ,的模块。也都放在dependencies里

    "dependencies": {
            ....
        "electron-builder": "^22.8.0"
      },

    二.主进程配置

    可以放在main.js里。也可以放在main文件夹下的index.js中(我是放在了main.js了)上代码!

      1 const electron = require('electron');
      2 const app = electron.app;
      3 const path = require('path');
      4 const log = require('electron-log')
      5 log.transports.console.level = false
      6 log.transports.console.level = 'silly'
      7 // 注意这个autoUpdater不是electron中的autoUpdater
      8 const { autoUpdater } = require("electron-updater");
      9 // 更新路径
     10 let updateUrl='';
     11 app.on('ready', function () {
     12     //自己的业务代码
     13     .
     14     .
     15     .
     16 
     17   // 判断是否是生产环境
     18   if (!app.isPackaged) {
     19     // 调试功能
     20     mainWindow.openDevTools();
     21     updateUrl  = "http://localhost/"
     22   }else{
     23     // 更新服务器地址
     24     mainWindow.openDevTools();
         //放打包完exe文件和latest.yml文件的路径
    25 updateUrl = "http://服务器地址/" 26 27 } 28 //调用检查更新 29 updateHandle() 30 } 31 32 33 // 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写 34 function updateHandle() { 35 let versionInfo = '' 36 let message = { 37 error: '检查更新出错', 38 checking: '正在检查更新……', 39 updateAva: '检测到新版本', 40 updateNotAva: '现在使用的就是最新版本,不用更新', 41 }; 42 // 设置是否自动下载,默认是true,当点击检测到新版本时,会自动下载安装包,所以设置为false 43 autoUpdater.autoDownload = false 44 autoUpdater.logger = log 45 const os = require('os'); 46 47 autoUpdater.setFeedURL(updateUrl); 48 autoUpdater.on('error', function (error) { 49 sendUpdateMessage(message.error) 50 }); 51 autoUpdater.on('checking-for-update', function () { 52 sendUpdateMessage(message.checking) 53 }); 54 autoUpdater.on('update-available', function (info) { 55 sendUpdateMessage(message.updateAva) 56 // 是否下载 57 mainWindow.webContents.send('isDownloadUpdate', versionInfo); 58 }); 59 autoUpdater.on('update-not-available', function (info) { 60 sendUpdateMessage(message.updateNotAva) 61 }); 62 63 // 更新下载进度事件 64 autoUpdater.on('download-progress', function (progressObj) { 65 // log.info(winURL) 66 // log.warn(progressObj) 67 mainWindow.webContents.send('downloadProgress', progressObj) 68 }); 69 70 // 更新下载完成事件 71 autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) { 72 73 ipcMain.on('updateNow', (e, arg) =>{ 74 console.log(arguments); 75 console.log("开始更新"); 76 //some code here to handle event 77 autoUpdater.quitAndInstall(); 78 }); 79 80 mainWindow.webContents.send('isUpdateNow',versionInfo) 81 }); 82 83 ipcMain.on("checkForUpdate",()=>{ 84 //执行自动更新检查 85 let checkInfo = autoUpdater.checkForUpdates() 86 checkInfo.then(function (data) { 87 versionInfo = data.versionInfo // 获取更新包版本等信息 88 }) 89 }); 90 91 ipcMain.on('downloadUpdate', () => { 92 // 下载 93 log.warn('执行下载') 94 autoUpdater.downloadUpdate() 95 }) 96 } 97 98 // 通过main进程发送事件给renderer进程,提示更新信息 99 function sendUpdateMessage(text) { 100 mainWindow.webContents.send('message', text) 101 }

     三.触发监听事件

    触发监听事件一般都是在第一个页面来做的。我这里是登录页 login.js

    现在登录页的created方法中触发。一启动程序。就会检查是否需要更新

    created() {
        .
        .
        .
        // electron应用启动后主动触发检查更新函数
        ipcRenderer.send("checkForUpdate");
    }, 

     然后检查到有新版本的时候,main.js里的方法就会调用这些监听事件,来处理升级版本

    //下载过程
    //downloadProgress事件可能因为下载速度太快,无法触发的问题
    ipcRenderer.on("downloadProgress", (event, progressObj)=> {
        // 打开下载进度样式
        app.$data.download=true;
        //progressObj.percent 下载进度
        if( Math.trunc(progressObj.percent)){
            let y = Math.trunc(progressObj.percent)
            var  elem=document.getElementById("ch"); //获取ch
            if (y==100){
                elem.style.backgroundColor="green";//百分百后背景颜色变化
                console.log('下载完成!')
            }
            elem.style.width=y+'%';
            elem.innerHTML=y+"%";// 计数值
        }
        
    });
    ipcRenderer.on('isUpdateNow', (event, versionInfo) => {
        // 自定义选择效果,效果自行编写
        console.log(versionInfo)
        alert("版本"+versionInfo.version+"下载完成,立即退出升级")
        ipcRenderer.send('updateNow')    
    })
    ipcRenderer.on('isDownloadUpdate', (event, versionInfo) => {
        // 自定义选择效果,效果自行编写
        console.log(versionInfo)
        if(confirm("检测到新版本,是否立即升级?")){
            console.log('正在升级!')
            ipcRenderer.send('downloadUpdate')
        }else{
            console.log('取消升级!')
        }
    })

    下载进度的样式可以自己写的炫酷点,我这里比较简单。甚至有点难看【捂脸】

     //html代码,我这里就放在login.html页面了
    <div id="download" v-show='download' >
          <div id="ch">
      </div>
    //css代码
    #ch{
       0px;
      height: 50px;
      background-color: pink;
      text-align: right;
      color: green;
      line-height: 50px;
      box-sizing: content-box;
    }

    现在所有的配置都已经完成了,就可以测试自动升级了

    四.自动升级

    先把package.json里的版本改成0.0.1,然后执行npm run dist(在package.json里配置的)打包。然后出现一个build的目录,里面有两个非常重要的东西

     latest.yml和.exe文件,这两个是要放在服务器下的(package.json里的publish下的url)然后如果有新版本的话,程序就会自动检查到然后更新了

    其他的文件就没啥了。第一个是exe的图标,第二个相当于执行.exe文件安装的安装目录。

    五.总结

    到了现在electron的打包并自动更新就简简单单的配置完成了,如果第一次弄这个,可能会有点懵,没关系,跟着步骤看着注解,一步一步的来就可以了,先看效果。

    然后慢慢的就可以了,如果有啥不一样的、或者有问题,欢迎评论留言哦~  咱们一起沟通解决写

    ok了!

  • 相关阅读:
    虚拟机三种虚拟网络的区别
    关于 三次握手和四次挥手 的生动解析
    Tkinter布局管理器
    F#周报2019年第4期
    F#周报2019年第3期
    ML.NET 0.9特性简介
    F#周报2019年第2期
    浏览器保存数据的几种方法
    F#周报2019年第1期
    ML.NET教程之客户细分(聚类问题)
  • 原文地址:https://www.cnblogs.com/zbzdqsmh/p/13637901.html
Copyright © 2020-2023  润新知