美文网首页让前端飞基础资源
electron打包更新到集成sqlite

electron打包更新到集成sqlite

作者: coderLfy | 来源:发表于2019-04-03 13:52 被阅读7次

    本文主要讲以下几点

    • 简单介绍electron
    • electron的进程与渲染层通讯
    • electron的打包配置
    • electron的自动更新
    • electron如何集成sqlite3
    • electron的资料分享
    • electron在内网开发的一点点建议
    • electron主进程的生命周期

    快速开始一个electron与简介

    electron是什么

    打开官网第一眼就是使用 JavaScript, HTML 和 CSS 构建跨平台的桌面应用,更加通俗一点就是一个桌面浏览器,实际上这样理解也是对的。因为electron就是通过javaScript使chromium来展示web页面

    我为啥用它

    • 前端可用制作跨平台应用
    • 生态圈好
    • 由github开发维护
    • electron(70+k)比nw.js (35+k)Star多两倍
    • electron产品我使用过表现优秀
      • Vscode
      • Atom
      • gitHub桌面端
      • ...

    如何快速上手electron

    我认为以下是快速开始的最好办法

    • 一定要多读官方文档,可以减少大部分时间
    • 官方提供的快速开始模板
    • 官方提供快速熟悉的API的模板

    直接使用electron官方提供的例子

    // 看这个的源码,很简单可以快速上手
    # 克隆这仓库
    $ git clone https://github.com/electron/electron-quick-start
    # 进入仓库
    $ cd electron-quick-start
    # 安装依赖库
    $ npm install
    # 运行应用
    $ npm start
    

    如果想了解这个electron的API可以克隆这个库并运行

    git clone https://github.com/electron/electron-api-demos
    
    cd electron-api-demos
    
    npm install
    
    npm start
    
    

    如何调试electron

    渲染进程调试(web页面)
    渲染器进程这chrome浏览器一样,BrowserWindow创建窗口后添加窗口实例.webContents.open

    主进程Electron调试
    使用vsCode中的debug,注意调试路径,如果需要增加变量环境依照配置增加即可

    electron中主进程的生命周期以及常用事件和渲染层

    主要聊electron中主进程的生命周期,渲染器的部分生命周期,一般只介绍通用都存在的,如果只有某个系统有的api就不写在这里了,大家可以自行查阅

    主进程中的生命周期

    生命周期图

    生命周期图

    正常流程会触发的生命周期

    • will-finish-launching:当应用程序完成基础的启动的时候被触发
    • web-contents-created:webContents被创建完成
    • browser-window-created:BrowserWindow被创建完成
    • ready:当 Electron 完成初始化时被触发
    • remote-require: 引入remote时被调用
    • before-quit: 在应用程序开始关闭窗口之前触发
    • will-quit:当所有窗口都已关闭并且应用程序将退出时发出
    • quit: 在应用程序退出时发出
    • window-all-closed:当所有的窗口都被关闭时触发

    这里要注意如果是进程杀死退出的所有都不触发,如果是cmd+Q或者开发者使用app.quit()退出的window-all-closed是不会被触发的,基本操作一般在ready中处理

    进程相关

    • gpu-process-crashed: 当 gpu 进程崩溃或被杀时触发。

    其他

    • browser-window-focus: 在 browserWindow 获得焦点时发出
    • browser-window-blur:在 browserWindow 失去焦点时发出

    渲染进程--(浏览器)-BrowserWindow

    • ready-to-show:当页面已经渲染完成(但是还没有显示) 并且窗口可以被显示时触发
    • move: 窗口移动
    • resize: 调整窗口大小后触发
    • close: 在窗口要关闭的时候触发。 它在DOM 的beforeunload 和 unload 事件之前触发.
    • blur: 失去焦点,同app
    • focus: 获得焦点,同app
    • maximize:窗口最大化时触发
    • unmaximize: 当窗口最大化退出状态触发
    • minimize: 窗口最小化时触发
    • restore: 当窗口从最小化还原触发
    • ...

    渲染进程 BrowserWindow实例中的webContents

    • did-finish-load:导航完成时触发,即选项卡的旋转器将停止旋转,并指派onload事件后
    • did-finish-load: 这个事件类似于 did-finish-load, 不过是在加载失败或取消后触发
    • dom-ready: 一个框架中的文本加载完成后触发该事件
    • crashed: 当渲染进程崩溃或被结束时触发
    • unresponsive: 页面未响应触发
    • devtools-opened: 当开发者工具被打开时,触发该事件。
    • devtools-closed: 当开发者工具被关闭时,触发该事件。
    • ...

    electron的进程与渲染层通讯

    • 主进程和渲染器进程
    • 主进程和渲染器进程的区别
    electron主进程与渲染进程

    chrome浏览器由于每个标签页都是一个进程,而electron所运行的进程称为主进程并且只有一个,主进程要操控浏览器的每个标签的网页称为渲染器进程,如何通讯呢?

    主进程和渲染器进程

    进程

    进程是正在运行的程序的实例(狭义定义)

    electron中的主进程

    Electron 运行 package.json 的 main 脚本的进程被称为主进程。 在主进程中运行的脚本通过创建web页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。

    electron中的渲染器进程

    由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它自己的渲染进程中。

    渲染器进程与主进程之间的区别

    • 主进程是从开始运行一直存在,渲染器进程通过BrowserWindow来创建实例,实例销毁则渲染进程销毁

    主进程使用 BrowserWindow 实例创建页面。 每个 BrowserWindow 实例都在自己的渲染进程里运行页面。 当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。

    • 主进程管理所有渲染进程,渲染进程是独立且自我管理(web页面)

    主进程管理所有的web页面和它们对应的渲染进程。 每个渲染进程都是独立的,它只关心它所运行的 web 页面。

    • 主进程中可以调用底层所有的GUI的API,渲染进程则因为安全问题不能随意调用。如果要调用则需要通讯让主进程来调用。

    在页面中调用与 GUI 相关的原生 API 是不被允许的,因为在 web 页面里操作原生的 GUI 资源是非常危险的,而且容易造成资源泄露。 如果你想在 web 页面里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。

    主进程与渲染器进程如何通讯

    主进程与渲染器进程通过ipcMain与ipcRenderer来通讯

    ipcMain与ipcRenderer通讯

    主进程向渲染器进程通讯

    这个方式主要是主进程中使用ipcMain使用on监听,监听获取后通过event.sender(相当于webContent)send来发送一个事件,渲染进程中使用ipcRenderer通过on来接收,如果是同步可以通过evnet.returnValue来返回主进程的结果代码如下:

    渲染器进程向主进程通讯

    渲染器进程主要通过ipcRenderer这个模块中的send来发送,该方法中可以同步与异步发送消息,接收消息使用on来接收

    通讯简化

    electron的打包

    常用方式:

    1. electron-builder(本人主要用这个)
    2. electron-pakager
    3. electron-forge

    electron-builder

    electron-builder 是一个完整的解决方案,并且自带自动更新策略

    electron-builder打包在package的script配置好

    打包常用参数:

      "build": {
        "appId": "your.id", // appid
        "productName": "程序名称", // 程序名称
        "files": [    // 打包需要的不过滤的文件
          "build/**/*",
          "main.js",
          "node_modules/**/*"
        ],
        "directories": { 
          "output": "./dist-out", // 打包输出的目录
          "app": "./",  // package所在路径
          "buildResources": "assets"   
        },
        "nsis": {
          "oneClick": false,  // 是否需要点击安装,自动更新需要关掉
          "allowToChangeInstallationDirectory": true, //是否能够选择安装路径
          "perMachine": true // 是否需要辅助安装页面
        },
        "win": {
          "target": [
            {
              "target": "nsis",  // 输出目录的方式
              "arch": [ // 输出的配置ia32或者x64/x86
                "x64"
              ]
            }
          ],
          "publish": [ // 自动更新的配置
            {
              "provider": "generic", // 自己配置更新的服务器要选generic
              "url": "http://127.0.0.1:8080/updata/" //更新配置的路径
            }
          ]
        }
      }
    

    在package.json中增加的快速启动项

    "scripts": {
      "pack": "electron-builder --dir",
      "dist": "electron-builder"
    }
    

    启动打包

    通常需要注意的点

    • 注意路径,由于打包后的路径会有问题最好使用path.join()来处理一下。
    • 碰到 The process cannot access the file because it is being used by another process.这个问题多数是vscode占用了关掉重开就好了

    如果配合create-react-app创建出来的应用

    • 可以先让react的程序进行打包成静态文件,在把静态文件打包到electron应用中
    • 如果electron-builder总是报类似electron.js找不到的警告,并且在上面提示让你去看网页中的方法,可以通过electron-builder提示的网址来修改,这实际是一个教程需要科学上网。

    electron-builder的自动更新

    如果在API中看到autoUpdater这个API,希望在看到这个API之前先参考官方的自动更新这样会让你少点坑,因为electron-builder的自动更新机制和electron提供有些不一样,electron-builder官网也有说明,否则就会一直报error了

    这个更新实际上是对比例两个版本之间的版本号,如果当前版本小于,服务器版本的话就会进行下载更新

    更新机制

    在资料里有一篇专门讲更新机制的,很好。这里简单总结。


    更新步骤.png

    autoUpader生命周期

    • error: 如果任意一个环节有问题就会走到这步
    • checking-for-update :当开始检查更新的时候触发。
    • update-available: 发现更新
    • update-not-available:当没有可用更新的时候触发.
    • update-downloaded: 在更新下载完成的时候触发。
    • before-quit-for-update : 此事件是在用户调用quitAndInstall()之后发出的。

    更新要注意的点:

    • electron-builder中的autoUplader需要使用 electron-updater这个模块,非原生模块
    • package.json中的publish中的url与更新的地址要一致(注意端口),否则会报net::ERR_CONNECTION_REFUSED
    • 如果是未打包也想跑一边autoUpdater的流程需要一个dev-app-update.yml的文件放在与main.js同一层级的地方,类似win-ia32-unpacked/resource/app-update.yml这样的文件,直接复制改名就能使用
    • 如果更新完成后在package中配置了自动安装的选项,在关闭应用就能直接安装,如果想自己控制马上安装需要加autoUpdater.quitAndInstall()
    • 如果初次启动应用在终端输出了你想要的结果,在渲染选只输出来了一部分,或者没有输出,如果不是报错的话,不妨监听一下该渲染进程的did-finish-load这个声明周期,在这里面做处理,根据场景可以使用once来监听
    • 需要一个静态网站服务器在你需要的文件夹使用http-server -o,如果没有就全局安装一个npm i http-server -g,在package中需要配置publish中的"provider": "generic"
    • 碰到spawn **/*.exe ENOENT这类的可能是你在开发环境运行了一个未安装的应用,并且使用了autoUpdater.quitAndInstall()就会报错,如果是安装好了就不会报这个错
    //electron-quick-start 
    //main.js 主进程中
    
    // 可以没有这个
    const { autoUpdater } = require('electron-updater')
    
    // ================= start 非必须 ===============
    const log = require('electron-log');
    autoUpdater.logger = log;
    autoUpdater.logger.transports.file.level = 'info';
    // ================ end 非必须 ==================
    
    // 封装
    function sendStatusToWindow(text) {
      log.info(text);
      mainWindow.webContents.send('message', text);
    }
    
    /**
     * 自动更新
     */
    function checkUpdata() {
      autoUpdater.setFeedURL('http://127.0.0.1:8080/updata/')
      // autoUpdater.on('error', (error) => {
      //   sendStatusToWindow( `[error]:${error}`)
      // })
      autoUpdater.on('checking-for-update', () => {
        sendStatusToWindow('Checking for update...');
        // mainWindow.webContents.send('downlaod')
    
      })
      autoUpdater.on('update-available', (info) => {
        sendStatusToWindow('Update available.');
      })
      autoUpdater.on('update-not-available', (info) => {
        sendStatusToWindow('Update not available.');
      })
      autoUpdater.on('error', (err) => {
        sendStatusToWindow('Error in auto-updater. ' + err);
      })
      autoUpdater.on('download-progress', (progressObj) => {
        let log_message = "Download speed: " + progressObj.bytesPerSecond;
        log_message = log_message + ' - Downloaded ' + progressObj.percent + '%';
        log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')';
        sendStatusToWindow(log_message);
        mainWindow.webContents.send('downloadExe', progressObj.percent)
      })
      autoUpdater.on('update-downloaded', (info) => {
        mainWindow.webContents.send('downloaded')
    
    
        sendStatusToWindow('Update downloaded');
        // autoUpdater.quitAndInstall();
      });
    
    

    electron中添加sqlite3

    需要的环境

    如果是windows环境需要准备 vs2015 与python2.7的环境

    1. python2.7.x 网上下载安装即可
    2. vs2015 以下方式可选其一
      1. 工具包 npm install --vs2015 -g windows-build-tools(推荐)
      2. 安装visual studio 中安装vs2015工具包(超久)

    程序中可添加的本地数据库,最多使用的两款

    • sqlite3(关系型)
    • neDB(非关系型)

    为自己的数据加上本地数据库sqlite3

    sqlite3【gitHub】
    为程序添加sqlite3npm i sqlite3 或者yarn add sqlite3

    如何使用?

    // 官网例子
    var sqlite3 = require('sqlite3').verbose();
    var db = new sqlite3.Database(':memory:'); // 这里是把数据存入内存
    db.serialize(function() {
    var db = new sqlite3.Database()
      db.run("CREATE TABLE lorem (info TEXT)");
      var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
      for (var i = 0; i < 10; i++) {
          stmt.run("Ipsum " + i);
      }
      stmt.finalize();
    
      db.each("SELECT rowid AS id, info FROM lorem", function(err, row) {
          console.log(row.id + ": " + row.info);
      });
    });
    
    db.close();
    

    sqilte3在安装的时候自动生成sqlite所需要的文件包,这个二进制文件需要使用node-pre-gyp或者是node-gyp这也就是为什么需要安装环境的原因,在这一步鬼知道当时报了多少东西,尤其是还要把这玩意弄进内网。
    比如说:

    • 开始运行的时候就报Error: Cannot find module 'E:\electronjs\electron-quick-start\node_modules\sqlite3\lib\binding\electron-v4.0-win32-x64\node_sqlite3.node'类似这样的东西,实际上确实没有这个东西,怎么解决呢?
      • 使用node-gyp这个模块直接重新编译一个版本正确的
    node-gyp rebuild 
    --target=4.0.4 --arch=x64
    --target_platform=win32 --dist-url=https://atom.io/download/electron/
    --module_name=node_sqlite3 --module_path=../lib/binding/electron-v4.0-win32-x64
    
    // 使用到的模块解析
    // target                => electron的版本号一定要一直
    // target_platform       => 需要打包的平台ia32/x64等
    // dist-url              => 这个是需要下载相关内容的地址
    // module_name           => 需要打包的模块名称
    // module_path           => 打包输出的地方
    

    如果觉得麻烦可以试试npm i electron-rebuild -D然后在使用./node_modules/.bin/electron-rebuild重新编译一遍,有时候可能是缓存问题,把缓存清除npm cache clear -f清除一下,还有就是npm i重新安装一下,因为环境的问题会跳出各种问题,可以多多尝试这些方法

    was compiled against a different Node.js version using
    NODE_MODULE_VERSION 64. This version of Node.js requires
    NODE_MODULE_VERSION 69. Please try re-compiling or re-installing
    

    如让你选择node编译版本的github【issues】====>也有可能是编译问题,利用electron-rebuild 重新编译一遍或者把sqlite3降级

    需要注意的

    • 打包的时候如果报error MSB4019: 未找到导入的项目Microsoft.WebApplication.targets重新安装一下vs2015工具包,或者以前安装的有问题重新安装(我就碰到了)
    • 用node-gyp编译sqlite3打包需要binding.gyp这个python文件以及其他配置所以直接进入node_modules\sqlite3这个文件运行 node-gyp的操作
    • 打包的时候要注意在渲染进程中使用sqlite3在打包的时候会出现打包问题,解决可以选在在主进程操作本地数据库
    • 打包之后使用DB会出现一个问题,在当前目录怎么都生成不了DB,在网上查了要么就通过手动授权为管理员打开,要么手动管理员打开,这根本就不能行,后来参考electron-vue发现可以使用app.getPath('userData')这个方法进行获取app可缓存地址,然后使用path.join合并一下路径就解决了无法生成DB文件的问题,事实上indexDB,locaStore这个两个的存储文件也在这个目录下

    其他模块

    • globalShortcut: 注册全局快捷键
    • Tray: 托盘
    • Menu:菜单事件

    内网开发需要注意

    内网开发真的很烦。。
    首先需要环境,然后就是需要下载的包,其次就是需要编译后的各种文件如sqlite3编译后的文件等如果在内网开发electron就需要把这些需要的包全都复制到对应位置

    大部分需要配置的文件都在C:\Users\xxxxxx代表你所在的文件夹,
    部分下载缓存文件在C:\Users\xxx\AppData\Local目录下的electron 和 electron-builderer里

    内网01.png

    参考的学习资料

    以下文章大部分阅读过,觉得不错推荐给大家

    electron

    electron构建相关

    electron打包相关

    electron更新

    electron

    electron编译

    electron tips

    相关文章

      网友评论

        本文标题:electron打包更新到集成sqlite

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