手摸手,带你用Electron+React开发一款桌面应用(4)

333 阅读6分钟

我正在参加跨端技术专题征文活动,详情查看:juejin.cn/post/710123…

大家好,我是爱吃鱼的桶哥,在上一期中我给大家分享了这个图书软件的最后一部分内容,今天我们就来收一下尾,为这个小工具的开发划上一个完整的句号。

自动打包

在前面的四期内容中,我们已经完成了整个应用的开发,包括图书的搜索、下载、设置以及发送图书等相关内容,但是一个软件给用户安装时肯定是需要有一个安装包,而不是让用户自己去运行代码,因此我们接下来要完成项目的打包。

在前面的一篇文件中,我介绍了Electron的打包及自动更新,具体链接在这:基于Github Actions完成Electron自动打包、发布及更新,这篇文章中就讲解了如何打包发布及自动更新,我们这里也会使用这篇文章中讲到的相关知识点,但是跟这篇文章中的又有一些不一样的地方,具体不一样的地方会在后续进行讲解。

首先我们还是需要添加打包的基础设置信息,在使用vite-react-electron这个基础的模板时,它已经帮助我们在根目录创建了一个electron-builder.json文件,这个文件其实就是把我们之前写在package.json中的内容单独抽取出来了,这样可以更加方便的维护我们的打包配置信息,在该文件中,我们需要填入相关的打包信息,然后才能完成项目的打包,具体的代码如下:

{
  "appId": "cn.toside.read.desktop",
  "productName": "kindle-helper-desktop",
  "copyright": "Copyright © 2022 ${author}",
  "asar": true,
  "directories": {
    "output": "release",
    "buildResources": "resources"
  },
  "files": ["dist/**/*", "node_modules/", "package.json"],
  "win": {
    "target": [
      {
        "target": "nsis",
        "arch": ["x64"]
      }
    ],
    "verifyUpdateCodeSignature": false,
    "artifactName": "${productName}-${version}-Setup.${ext}"
  },
  "nsis": {
    "oneClick": false,
    "perMachine": false,
    "allowToChangeInstallationDirectory": true,
    "deleteAppDataOnUninstall": false
  },
  "mac": {
    "target": ["dmg", "zip"],
    "artifactName": "${productName}-${version}-Installer.${ext}"
  },
  "linux": {
    "target": ["AppImage"],
    "artifactName": "${productName}-${version}-Installer.${ext}"
  }
}

上述代码的相关配置信息已经在基于Github Actions完成Electron自动打包、发布及更新这篇文章中进行过讲解,这里直接拿来用,所以就不做过多的讲解了,如果还有不了解相关内容的小伙伴,可以去前面的这篇文章中再回顾一次。

当配置完如上信息后,我们只需要执行npm run build,项目就会自动进行打包了,这条执行命令是vite-react-electron这个基础模板中已经帮我们配置好的,所以无需我们自己添加。

本地的打包会根据我们的系统来打包对应的安装包,如果想要自动进行打包,那就需要借助CI了,在之前的文章中也介绍了如何使用Github Actions来自动打包,这里也不做过多的介绍,简单贴一下自动执行的代码:

// .github/workflows/build.yml
name: Build

on:
  push:
    tags:
      - "v*.*.*"

jobs:
  release:
    name: build and release electron app
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        os: [windows-latest, macos-latest, ubuntu-latest]

    steps:
      - name: Check out git repository
        uses: actions/checkout@v3.0.0

      - name: Install Node.js
        uses: actions/setup-node@v3.0.0
        with:
          node-version: "16"

      - name: Install Dependencies
        run: npm install

      - name: Build Electron App
        run: npm run build
        env:
          GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}

      - name: Cleanup Artifacts for Windows
        if: matrix.os == 'windows-latest'
        run: |
          npx rimraf "release/!(*.exe)"
          
      - name: Cleanup Artifacts for MacOS
        if: matrix.os == 'macos-latest'
        run: |
          npx rimraf "release/!(*.dmg)"
      
      - name: Cleanup Artifacts for Linux
        if: matrix.os == 'ubuntu-latest'
        run: |
          npx rimraf "release/!(*.AppImage)"
      
      - name: Upload artifacts
        uses: actions/upload-artifact@v3.0.0
        with:
          name: ${{ matrix.os }}
          path: release

      - name: Release
        uses: softprops/action-gh-release@v0.1.14
        if: startsWith(github.ref, 'refs/tags/')
        with:
          files: "release/**"
        env:
          GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}

我们在根目录下新建一个.github文件夹,然后在里面再新建一个workflows文件夹,最后在创建一个以.yml为结尾的文件,当这个文件被上传到Github上,就会自动执行打包的过程。

上述的CI命令中,当检测到有tag版本时,就会执行,因此我们每次发布的时候都需要创建一个tag,但是手动创建太麻烦了,因此我们需要借助npm version来帮我们自动升版本,我参考了网上的代码,在packages.json文件中添加了相应脚本来帮我们自动升级tag,代码如下:

"patch": "npm version patch && git push origin develop && git push origin --tags",
"minor": "npm version minor && git push origin develop && git push origin --tags",
"major": "npm version major && git push origin develop && git push origin --tags"

当本地的代码完成提交后,我们只需要执行npm run patch,代码就会自动被提交到github,并且自动根据本地的版本来进行升级一个小版本,然后自动打包就开始执行了,等打包完成即可在github中看到对应的安装包,如下:

image.png

自动更新

当我们的项目打包完成并安装后,一旦有新的内容更新,则需要提醒用户安装最新版。在之前的文章中我们将了通过electron-updater来对应用进行更新,虽然这种方式很简单,但是在Mac端下更新Electron应用,需要申请对应的证书,而申请证书是需要每年支付99刀的,因此我们这里换一直实现的思路。

其实更新的本质就是对比本地应用的版本跟远程的应用的版本是否一致,如果不一致,则提示用户需要升级,我们这里直接提示用户到Github中去下载,具体的代码如下:

// packages/main/utils/updateChecker.ts
import { dialog, shell } from 'electron';
import axios from 'axios';
import { lt } from 'semver'
import pkg from '../../../package.json';
const version = pkg.version;
const releaseUrl =
    'https://api.github.com/repos/myadmin/kindle-helper-desktop/releases/latest';
const releaseUrlBackup =
    'https://github.com/myadmin/kindle-helper-desktop/blob/develop/package.json';
const downloadUrl =
    'https://github.com/myadmin/kindle-helper-desktop/releases/latest';

const checkVersion = async () => {
    let res: any;
    try {
        res = await axios.get(releaseUrl).catch(async () => {
            const result = await axios.get(releaseUrlBackup);
            return result;
        });
    } catch (err) {
        console.log(err);
    }
    if (res.status === 200) {
        const latest = res.data.version || res.data.name;
        const result = compareVersion2Update(version, latest); // 比对版本号,如果本地版本低于远端则更新
        if (result) {
            dialog
                .showMessageBox({
                    type: 'info',
                    title: '发现新版本',
                    message: '发现新版本,更新了很多功能,是否去下载最新的版本?',
                    buttons: ['是', '否'],
                    checkboxLabel: '以后不再提醒',
                    checkboxChecked: false,
                })
                .then(({ response }) => {
                    if (response === 0) {
                        // if selected yes
                        shell.openExternal(downloadUrl);
                    }
                });
        }
    } else {
        return false;
    }
};

const compareVersion2Update = (current: string, latest: string): boolean => {
    try {
        return lt(current, latest);
    } catch (e) {
        return false;
    }
};

export default checkVersion;

上述代码简单来说,其实就是对比了本地的package.jsonversion字段与远程仓库中version字段的差异,当检测到差异后,会直接提示用户有最新版本,是否需要下载,如果点击是,则直接跳转到Github仓库进行下载,否则则关闭弹窗。

到这里,基本的自动打包和自动更新就都讲完了,后续我会持续更新我的项目,有兴趣的小伙伴可以到Github中给我点个star,具体的地址在这:kindle-helper-desktop

最后

这是最后一篇关于这个软件的分享文章,因此这篇文章相对前面的内容来说比较简单。虽然这篇内容很简单,但是还是需要大家自己去动手写写才能掌握,后续我会继续分享更多的好文章,请大家多多点赞,多多关注,感谢大家!

最后,本期的分享内容就到这里了,如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,谢谢大家

手摸手,带你用Electron+React开发一款桌面应用(1)

手摸手,带你用Electron+React开发一款桌面应用(2)

手摸手,带你用Electron+React开发一款桌面应用(2.5)

基于Github Actions完成Electron自动打包、发布及更新