electron是一个使用JS,CSS,HTML构建跨平台的桌面应用程序的框架,微软的VScode就是使用该技术开发

环境搭建 Link to heading

  1. 安装node环境

  2. 由于使用的是electron-vue脚手架工具,首先要安装vuecli

npm install -g @vue/cli
# OR
yarn global add @vue/cli
  1. 起步

vue init阶段会出现一些项目基本选项,按照自己需求选择就好,打包工具选择elelctron-builder之后会用到它打包和更新

img

vue init simulatedgreg/electron-vue my-project

cd my-project

npm install
# OR
yarn

npm run dev 
# OR
yarn dev
  1. 出现以下界面及成功

img

注意事项 Link to heading

  • npm install时候可能会由于网络原因导致包安装失败,使用cnpm或者nrm切换软件源
  • npm install时候可能会遇到electron下载失败情况,有两种解决方法
    1. 在项目根目录下新建.npmrc或者.yarnrc文件,里面写入
    electron_mirror=http://npm.taobao.org/mirrors/electron/
    
    1. 淘宝镜像下载对应系统和版本的electron包到electron缓存目录
    mac/win/liunx: 当前用户名/.electron/ 
    
  • windows用户在npm install时候会遇到node-gyp错误,这是由于你的系统没有安装正确到构建工具,可以使用windows-build-tools一键安装所有到所需工具包
npm install --global windows-build-tools
# OR
yarn global add windows-build-tools
  • npm run dev时候可能会遇到process is not defined错误,这是由于node10.X版本导致的,有两种解决方法
    1. 升级node版本到12.X
    2. 打开项目/src/index.ejs,修改!process.browser!require('process').browser

基础入门 Link to heading

插件使用 Link to heading

插件使用和vue一样,npm/yarn直接装包就可以,脚手架自带electron-vuex可以实现主进程与渲染线程共享数据,推荐使用

css预处理器 Link to heading

假设我们使用less作为我们到css预先处理,需要安装less并且修改webpack配置

  1. 安装
npm install -D less less-loader
# OR
yarn add -D less less-loader
  1. 打开.electron-vue/webpack.renderer.config.js,在less rule里面加入less-loader
{
  test: /\.less$/,
  use: [
    {
      loader: "vue-style-loader"
    },
    {
      loader: "css-loader",
      options: {
        importLoaders: 1
      }
    },
    {
      loader: "postcss-loader",
    },
    {
      loader: "less-loader",
      options: {
        javascriptEnabled: true,
        modifyVars: {
          'text-primary-color': '#293A4D', // 主要'
          'text-minor-color': 'rgba(41, 58, 77, 0.45)', // 次要'
          'text-highlight-color': '#1890FF' // 高亮
        }
      }
    }
  ]
}

静态资源使用 Link to heading

在项目根目录下的static目录,可以存放主进程和渲染进程都可以访问到的静态资源,electron-vue提供一个__static全局变量来快速访问此目录,而且开发环境和生产都可以使用。

  1. vue模版使用
<template>
  <img v-bind:src="imageUrl">
</template>

<script>
  export default {
    data () {
      // 注意 路径的起始是 `static/`
      return { imageUrl: 'static/imgs/unsplash.png' }
    }
  }
</script>
  1. js文件使用
import fs from 'fs'
import path from 'path'

let fileContents = fs.readFileSync(path.join(__static, '/someFile.txt'), 'utf8')

console.log(fileContents)

读写本地文件 Link to heading

使用 electron 的一大好处是可以访问用户的文件系统。这使你可以读取和写入本地系统上的文件。electron提供了app.getPath(name)来快速访问本地文件目录,比如桌面、用户目录等等

// 用户的home文件夹
app.getPath('home')

// 用户桌面
app.getPath('desktop')

// 用户下载文件夹
app.getPath('downloads')

// 更多访问 https://www.electronjs.org/docs/api/app#appgetpathname

主线程与渲染进程通信 Link to heading

  1. ipcMainipcRenderer
// 在主进程中.
const { ipcMain } = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
  console.log(arg) // prints "ping"
  event.reply('asynchronous-reply', 'pong')
})

ipcMain.on('synchronous-message', (event, arg) => {
  console.log(arg) // prints "ping"
  event.returnValue = 'pong'
})
//在渲染器进程 (网页) 中。
const { ipcRenderer } = require('electron')
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong"

ipcRenderer.on('asynchronous-reply', (event, arg) => {
  console.log(arg) // prints "pong"
})
ipcRenderer.send('asynchronous-message', 'ping')
  1. remote模块

在渲染进程中,可以通过const {remote} = require('electron')来获取到remote对象. 通过这个对象可以允许渲染进程访问主进程的模块.

// 把自定义方法挂载到app下
const { app } = require('electron');

app.utils = {
  test () {
    return 'hello world'
  }
}
// 在渲染进程中通过remote模块访问此方法
const {remote} = require('electron')
remote.app.utils.test()

软件打包 Link to heading

electron-packagerelectron-builder都可以把代码打包成各个平台安装包。正经过调研和实际使用electron-builder功能丰富,可配置性强,故下面都使用electron-builder进行打包

  1. vue init阶段应该选择electron-builder作为打包工具
  2. 为了方便首先自定义打包命令 为各个平台添加打包命令。在package.json文件scripts里加入以下命令
"scripts": {
  "build:dmg": "node .electron-vue/build.js && electron-builder --mac",
  "build:deb": "node .electron-vue/build.js && electron-builder --linux",
  "build:exe": "node .electron-vue/build.js && electron-builder --win"
}
  1. 自定义打包配置

与打包相关的配置在package.json文件的build下面

"build": {
  "productName": "hello-electron-vue",
  "appId": "com.example.yourapp",
  "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"
  },
  "win": {
    "icon": "build/icons/icon.ico"
  },
  "linux": {
    "icon": "build/icons"
  }
}

上面是默认配置,下面是我的自定义配置并会进行相关说明,更多配置请查看electron-builder官方文档

"build": {
  // productName 是软件安装后的名字,只适用于像dmg、exe、deb这种安装包
  "productName": "这里是软件安装后的名字",
  "appId": "com.example.yourapp",
  "copyright": "这里是软件版权信息",
  "directories": {
    "output": "build"
  },
  "files": [
    "dist/electron/**/*"
  ],
  // electron下载镜像地址,推荐设置,不然下载electron会失败
  "electronDownload": {
    "mirror": "https://npm.taobao.org/mirrors/electron/"
  },
  // 打包dmg安装包自定义配置,对应macos平台
  "dmg": {
    "contents": [
      {
        "x": 410,
        "y": 150,
        "type": "link",
        "path": "/Applications"
      },
      {
        "x": 130,
        "y": 150,
        "type": "file"
      }
    ],
    // 如果没有苹果开发者账号请禁止dmg签名
    "sign": false,
    "icon": "build/icons/icon.ico"
  },
  // 打包成appImage自定义配置,对应linux平台
  "appImage": {
    "desktop": {
      "Name[zh_CN]": "这里是软件安装后的名字",
      "Name": "这里是软件安装后的名字",
      "Icon": "build/Icons/Icon256x256.png"
    }
  },
  // windows平台打包工具配置
  "nsis": {
    // 是否一键安装,false后安装时候会出现安装引导界面,比如自定义安装位置
    "oneClick": false,
    "perMachine": false,
    // 是否允许用户自定义安装目录
    "allowToChangeInstallationDirectory": true,
    // 安装/卸载时候图标
    "installerIcon": "build/icons/icon.ico",
    "uninstallerIcon": "build/icons/icon.ico",
    "installerHeaderIcon": "build/icons/icon.ico",
    // 安装完成后i是否创建快捷方式
    "createDesktopShortcut": true
  },
  // 打包成deb安装包自定义配置,对应linux平台
  "deb": {
    "icon": "build/icons"
  },
  "mac": {
    "icon": "build/icons/icon.icns",
    // macos平台如果没有苹果开发者账号请禁止代码签名,不然会打包错误
    "identity": null
  },
  "win": {
    // win平台下图标为ico格式,mac平台为icns,linux平台为png
    "icon": "build/icons/icon.ico"
  },
  "linux": {
    "icon": "build/icons",
    // linux平台打包类型
    "target": ["AppImage", "deb"]
  }
}
  1. 根据第二步打包命令执行即可

建议在当前平台只打包当前平台,如果打包其他平台可能会出现无法预知错误,可以利用虚拟机在一个电脑上打包多平台。在yarn build时候你可能会遇到打包组件(electron fpm nsis)下载失败情况,请到这里下载对应版本到组件,然后放到系统缓存目录

macOS ~/Library/Caches/electron-builder
linux ~/.cache/electron-builder
windows %LOCALAPPDATA%\electron-builder\cache
  1. 打包成功后在build目录里面会找到对应安装包

注意事项 Link to heading

  • deb安装包在ubuntu安装成功后,会出现打不开软件情况,因为系统缺少libgconf2-4,运行下面命令安装即可
sudo apt -y install libgconf2-4

软件更新 Link to heading

electron-builder插件也自带更新功能,也可以把打包好的安装包发布到各个开源平台以及自定义。

注意事项 Link to heading

  • 三个平台只支持特定的安装包格式,其他格式(deb)暂不支持
macOS: DMG
Linux: AppImage
Windows: NSIS
  • macos平台必须开启代码签名才可以进行更新操作

12

  1. 添加发布配置

publish 配置添加到package.json文件的build下面会对所有平台生效,也可以为某个特定平台添加特有发布配置

"publish": [
  {
    // provider 字段是发布对平台,支持Bintray, GitHub, S3, Spaces or Snap Store和自定义发布服务器
    // 这里只演示自定义服务器,更多配置及api请查看官方文档https://www.electron.build/configuration/publish
    "provider": "generic",
    // url为发布服务器地址和路径,搭建一个文件服务器就可以,或者oss。路径下就是安装包存放的位置
    "url": "http://127.0.0.1:2333/test/"
  }
]
  1. 相关代码

更新是写在主线程中,因为更新只能在打包后测试,为了调试方便建议使用electron-log把每一步日志和错误都打印出来

import { autoUpdater } from 'electron-updater'
const log = require('electron-log')

// 检查更新
// sendStatusToWindow函数为把更新消息发送到渲染进程
ipcMain.on('check-update', (event, arg) => {
  log.info("check-update")
  // 检查更新
  autoUpdater.checkForUpdates()
})

autoUpdater.on('error', (err) => {
  log.error("update-error")
  log.error(err)
  sendStatusToWindow(-1, '更新错误', 0)
})

autoUpdater.on('checking-for-update', () => {
  log.info("checking-for-update")
  sendStatusToWindow(1, '正在检查更新', 0)
})

autoUpdater.on('update-available', () => {
  log.info("update-available")
  // 发现有可用更新
  sendStatusToWindow(1, '有可用更新', 0)
})

autoUpdater.on('update-not-available', () => {
  log.info("update-not-available")
  sendStatusToWindow(1, '没有可用更新', 0)
})

autoUpdater.on('download-progress', (progress, bytesPerSecond, percent, total, transferred) => {
  // 监听下载进度
  log.info("download-progress")
  log.info(parseInt(progress.percent) + '%')
  sendStatusToWindow(1, '下载中', progress.percent)
})

autoUpdater.on('update-downloaded', (UpdateInfo) => {
  // 下载安装包完成后会触发,此时发送给渲染进程下载完成消息,渲染进程点击安装,执行autoUpdater.quitAndInstall()方法重启应用安装
  log.info('update-downloaded')
  log.info(UpdateInfo)
  sendStatusToWindow(2, '已下载完成', 100)
  ipcMain.on('update-install', (event, arg) => {
    log.info('update-install')
    autoUpdater.quitAndInstall()
  })
})
  1. 上传安装包和yml文件

yarn build完成后,如果你配置了publish会额外生成一个yaml文件,此文件记录当前安装包一些信息,以便检查更新进行对比来判断是否要更新。默认情况下win平台会生成latestyml,macos平台latest-mac.yml,linux平台latest-linux.yml,把安装包和yml文件一起上传到发布服务器相应路径下

23

参考资料 Link to heading