Практика разработки Electron-vue 4 — выпуск и обновление через CI

Vue.js Electron

предисловие

Некоторое время назад я использовалelectron-vueРазработано кросс-платформенное (в настоящее время поддерживающее Mac и Windows) бесплатное приложение для загрузки изображений с открытым исходным кодом——PicGo, я наступил на много ям в процессе разработки, причем не только со стороны бизнес-логики самого приложения, но и со стороны самого электрона. В процессе разработки этого приложения я многому научился. Поскольку я также начал изучать электрон с нуля, такой большой опыт также должен вдохновить и дать инструкции начинающим ученикам, которые хотят изучать разработку электронов. Поэтому я написал практический опыт разработки Электрона и объяснил его с точки зрения наиболее близкой к разработке реальных инженерных проектов. Надеюсь помочь всем.

Ожидается, что несколькоСерия статейИли расширить с точки зрения:

  1. Начало работы с электрон-вью
  2. Простая разработка основного процесса и процесса визуализации
  3. Представляем базу данных JSON на основе Lodash - lowdb
  4. Некоторые меры кроссплатформенной совместимости
  5. Выпуск и обновление через CI
  6. ... (подумайте о написании снова)

иллюстрировать

PicGoсостоит в том, чтобы принятьelectron-vueразработан, поэтому, если выvue, то учиться вместе будет быстрее. Если ваш технический стек похож наreact,angular, то чисто по этому туториалу, хотя вы можете и не много узнать о построении стороны рендера (которую можно понимать как страницу), вы все же должны получить соответствующие знания по основной стороне (основной процесс электрон).

Если вы не читали предыдущую статью, вы можете начатьпредыдущая статьяСледуйте вместе.

Подготовка логотипа

После настоящей битвы предыдущих статей я считаю, что у всех не так уж много проблем с созданием базового электронного приложения. В этой статье в основном объясняется, как разрешить нашему приложению автоматически помогать нам создавать приложение через систему CI, а затем публиковать его для пользователей. И как уведомить пользователей, если позже будет обновление.

Конечно, перед этим нам еще нужно сделать еще одну вещь: добавить красивый ЛОГОТИП в ваше приложение. Дизайн и производство LOGO не входит в задачу этой статьи. Чтобы наше приложение можно было использовать на разных платформах, размер и формат LOGO приложений на разных платформах также различаются. Форматы изображений, необходимые для трех платформ, следующие:

  • Linux - png
  • macOS - icns
  • Windows - ico

Подготовьте изображение в формате png ниже 1024*1024 и выше 256*256 (постоянная длина и ширина) (рекомендуется 512*512), а затем мы можем использовать некоторые инструменты для перехода от png к двум другим форматам. Если вы ищете png в ico или png в icns, существует множество веб-сайтов для онлайн-конвертации, вы можете перейти к вышеупомянутой онлайн-конверсии. На Mac я рекомендую использоватьimage2iconэтот инструмент.

Затем мы помещаем полученные три файла изображения в корневую директорию проекта electronic-vue.build/icons/Под содержанием.

Создание конфигураций для разных платформ

В этой статье мы в основном используем electronic-vue, настроенный на основеelectron-builderbuild script для сборки нашего приложения. Сценарий сборки будет читатьpackage.jsonвнутреннийbuildКонфигурация в поле для сборки. Конфигурация electronic-vue по умолчанию выглядит следующим образом:

"build": {
  "productName": "ElectronVue",
  "appId": "org.simulatedgreg.electron-vue",
  "dmg": {
    "contents": [
      {
        "x": 410,
        "y": 150,
        "type": "link",
        "path": "/Applications"
      },
      {
        "x": 130,
        "y": 150,
        "type": "file"
      }
    ]
  },
  "directories": {
    "output": "build"
  },
  "files": [
    "dist/electron",
    "node_modules/",
    "package.json"
  ],
  "mac": {
    "icon": "build/icons/icon.icns"
  },
  "win": {
    "icon": "build/icons/icon.ico"
  },
  "linux": {
    "icon": "build/icons"
  }
}

Кратко опишите значение некоторых полей в конфигурации сборки.

первыйproductNameэто имя вашего приложения.appIdРоль состоит в том, чтобы использовать платформу Windows, чтобы различать идентичность приложения. (УведомлениеЭта конфигурация должна быть настроена, и будут места, где она будет использоваться позже. Если он не настроен и не используется, то встроенное приложение платформы Windows не сможет отправить на рабочий стол уведомление об элетроне)dmgЭта конфигурация описывает платформу macOS, открытуюdmgИнформация в интерфейсе отображается после установки пакета. Как показано ниже:

Указывает, что имеется два идентификатора, один из которых является файлом приложения, а координаты(130, 150), один ярлык на папку приложения, координаты есть(410, 150).

directoriesизoutputПоле — это каталог, в котором упакованы файлы, сгенерированные вашим приложением.

filesУказывает каталог для упаковки.

а такжеmac,win,linuxЭто разные конфигурации для трех платформ. Видно, что их конфигурации в конфигурации по умолчанию указывают на разные значки (то есть на ЛОГОТИП, упомянутый в предыдущем разделе).

При фактической разработке PicGo в некоторых случаях по умолчаниюbuildНекоторые изменения были внесены в элементы конфигурации:

"build": {
  "productName": "PicGo",
  "appId": "com.molunerfinn.picgo",
  "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",
    "extendInfo": {
      "LSUIElement": 1
    }
  },
  "win": {
    "icon": "build/icons/icon.ico",
    "target": "nsis"
  },
  "nsis": {
    "oneClick": false,
    "allowToChangeInstallationDirectory": true
  },
  "linux": {
    "icon": "build/icons"
  }
},

Поскольку PicGo — это в основном приложение для верхней панели в macOS, я не хочу иметь значок-заполнитель в нижней панели докеров, поэтому вmacВ поле добавлено:

"extendInfo": {
  "LSUIElement": 1
}

это свойство. Ссылка, связаннаяissue.

На платформе Windows нет возможности выбрать путь установки инсталляционного пакета, упакованного по умолчанию, и по умолчанию он будет установлен только в пользовательскую директорию на диске C. Это не то, чего мы хотим. Мы хотим, чтобы пользователь мог выбрать путь для установки.

Так что нужно изменитьwindowsнекоторая конфигурация и плюсnsisконфигурация для достижения:

"win": {
  "icon": "build/icons/icon.ico",
  "target": "nsis"
},
"nsis": {
  "oneClick": false,
  "allowToChangeInstallationDirectory": true
}

Поскольку я еще не упаковывал приложения для платформы Linux, конфигурация, связанная с Linux, пока не будет изменена.

Небольшая яма, упаковывающая платформу Windows

Помните конфигурацию, упомянутую ранее:appIdНу, эта конфигурация требует, чтобы мы были в основном процессеindex.jsтакже использоваться. В противном случае упакованное приложение потеряет функцию уведомления приложений платформы Windows. этоappIdЕго можно брать произвольно, главное, чтобы он гарантированно не повторялся с другими приложениями. Для PicGo,appIdдаcom.molunerfinn.picgo.

Откройте свойmain/index.js, добавьте это на платформе WindowsappId:

// ...
import pkg from '../../package.json'

// ...
// ...

if (process.platform === 'win32') {
  app.setAppUserModelId(pkg.build.appId)
}

Это решает проблему уведомлений.

Автоматическая сборка и выпуск через систему CI

Связанные с версией

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

  1. Склад имеет две основные ветки: одну для разработчиков и одну для мастера. Обычно разрабатывается на dev, сливается с мастером только при выпуске новой версии.
  2. Напишите простую обновленную версию скрипта, тег в один клик + отправка на GitHub.
  3. В сочетании с системой CI код основной ветки создается автоматически, и приложение помещается в репозиторий GitHub.

где простая обновленная версия скрипта, в которой я былpackage.jsonнаписал простойscripts:

"scripts": {
  "patch": "npm version patch && git push origin master && git push origin --tags", // 小版本
  "minor": "npm version minor && git push origin master && git push origin --tags", // 次版本
  "major": "npm version major && git push origin master && git push origin --tags"  // 大版本
}

Он использует команду из npm,npm version [options], подробности см. в версииДокументация. Проще говоря, он может автоматически помочь вам обновить версии, изменитьpackage.jsonОтмечена версия в файле и соответствующий git-тег, что очень удобно.

Например, семантический номер версии обычно состоит из следующих трех частей:major.minor.patch,Например1.5.3. Если я бегуnpm run patch, то минорная версия будет обновлена:1.5.4, при измененииpackage.jsonвнутреннийversionПоле1.5.4и автоматически поместите на него тег git1.5.4, и отправьте эту модификацию и тег на удаленный компьютер.

Однако следует отметить, что в начале я привел его с электрон-вьюnpm run buildЭтот сценарий сказал CI выполнить сборку, но обнаружил, что он не может автоматически загрузить его в выпуск GitHub. Поэтому, ознакомившись с соответствующей информацией, я обнаружил, что проще всего назвать соответствующие сценарии npm какrelease. Так что ставлю оригиналnpm run buildСкрипт был скопирован снова и получил новое имяrelease:

"scripts": {
  // ...
  "release": "node .electron-vue/build.js && electron-builder",
  // ...
}

связанные с КИ

При этом система CI еще не упоминалась. Что такое КИ? Вы можете обратиться к объяснению, данному г-ном Жуань Ифэном.«Что такое непрерывная интеграция? 》. Было бы слишком утомительно, если бы нам приходилось создавать его локально каждый раз, когда мы выпускаем приложение, а затем вручную загружать его на GitHub (или куда-либо еще), а затем позволять другим загружать его. И обычно мы разрабатываем электронные приложения, чтобы иметь возможность кросс-платформенности, но создание приложений для разных платформ означает, что мы должны строить на разных платформах отдельно. Это также невыносимо.

Таким образом, в Интернете есть некоторые сторонние системы CI, которые могут помочь нам выполнить определенные сценарии (такие как сборка, тестирование) при обновлении определенных ветвей (например, master) (например, обновленных тегов). Это избавляет нас от необходимости создавать локально на нескольких платформах и делает некоторые вещи «автоматизированными».

С CI выпуск моего электронного приложения становится следующим процессом:

Таким образом, нам нужен только Push-код.

Для сборок Linux или macOS мы можем использоватьTravis-CI, для сборок платформы Windows мы можем использоватьAppVeyor. Хорошей новостью является то, что их можно бесплатно создавать для проектов с открытым исходным кодом на GitHub, и они очень хорошо интегрируются с репозиториями GitHub, а конфигурация относительно проста, что можно назвать очень добросовестной.

Прежде чем использовать их, нам нужно предоставить им определенные разрешения для доступа к нашему репозиторию GitHub. Итак, нужно:

  1. Зарегистрируйте их в своей учетной записи GitHub, чтобы получить список ваших репозиториев.
  2. Сборка на GitHubtoken, предоставляя системе CI разрешение на чтение и запись в ваш репозиторий. Для конкретной операции создания токена вы можете обратиться к статье, которую я написал ранее для шестнадцатеричной персистентности.статья.
  3. Создавайте разные файлы конфигурации для разных платформ CI, чтобы они знали, что вы от них хотите. Тем не менее, electronic-vue любезно подготовил для нас шаблон конфигурационного файла Travis-CI..travis.ymlи шаблон профиля AppVeyorappveyor.yml. Так что нам просто нужно сделать небольшие модификации поверх них.

Travis-CI

После регистрации и входа в Travis-CI найдите репозиторий, который хотите создать, откройте его и нажмите «Настройки», чтобы перейти на следующую страницу:

Настройте переменную среды с именемGH_TOKEN, значение токена — это токен, который мы сгенерировали на GitHub на предыдущем шаге. Это пригодится позже.

ПикГо Модифицированный.travis.ymlследующим образом:

# Commented sections below can be used to run tests on the CI server
# https://simulatedgreg.gitbooks.io/electron-vue/content/en/testing.html#on-the-subject-of-ci-testing
osx_image: xcode8.3
sudo: required
dist: trusty
language: c
matrix:
  include:
  - os: osx
  # - os: linux
    env: CC=clang CXX=clang++ npm_config_clang=1
    compiler: clang
cache:
  directories:
  - node_modules
  - "$HOME/.electron"
  - "$HOME/.cache"
addons:
  apt:
    packages:
    - libgnome-keyring-dev
    - icnsutils
before_install:
- mkdir -p /tmp/git-lfs && curl -L https://github.com/github/git-lfs/releases/download/v1.2.1/git-lfs-$([
  "$TRAVIS_OS_NAME" == "linux" ] && echo "linux" || echo "darwin")-amd64-1.2.1.tar.gz
  | tar -xz -C /tmp/git-lfs --strip-components 1 && /tmp/git-lfs/git-lfs pull
install:
- nvm install 8.9
- curl -o- -L https://yarnpkg.com/install.sh | bash
- source ~/.bashrc
- npm install -g xvfb-maybe
- yarn
script:
- npm run release
- yarn run build:docs
branches:
  only:
  - master
after_script:
  - cd docs/dist
  - git init
  - git config user.name "Molunerfinn"
  - git config user.email "marksz@teamsz.xyz"
  - git add .
  - git commit -m "Travis build docs"
  - git push  --force --quiet "https://${GH_TOKEN}@github.com/Molunerfinn/PicGo.git" master:gh-pages

Отбросьте множество предварительных зависимостей (таких как библиотека компиляции C++) и среду сборки (какая система, какой язык), все это предустановлено для нас с помощью electronic-vue. Есть только несколько частей, на которые нам нужно обратить внимание:

  1. script
  2. branches
  3. after_script

scriptЭто команда, которую вы хотите, чтобы CI запускал, когда система, среда и зависимости готовы. Здесь я запускаю две команды, одна из нихnpm run release, это для упаковки и сборки приложения, и после выполнения этой командыelectron-builderСгенерированный установочный пакет будет автоматически помещен в предварительную версию нашего репозитория GitHub. Другой - построить PicGoДомаКомандаyarn run build:docs.

branchesДекларирует, какие ветки вы хотите собрать после получения обновлений кода на GitHub, здесь мы, естественно, выбираем master.

after_scriptЭто то, что вы делаете после выполнения скрипта в скрипте. Может быть пустым. Для меня эта часть в основном продвигает домашнюю страницу PicGo, созданную на предыдущем шаге, на GitHub.gh-pagesветвь. Конечно, если у вашего приложения есть веб-сайт, такой как инструкции и документация, вы также можете создать и отправить его сюда.

обратите внимание, что вafter_scriptВ последней строке команды есть${GH_TOKEN}, это переменная среды, которую мы настроили в конфигурации Travis-CI доGH_TOKEN. Преимущество использования переменных среды заключается в том, что ваш токен не раскрывается, о нем знает только система сборки.

AppVeyor

С предыдущим опытом AppVeyor еще проще. После регистрации и входа в систему мы добавляем ПРОЕКТ на домашнюю страницу и выбираем репозиторий, который вы хотите построить. Затем найдите настройку НАСТРОЙКА:

затем слеваGenralВ области содержимого столбца найдите ветку сборки как мастер и установите нас только вtagСборка при обновлении:

Конечно, это все основано на фактической конфигурации проекта, я просто сказал, что проект PicGo настроен так.

затем слеваEnvironmentобласть, находим конфигурацию переменной окружения, пишем ещеGH_TOKEN:

Не забудьте потянуть вниз, чтобы сохранить после изменения конфигурации!

Это даже в том случае, если настройка веб-страницы завершена. А теперь посмотримappveyor.ymlЭтот файл конфигурации:

# Commented sections below can be used to run tests on the CI server
# https://simulatedgreg.gitbooks.io/electron-vue/content/en/testing.html#on-the-subject-of-ci-testing
version: 0.1.{build}

branches:
  only:
    - master

image: Visual Studio 2017
platform:
  - x64

cache:
  - node_modules
  - '%APPDATA%\npm-cache'
  - '%USERPROFILE%\.electron'
  - '%USERPROFILE%\AppData\Local\Yarn\cache'

init:
  - git config --global core.autocrlf input

install:
  - ps: Install-Product node 8 x64
  - git reset --hard HEAD
  - npm install
  - node --version

build_script:
  #- yarn test
  - npm run release

test: off

Еще нужно только обратить внимание на конфигурацию, которая нас волнует. одинbranches,одинbuild_script. имеютTravis-CIиз.travis.ymlопыт, я верю, что вы можете понять это тоже быстро.

После приведенной выше конфигурации вы внедрили простой автоматизированный процесс сборки и отправки для интерфейсных проектов. Теперь вам нужно только обратить внимание на отправку кода, и построение приложения будет автоматически завершено системой CI за вас. Конечно, система CI используется не только для создания электронных приложений.Как видите, построение и тестирование других проектов, которые вы можете придумать, на самом деле могут быть выполнены за вас с помощью предопределенных сценариев.

РелизРелиз

Когда CI создает игровое приложение, он отправляет его на страницу выпуска GitHub, чтобы оно сталоdraft(черновик), вы можете отредактировать этот черновик, добавить заголовок и обновить описание, просто нажмитеpublishОпубликуйте новую версию приложения.

Обновление электронного приложения

Автоматическое обновление электронных приложений на самом деле имеет хорошее решение в сообществеelectron-updater. И электрон-вью тоже в основном процессеmain/index.jsЗдесь мы предварительно написали закомментированный код для нас:

// import { autoUpdater } from 'electron-updater'

// autoUpdater.on('update-downloaded', () => {
//   autoUpdater.quitAndInstall()
// })

// app.on('ready', () => {
//   if (process.env.NODE_ENV === 'production') {
//     autoUpdater.checkForUpdates()
//   }
// }

Пока введение autoUpdater может автоматически помочь нам проверять наличие обновлений и автоматически загружать и устанавливать обновления. Однако все невозможно. Хотя этот метод очень прост, он требует строгих условий и требует наличия сертификата для подписи приложения. Сертификат под платформу macOS требует от вас подать заявку на разработчика, а ежегодная плата в 99$ делает меня запредельной.

Поэтому я могу довольствоваться только следующим лучшим вариантом.Могу ли я сравнить текущую версию, запросив номер версии GitHub, нужно ли ее обновлять, и напомнить пользователю? Попробовав, все работает. Моя реализация выглядит следующим образом:

Я сначала написалupdateCheckerпомощник:

import { dialog, shell } from 'electron'
import db from '../../datastore'
import axios from 'axios'
import pkg from '../../../package.json'
const version = pkg.version
const release = 'https://api.github.com/repos/Molunerfinn/PicGo/releases/latest'
const downloadUrl = 'https://github.com/Molunerfinn/PicGo/releases/latest'

const checkVersion = async () => {
  let showTip = db.read().get('picBed.showUpdateTip').value()
  if (showTip === undefined) {
    db.read().set('picBed.showUpdateTip', true).write()
    showTip = true
  }
  // 自动更新的弹窗如果用户没有设置不再提醒,就可以去查询是否需要更新
  if (showTip) {
    const res = await axios.get(release)
    if (res.status === 200) {
      const latest = res.data.name // 获取版本号
      const result = compareVersion2Update(version, latest) // 比对版本号,如果本地版本低于远端则更新
      if (result) {
        dialog.showMessageBox({
          type: 'info',
          title: '发现新版本',
          buttons: ['Yes', 'No'],
          message: '发现新版本,更新了很多功能,是否去下载最新的版本?',
          checkboxLabel: '以后不再提醒',
          checkboxChecked: false
        }, (res, checkboxChecked) => {
          if (res === 0) { // if selected yes
            shell.openExternal(downloadUrl)
          }
          db.read().set('picBed.showUpdateTip', !checkboxChecked).write()
        })
      }
    } else {
      return false
    }
  } else {
    return false
  }
}

// if true -> update else return false
const compareVersion2Update = (current, latest) => {
  const currentVersion = current.split('.').map(item => parseInt(item))
  const latestVersion = latest.split('.').map(item => parseInt(item))
  let flag = false

  for (let i = 0; i < 3; i++) {
    if (currentVersion[i] < latestVersion[i]) {
      flag = true
    }
  }

  return flag
}

export default checkVersion

затем вmain/index.jsЗдесь я вызываю этот помощник обновления, когда приложение готово к запуску:

// ...
import uploader from './utils/uploader.js'

app.on('ready', () => {
  // ...
  updateChecker()
  // ...
})

При запуске приложения появится запрос на обновление:

Суммировать

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

Большая часть этой статьи разработана мнойPicGoВозникшие проблемы и ямы, на которые наступили. Возможно, за простыми предложениями в тексте кроются мои бесчисленные чтения и отладки. Надеюсь, эта статья даст вамelectron-vueРазвитие приносит некоторое вдохновение. Соответствующий код в тексте, вы можете найти его вPicGoНайдено в репозитории проекта, добро пожаловать в звезду~ Если эта статья поможет вам, это будет мое самое счастливое место. Если вам нравится, пожалуйста, следуйте за мнойблогтак же какСтатьи из этой сериипоследующий прогресс.

Примечание: фотографии в этой статье принадлежат моей личной работе, если не указано иное, если вам нужно перепечатать, пожалуйста, отправьте личное сообщение