Упаковка и автоматическое обновление приложений Electron

внешний интерфейс Electron
Упаковка и автоматическое обновление приложений Electron

В предыдущей статье мы рассмотрели некоторые основы электрона,Начните работать с Electron и научитесь писать полный практический кейс, здесь мы продолжим знакомить с упаковкой Electron и автоматическими обновлениями на основе этого проекта.

создать значок

Перед упаковкой приложения подготовьте значок приложения в качестве значка пакета установки. Для разных операционных систем требуются разные форматы значков. Соответствующий формат для Mac:icns, соответствующий формат для Windowsico.

Генерация иконок может быть выполнена с помощьюelectron-icon-builder.

  • Во-первых, подготовьте1024*1024的pngКартинка, кидаем картинку в папку проекта, выбираем поставить сюдаtasky/public文件夹середина.

image.png

  • Установите электронно-иконостроитель:

    npm i electron-icon-builder --D

  • существуетpackage.jsonизscriptsДобавить команду:

    "build-icon": "electron-icon-builder --input=./public/icon.png --output=build --flatten"

  • бегатьnpm run build-icon, будет вbuildВ папке создается ряд файлов значков, необходимых для упаковки.

image.png

Пакетные приложения

В экосистеме Electron есть два широко используемых инструмента упаковки:electron-builderа такжеelectron-packager.

electron-builderКонфигурация более гибкая, а использование более обширное. Ниже мы используемelectron-builderупаковать.

Установить

npm i electron-builder --D

настроить

использоватьelectron-builderУпаковка в основном разнообразная, поддерживает два способа настройки:

  1. существуетpackage.jsonдобавлено вbuildПоле:
"build": {
  "appId": "your.app.id"
}
  1. Задает файл конфигурации, в который записываются элементы конфигурации. По умолчанию находится файл electronic-builder.yml в корневом каталоге проекта.
appId:"your.app.id"

В ежедневном развитии,package.jsonЭтот метод настройки используется чаще, и мы в основном используем этот метод.

Базовая конфигурация

"build": {
    "appId": "this.is.tasky", 
    "productName": "Tasky",
    "copyright": "Copyright © 2021 Alaso",
    "directories": {
      "buildResources": "build",   //指定打包需要的静态资源,默认是build
      "output": "dist",  //打包生成的目录,默认是dist
    }
 },

Папка сборки помещается с,electron-builderСтатические файлы по умолчанию, необходимые в процессе упаковки, такие как файл значка, который мы создали выше; папка dist содержит различные файлы, созданные в процессе упаковки.

  1. существуетpackage.jsonизscriptsДобавить команду:"pack": "electron-builder"
  2. бегатьnpm run pack

На основе приведенной выше конфигурации,electron-builderФайлы по умолчанию будут упакованы в соответствии с текущей операционной системой. Например, под платформой Windows результаты упаковки следующие:

image.png

Конфигурация, зависящая от платформы

electron-builderОн автоматически определит текущую операционную систему и распечатает установочный пакет, соответствующий системе.Это также означает, что если вы хотите сгенерировать exe\msi, вам нужно быть в операционной системе Windows, а если это dmg, вам нужно быть в операционной системе Mac.

electron-builderСреди вариантов конфигурации есть много конфигураций, связанных с операционной системой, которые можно настроить для упаковки разных платформ. Ниже в качестве примеров используются Windows и Mac, чтобы представить некоторые часто используемые конфигурации, связанные с платформой.

  1. Windows
"build": {
  ...
  "win": {
    "target": ["msi","nsis"],        //安装包的格式,默认是"nsis"
    "icon": "build/icons/icon.ico"   //安装包的图标
  },
  
  //"target"值"nsis"打包出来的就是exe文件
  //nsis是windows系统安装包的制作程序,它提供了安装、卸载、系统设置等功能
  //关于"nsis"的一些配置
  "nsis": {                          
    "oneClick": false,               //是否一键安装,默认为true
    "language": "2052",              //安装语言,2052对应中文
    "perMachine": true,              //为当前系统的所有用户安装该应用程序
    "allowToChangeInstallationDirectory": true   //允许用户选择安装目录
  }
}

image.png 2. Mac

...
"build": {
  "mac": {
     "target": ["dmg", "zip"],       //安装包的格式,默认是"dmg"和"zip"
     "category": "public.app-category.utilities"  //应用程序安装到哪个分类下,具体有哪些分类可以在苹果官网上找
  },
  "dmg": {
     "background": "build/background.jfif",   //安装窗口背景图
     "icon": "build/icons/icon.icns",         //安装图标
     "iconSize": 100,                         //图标的尺寸
     "contents": [                            //安装图标在安装窗口中的坐标信息
        {
          "x": 380,
          "y": 180,
          "type": "link",
          "path": "/Applications"
        },
        {
          "x": 130,
          "y": 180,
          "type": "file"
        }
     ],
     "window": {                             //安装窗口的大小
        "width": 540,
        "height": 380
     }
   }
}

{B92F643C-E8F2-183F-C7DE-E0C24E347CFC}.jpg {552B6FD3-6150-4409-662B-0916EBC574D3}.jpg

Какие файлы будут упакованы в установочный пакет

В созданной папке пакета будетapp.asar, который является основным сжатым пакетом бизнес-файлов приложения Electron.Чтобы узнать, какие файлы в проекте упакованы в установочный пакет, вы можете распаковать их с помощьюapp.asarсмотреть.

распаковатьapp.asarВам нужно использовать инструмент asar, сначала установите его:npm i asar -g.

затем переключитесь наapp.asarкаталог, выполнить:asar extract app.asar ./app-folder.

Возьмем окна в качестве примера,app.asarродыtasky\dist\win-unpacked\resourcesВ каталоге после распаковки можно увидеть содержимое app-папки следующим образом:

image.png

Как видите, практически все файлы в проекте (кромеpackage-lock.json\ .gitignore \ buildпапка), а такжеnode_modules.

дляnode_modules,не всеnode_modulesСодержимое будет упаковано в установочный пакет, толькоpackage.jsonсерединаdependenciesЗависимости в полях будут упакованы,devDependenciesЗависимости в полях нет.Это единственное правило, и оно не имеет никакого отношения к тому, действительно ли проект использует зависимости.

Поэтому, чтобы уменьшить размер инсталляционного пакета, рекомендуется, чтобы внешние пакеты, используемые в процессе рендеринга, устанавливались вdevDependencies, а затем используйте webpack для упаковки кода внешнего пакета и бизнес-кода вместе, что будет подробно описано в следующей статье.

Конечно,Вы можете указать, какой контент упаковывать, настроив поле файлов.image.png

Например, мы упаковываем толькоsrc文件夹,index.jsа такжеpackage.json, который можно настроить следующим образом:

"build": {
  "files": [
    "package.json",
    "index.js",
    "src/**/*"
  ]
}

автоматическое обновление

Для автоматического обновления установочный пакет приложения должен храниться на сервере в Интернете.Каждый раз, когда приложение открывается, выполняется автоматическое определение, и в соответствии с текущим приложениемversionСопоставьте с онлайн-версией, когда будет найдена новаяversionКогда загрузка будет завершена, она будет загружена автоматически.После завершения загрузки пользователю будет предложено установить новую версию.

image.png

Пакет разных версий

существуетpackage.jsonСреди них есть"version"поле для определения текущей версии.

  • шаг 1: настройка"version": "1.0.0",бегатьnpm run pack
  • шаг 2: установить"version": "1.0.1", бегатьnpm run pack

Хотя мы не изменили содержание приложения, но оно будет распознаваться как две версии «1.0.0» и «1.0.1».

Собрать сервер для установки инсталляционного пакета

Запускаем сервер локально и ставим последнюю версию установочного пакета ресурсов.

  • 1. Инициализация
mkdir tasky-server
cd tasky-server
npm init -y
npm install koa koa-static --save
  • 2. Создайте новый в каталоге Tasky-Server.index.js, Читается следующим образом:
const Koa = require('koa')
const app = new Koa()

const static = require('koa-static')
const path = require('path')

app.use(static(path.join(__dirname,'./static')));

app.listen(9005)
  • 3. Создайтеstaticпапку, поставить последнюю версию инсталляционного пакета. Какие файлы включены? Предположим, что последняя версия "1.0.1".

Платформа Mac: latest-mac.yml,Tasky-1.0.1-mac.zip,Tasky-1.0.1.dmg,Tasky-1.0.1.dmg.blockmap

Платформа Windows: latest.yml,Tasky 1.0.1.msi,Tasky Setup 1.0.1.exe,Tasky Setup 1.0.1.exe.blockmap

image.png

  • 4. Запустите сервер.node index.js

Проверить наличие обновлений

Обнаружение обновлений может быть выполнено с помощьюelectron-updaterреализовать. он сочетает в себеelectron-builder, что очень просто реализовать. код напрямую.

  • Первый шаг, настроить в сборке"publish"Поле:
"build": {
    ...
    "publish": [
      {
         "provider": "generic",
         "url": "http://127.0.0.1:9005/" 
      }
    ]
}

Второй шаг — вызов основного процесса приложения.electron-updaterОбновление обнаружения модуля.

const { autoUpdater } = require('electron-updater')
function checkUpdate(){
  if(process.platform == 'darwin'){  
  
    //我们使用koa-static将静态目录设置成了static文件夹,
    //所以访问http://127.0.0.1:9005/darwin,就相当于访问了static/darwin文件夹,win32同理
    autoUpdater.setFeedURL('http://127.0.0.1:9005/darwin')  //设置要检测更新的路径
    
  }else{
    autoUpdater.setFeedURL('http://127.0.0.1:9005/win32')
  }
  
  //检测更新
  autoUpdater.checkForUpdates()
  
  //监听'error'事件
  autoUpdater.on('error', (err) => {
    console.log(err)
  })
  
  //监听'update-available'事件,发现有新版本时触发
  autoUpdater.on('update-available', () => {
    console.log('found new version')
  })
  
  //默认会自动下载新版本,如果不想自动下载,设置autoUpdater.autoDownload = false
  
  //监听'update-downloaded'事件,新版本下载完成时触发
  autoUpdater.on('update-downloaded', () => {
    dialog.showMessageBox({
      type: 'info',
      title: '应用更新',
      message: '发现新版本,是否更新?',
      buttons: ['是', '否']
    }).then((buttonIndex) => {
      if(buttonIndex.response == 0) {  //选择是,则退出程序,安装新版本
        autoUpdater.quitAndInstall() 
        app.quit()
      }
    })
  })
}

app.on('ready', () => {
  //每次启动程序,就检查更新
  checkUpdate()
}

image.png

Что является основанием для определения необходимости обновления?

Electron-Updater укажет путь в соответствии с SetFeedurl выше.latest.ymlсерединаversionчтобы определить, требуется ли обновление, большее, чем текущая версияversionЕго нужно обновить, иначе он не будет обновляться..ymlЭто также файл конфигурации, немного похожий на наш обычно используемый.jsonФайлы конфигурации пишутся по-разному.image.png

решение на гитхабе

Если вы не хотите настраивать свой сервер, вы также можете помочь github. Github использует автоматическую публикацию, без ручной загрузки ресурсов каждого нового установочного пакета.

автоматическая публикация

Первый шаг по-прежнему заключается в настройке"publish"поле.

"build": {
    ...
    "publish": ['github']
}

Второй шаг, в"scripts"Настройте новые инструкции в , из-за контроля разрешений github требуется GH_TOKEN, который можно найти вGitHub.com/settings/к…Сгенерируйте GH_TOKEN в формате .

"scripts": {
    ...
    "release": "cross-env GH_TOKEN=ghp_KmVD3.......W2k3Pd4vV electron-builder"
}

третий шаг,npm run release, он загрузит ресурсы на github после упаковки и сгенерирует черновик релиза. Вы можете найти этот черновик в проекте github и опубликовать релиз.

image.png image.png

Проверить наличие обновлений

Аналогично приведенному выше, на примере Windows код выглядит следующим образом.

const { autoUpdater } = require('electron-updater')
function checkUpdate(){
  //检测更新
  autoUpdater.checkForUpdates()
  
  //监听'error'事件
  autoUpdater.on('error', (err) => {
    console.log(err)
  })
  
  //监听'update-available'事件,发现有新版本时触发
  autoUpdater.on('update-available', () => {
    console.log('found new version')
  })
  
  //默认会自动下载新版本,如果不想自动下载,设置autoUpdater.autoDownload = false
  
  //监听'update-downloaded'事件,新版本下载完成时触发
  autoUpdater.on('update-downloaded', () => {
    dialog.showMessageBox({
      type: 'info',
      title: '应用更新',
      message: '发现新版本,是否更新?',
      buttons: ['是', '否']
    }).then((buttonIndex) => {
      if(buttonIndex.response == 0) {  //选择是,则退出程序,安装新版本
        autoUpdater.quitAndInstall() 
        app.quit()
      }
    })
  })
}

app.on('ready', () => {
  //每次启动程序,就检查更新
  checkUpdate()
}

Эпилог

В нашем примере выше все веб-ресурсы страницы упакованы в установочный пакет, в другом случае веб-ресурсы отделены от «оболочки приложения», а веб-ресурсы размещены на сервере и загружаются динамически через сеть. каждый раз, как показано ниже так:

mainWindow.loadURL('https://juejin.cn')

В сценариях, когда бизнес требует частого обновления, этот метод можно использовать для быстрого и простого внедрения обновлений. В этом случае мы можем упаковать и обновить «оболочку» вышеописанным способом, который связан с основным процессом, а упаковка ресурсов страницы ничем не отличается от упаковки обычных фронтенд-проектов, так что я выиграл не вдаваться в подробности здесь.

Эта статья в основном объясняет использованиеelectron-builderУпаковка приложений и автоматические обновления, в следующей статье мы рассмотрим комбинацию Electron и Vue.

Спасибо за прочтение, если вы считаете, что это хорошо, ставьте лайк ❤️❤️!

Для более технических обменов, пожалуйста, обратите внимание на мой общедоступный номер: Alasolala