vue3 + Electron桌面系统的坑

搭建项目

vue create vue3-electron
复制代码

cd vue3-electron

vue add electron-builder
复制代码

这里选择v13.0.0的Electron:

Electron13 需要node 的版本 > 14 !多人开发建议锁版本,避免不同版本之间带来的坑!

稍等片刻:

yarn run electron:serve
复制代码

Electron 安装失败

这应该是大部分朋友都会遇上的问题。

最开始的解决方案:

  1. 删除node_modules/electron
  2. 再次安装(yarn/cnpm/ --registry registry.npmmirror.com/)

这种方案,有时能成功,有时搞半天都不行。

最终的解决方案:

  1. 就是到node_modules文件夹里面的electron文件夹里面的install.js
  2. 然后在这个文件夹下打开terminal,然后输入npm install.js

等待这个运行好之后,基本上就成功了!

打包失败

mac 打包的图标格式为 icns,windows打包的图片格式为ico

这里推荐一个免费好用的图片格式转换工具:convert.72wo.com/icns-to-ico

打包配置:

// vue.config.js

  pluginOptions: {

    electronBuilder: {

      builderOptions: {

        win: {

          icon: 'src/assets/img/icon.ico'

        },

        mac: {

          icon: 'src/assets/img/icon.icns'

        }

      }

    }

  }
复制代码

electron-builder 在打包时会检测cache中是否有electron 包,如果没有的话会从github上拉取,在国内网络环境中拉取的过程大概率会失败,所以你可以自己去下载一个包放到cache目录里。

各个平台的目录地址

  • Linux: $XDG_CACHE_HOME or ~/.cache/electron/
  • MacOS: ~/Library/Caches/electron/
  • Windows: ~/AppData/Local/electron/Cache/

下载地址: github.com/electron/el…

版本号根据你自己使用的版本来下载!

mac 打包

mac 打包会检查环境中是否有签名钥匙,及其检测是否合法。没有的时候会直接跳过,如果没有签名的文件的话,直接跳过吧。

我们没有现阶段没用弄签名文件,这里暂时没有经验可分享。

windows 打包

windows 打包要手动下载三个文件:

github.com/electron-us…

github.com/electron-us…

github.com/electron-us…

如果打包的时候再下载,基本上都失败。提前下好了,分别放在下面的路径下:

开发的坑

打包后白屏

  • hash路由

  • publicPath: process.env.NODE_ENV === 'production' ? './' : '/',

axios请求失败

axios.defaults.adapter = require('axios/lib/adapters/http')
复制代码

因为electron环境下必须强制使用node的网络请求模块

xcode找不到

设置xcode-select到指定的位置

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
复制代码

如果安装了多个xcode,则只需要对xcode.app进行替换。

windows 文件路径处理

ES9 之前,\u表示 unicode 转义,\x表示十六进制转义,``后跟一个数字表示八进制转义,这使得创建特定的字符串变得不可能,例如Windows文件路径C:\uuu\xxx\111

String.raw `C:\Windows\System`

'C:\\Windows\\System'

String.raw `C:\Windows\System`

'C:\Windows\System'
复制代码

ipcRenderer.on多次执行

每次触发ipcRenderer模块都会新建一个新的ipcRenderer,导致ipcRenderer内的函数块会被执行n次(取决于当前残留有多少个ipcRenderer)。

封装server.js: (server在主进程中使用)

import { ipcMain } from 'electron'



const _map = new Map()



ipcMain.on('from-client', (event, params) => {

  const reply = function (data) {

    event.reply('from-server', {

      _symbol: params._symbol,

      // data 传递给客户端,最终 resolve 它

      data

    })

  }

  const ctx = {

    reply,

    type: params.type

  }

  const cb = _map.get(params.type)

  if (typeof cb === 'function') {

    cb(ctx, params.data)

  } else {

    cb(ctx, '没有注册~')

  }

})



export default function server (type, callback) {

  _map.set(type, callback)

}
复制代码

封装request.js:(request在渲染进程中使用)

const { ipcRenderer } = window.require('electron')

const _map = new Map()

ipcRenderer.on('from-server', (event, params) => {

  const cb = _map.get(params._symbol)

  if (typeof cb === 'function') {

    _map.delete(params._symbol)

    cb(params.data)

  }

})



export default function request (type, data) {

  const _symbol = Date.now() + type

  return new Promise(resolve => {

    _map.set(_symbol, (data) => {

      resolve(data)

    })

    ipcRenderer.send('from-client', {

      _symbol: _symbol,

      type: type,

      data: data

    })

  })

}
复制代码

猜你喜欢

转载自juejin.im/post/7037302384137076773